libnsgif: Update to the latest upstream master (#2547)

* libnsgif: Delete patch for read only source data.

The source data is now read only in upstream libnsgif and the code
has changed quite a bit so this does not apply.

* libnsgif: Update to latest upstream master.

* libnsgif: Only one insufficient data return code now.

There is only one code now, for "I need more data".

* libnsgif: Update for renamed structure member.
This commit is contained in:
Michael Drake 2021-11-21 10:06:37 +00:00 committed by GitHub
parent f352bcd191
commit 8c9d899acd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1089 additions and 1072 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
/*
* Copyright 2004 Richard Wilson <richard.wilson@netsurf-browser.org>
* Copyright 2008 Sean Fox <dyntryx@gmail.com>
* Copyright 2013-2021 Michael Drake <tlsa@netsurf-browser.org>
*
* This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/
* Licenced under the MIT License,
@ -15,53 +16,55 @@
#ifndef _LIBNSGIF_H_
#define _LIBNSGIF_H_
#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
/* Error return values */
typedef enum {
GIF_WORKING = 1,
GIF_OK = 0,
GIF_INSUFFICIENT_FRAME_DATA = -1,
GIF_FRAME_DATA_ERROR = -2,
GIF_INSUFFICIENT_DATA = -3,
GIF_DATA_ERROR = -4,
GIF_INSUFFICIENT_MEMORY = -5,
GIF_FRAME_NO_DISPLAY = -6,
GIF_END_OF_FRAME = -7
GIF_WORKING = 1,
GIF_OK = 0,
GIF_INSUFFICIENT_DATA = -1,
GIF_INSUFFICIENT_FRAME_DATA = GIF_INSUFFICIENT_DATA,
GIF_FRAME_DATA_ERROR = -2,
GIF_DATA_ERROR = -4,
GIF_INSUFFICIENT_MEMORY = -5,
GIF_FRAME_NO_DISPLAY = -6,
GIF_END_OF_FRAME = -7
} gif_result;
/** GIF frame data */
typedef struct gif_frame {
/** whether the frame should be displayed/animated */
bool display;
/** delay (in cs) before animating the frame */
unsigned int frame_delay;
/** whether the frame should be displayed/animated */
bool display;
/** delay (in cs) before animating the frame */
unsigned int frame_delay;
/* Internal members are listed below */
/* Internal members are listed below */
/** offset (in bytes) to the GIF frame data */
unsigned int frame_pointer;
/** whether the frame has previously been used */
bool virgin;
/** whether the frame is totally opaque */
bool opaque;
/** whether a forcable screen redraw is required */
bool redraw_required;
/** how the previous frame should be disposed; affects plotting */
unsigned char disposal_method;
/** whether we acknoledge transparency */
bool transparency;
/** the index designating a transparent pixel */
unsigned char transparency_index;
/** x co-ordinate of redraw rectangle */
unsigned int redraw_x;
/** y co-ordinate of redraw rectangle */
unsigned int redraw_y;
/** width of redraw rectangle */
unsigned int redraw_width;
/** height of redraw rectangle */
unsigned int redraw_height;
/** offset (in bytes) to the GIF frame data */
unsigned int frame_pointer;
/** whether the frame has previously been used */
bool virgin;
/** whether the frame is totally opaque */
bool opaque;
/** whether a full image redraw is required */
bool redraw_required;
/** how the previous frame should be disposed; affects plotting */
unsigned char disposal_method;
/** whether we acknowledge transparency */
bool transparency;
/** the index designating a transparent pixel */
unsigned int transparency_index;
/** x co-ordinate of redraw rectangle */
unsigned int redraw_x;
/** y co-ordinate of redraw rectangle */
unsigned int redraw_y;
/** width of redraw rectangle */
unsigned int redraw_width;
/** height of redraw rectangle */
unsigned int redraw_height;
/* Frame flags */
unsigned int flags;
} gif_frame;
/* API for Bitmap callbacks */
@ -74,77 +77,81 @@ typedef void (*gif_bitmap_cb_modified)(void *bitmap);
/** Bitmap callbacks function table */
typedef struct gif_bitmap_callback_vt {
/** Create a bitmap. */
gif_bitmap_cb_create bitmap_create;
/** Free a bitmap. */
gif_bitmap_cb_destroy bitmap_destroy;
/** Return a pointer to the pixel data in a bitmap. */
gif_bitmap_cb_get_buffer bitmap_get_buffer;
/** Create a bitmap. */
gif_bitmap_cb_create bitmap_create;
/** Free a bitmap. */
gif_bitmap_cb_destroy bitmap_destroy;
/** Return a pointer to the pixel data in a bitmap. */
gif_bitmap_cb_get_buffer bitmap_get_buffer;
/* Members below are optional */
/* Members below are optional */
/** Sets whether a bitmap should be plotted opaque. */
gif_bitmap_cb_set_opaque bitmap_set_opaque;
/** Tests whether a bitmap has an opaque alpha channel. */
gif_bitmap_cb_test_opaque bitmap_test_opaque;
/** The bitmap image has changed, so flush any persistant cache. */
gif_bitmap_cb_modified bitmap_modified;
/** Sets whether a bitmap should be plotted opaque. */
gif_bitmap_cb_set_opaque bitmap_set_opaque;
/** Tests whether a bitmap has an opaque alpha channel. */
gif_bitmap_cb_test_opaque bitmap_test_opaque;
/** The bitmap image has changed, so flush any persistent cache. */
gif_bitmap_cb_modified bitmap_modified;
} gif_bitmap_callback_vt;
/** GIF animation data */
typedef struct gif_animation {
/** LZW decode context */
void *lzw_ctx;
/** callbacks for bitmap functions */
gif_bitmap_callback_vt bitmap_callbacks;
/** pointer to GIF data */
unsigned char *gif_data;
/** width of GIF (may increase during decoding) */
unsigned int width;
/** heigth of GIF (may increase during decoding) */
unsigned int height;
/** number of frames decoded */
unsigned int frame_count;
/** number of frames partially decoded */
unsigned int frame_count_partial;
/** decoded frames */
gif_frame *frames;
/** current frame decoded to bitmap */
int decoded_frame;
/** currently decoded image; stored as bitmap from bitmap_create callback */
void *frame_image;
/** number of times to loop animation */
int loop_count;
/** LZW decode context */
void *lzw_ctx;
/** callbacks for bitmap functions */
gif_bitmap_callback_vt bitmap_callbacks;
/** pointer to GIF data */
const uint8_t *gif_data;
/** width of GIF (may increase during decoding) */
unsigned int width;
/** height of GIF (may increase during decoding) */
unsigned int height;
/** number of frames decoded */
unsigned int frame_count;
/** number of frames partially decoded */
unsigned int frame_count_partial;
/** decoded frames */
gif_frame *frames;
/** current frame decoded to bitmap */
int decoded_frame;
/** currently decoded image; stored as bitmap from bitmap_create callback */
void *frame_image;
/** number of times to loop animation */
int loop_count;
/* Internal members are listed below */
/* Internal members are listed below */
/** current index into GIF data */
unsigned int buffer_position;
/** total number of bytes of GIF data available */
unsigned int buffer_size;
/** current number of frame holders */
unsigned int frame_holders;
/** index in the colour table for the background colour */
unsigned int background_index;
/** image aspect ratio (ignored) */
unsigned int aspect_ratio;
/** size of colour table (in entries) */
unsigned int colour_table_size;
/** whether the GIF has a global colour table */
bool global_colours;
/** global colour table */
unsigned int *global_colour_table;
/** local colour table */
unsigned int *local_colour_table;
/** current index into GIF data */
unsigned int buffer_position;
/** total number of bytes of GIF data available */
unsigned int buffer_size;
/** current number of frame holders */
unsigned int frame_holders;
/** background index */
unsigned int bg_index;
/** background colour */
unsigned int bg_colour;
/** image aspect ratio (ignored) */
unsigned int aspect_ratio;
/** size of colour table (in entries) */
unsigned int colour_table_size;
/** whether the GIF has a global colour table */
bool global_colours;
/** global colour table */
unsigned int *global_colour_table;
/** local colour table */
unsigned int *local_colour_table;
/** current colour table */
unsigned int *colour_table;
/** previous frame for GIF_FRAME_RESTORE */
void *prev_frame;
/** previous frame index */
int prev_index;
/** previous frame width */
unsigned prev_width;
/** previous frame height */
unsigned prev_height;
/** previous frame for GIF_FRAME_RESTORE */
void *prev_frame;
/** previous frame index */
int prev_index;
/** previous frame width */
unsigned prev_width;
/** previous frame height */
unsigned prev_height;
} gif_animation;
/**
@ -157,28 +164,23 @@ void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks);
* any information that hasn't already been decoded.
* If an error occurs, all previously decoded frames are retained.
*
* @return Error return value.
* \return Error return value.
* - GIF_FRAME_DATA_ERROR for GIF frame data error
* - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to process
* any more frames
* - GIF_INSUFFICIENT_DATA reached unexpected end of source data
* - GIF_INSUFFICIENT_MEMORY for memory error
* - GIF_DATA_ERROR for GIF error
* - GIF_INSUFFICIENT_DATA for insufficient data to do anything
* - GIF_OK for successful decoding
* - GIF_WORKING for successful decoding if more frames are expected
*/
gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data);
gif_result gif_initialise(gif_animation *gif, size_t size, const uint8_t *data);
/**
* Decodes a GIF frame.
*
* @return Error return value. If a frame does not contain any image data,
* GIF_OK is returned and gif->current_error is set to
* GIF_FRAME_NO_DISPLAY
* \return Error return value.
* - GIF_FRAME_DATA_ERROR for GIF frame data error
* - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame
* - GIF_DATA_ERROR for GIF error (invalid frame header)
* - GIF_INSUFFICIENT_DATA for insufficient data to do anything
* - GIF_INSUFFICIENT_DATA reached unexpected end of source data
* - GIF_INSUFFICIENT_MEMORY for insufficient memory to process
* - GIF_OK for successful decoding
*/

View File

@ -96,7 +96,6 @@ struct lzw_ctx {
uint8_t stack_base[LZW_TABLE_ENTRY_MAX];
};
/* Exported function, documented in lzw.h */
lzw_result lzw_context_create(struct lzw_ctx **ctx)
{
@ -109,14 +108,12 @@ lzw_result lzw_context_create(struct lzw_ctx **ctx)
return LZW_OK;
}
/* Exported function, documented in lzw.h */
void lzw_context_destroy(struct lzw_ctx *ctx)
{
free(ctx);
}
/**
* Advance the context to the next sub-block in the input data.
*
@ -153,7 +150,6 @@ static lzw_result lzw__block_advance(struct lzw_read_ctx *restrict ctx)
return LZW_OK;
}
/**
* Get the next LZW code of given size from the raw input data.
*
@ -223,7 +219,6 @@ static inline lzw_result lzw__read_code(
return LZW_OK;
}
/**
* Handle clear code.
*

View File

@ -4,6 +4,7 @@
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2017 Michael Drake <michael.drake@codethink.co.uk>
* Copyright 2021 Michael Drake <tlsa@netsurf-browser.org>
*/
#ifndef LZW_H_
@ -19,11 +20,9 @@
/** Maximum LZW code size in bits */
#define LZW_CODE_MAX 12
/* Declare lzw internal context structure */
struct lzw_ctx;
/** LZW decoding response codes */
typedef enum lzw_result {
LZW_OK, /**< Success */
@ -37,7 +36,6 @@ typedef enum lzw_result {
LZW_BAD_CODE, /**< Error: Bad LZW code */
} lzw_result;
/**
* Create an LZW decompression context.
*

View File

@ -1,31 +0,0 @@
--- libnsgif.c.orig 2021-04-24 18:33:02.757323861 +0100
+++ libnsgif.c 2021-04-24 18:35:14.659860190 +0100
@@ -424,20 +424,15 @@
block_size = gif_data[0] + 1;
/* Check if the frame data runs off the end of the file */
if ((int)(gif_bytes - block_size) < 0) {
- /* Try to recover by signaling the end of the gif.
- * Once we get garbage data, there is no logical way to
- * determine where the next frame is. It's probably
- * better to partially load the gif than not at all.
+ /* jcupitt 15/9/19
+ *
+ * There was code here to set a TRAILER tag. But this
+ * wrote to the input buffer, which will not work for
+ * libvips, where buffers can be mmaped read only files.
+ *
+ * Instead, just signal insufficient frame data.
*/
- if (gif_bytes >= 2) {
- gif_data[0] = 0;
- gif_data[1] = GIF_TRAILER;
- gif_bytes = 1;
- ++gif_data;
- break;
- } else {
- return GIF_INSUFFICIENT_FRAME_DATA;
- }
+ return GIF_INSUFFICIENT_FRAME_DATA;
} else {
gif_bytes -= block_size;
gif_data += block_size;

View File

@ -12,10 +12,13 @@ cp libnsgif/include/libnsgif.h .
cp libnsgif/src/lzw.[ch] .
cp libnsgif/src/utils/log.h utils
echo applying patches ...
for patch in patches/*.patch; do
patch -p0 <$patch
done
if [ -d "patches" ]
then
echo applying patches ...
for patch in patches/*.patch; do
patch -p0 <$patch
done
fi
echo cleaning up ...
rm -rf libnsgif

View File

@ -146,14 +146,11 @@ vips_foreign_load_nsgif_errstr( gif_result result )
case GIF_OK:
return( _( "OK" ) );
case GIF_INSUFFICIENT_FRAME_DATA:
return( _( "Insufficient data to complete frame" ) );
case GIF_FRAME_DATA_ERROR:
return( _( "GIF frame data error" ) );
case GIF_INSUFFICIENT_DATA:
return( _( "Insufficient data to do anything" ) );
return( _( "Incomplete data" ) );
case GIF_DATA_ERROR:
return( _( "GIF header data error" ) );
@ -313,9 +310,9 @@ vips_foreign_load_nsgif_set_header( VipsForeignLoadNsgif *gif,
if( gif->anim->global_colours &&
gif->anim->global_colour_table &&
gif->anim->background_index >= 0 &&
gif->anim->background_index < gif->anim->colour_table_size ) {
int index = gif->anim->background_index;
gif->anim->bg_index >= 0 &&
gif->anim->bg_index < gif->anim->colour_table_size ) {
int index = gif->anim->bg_index;
unsigned char *entry = (unsigned char *)
&gif->anim->global_colour_table[index];