summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2021-11-02 19:04:01 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2021-11-02 19:04:01 +0000
commit41f33c7495e7b83b40a93e4a76481d770f0c5f7b (patch)
treedbe9ac31a49cc3a821d15b077868b2c4d1a00d5c
parent42cfb0d9a5b4e6dbf0981262916e160be438157b (diff)
downloadlibnsgif-41f33c7495e7b83b40a93e4a76481d770f0c5f7b.tar.gz
libnsgif-41f33c7495e7b83b40a93e4a76481d770f0c5f7b.tar.bz2
GIF: Change background colour handling.
We used to memset a colour we looked up in the colour table when clearing the previous frame. This didn't make sense, because the colour is four bytes wide. Now we write the actual colour in properly. Also, the background color comes from the global colour table (if one exists), rather than from the local colour table. If there is no colour table, black is used.
-rw-r--r--include/libnsgif.h6
-rw-r--r--src/libnsgif.c29
2 files changed, 20 insertions, 15 deletions
diff --git a/include/libnsgif.h b/include/libnsgif.h
index 81a67b5..a11c3a5 100644
--- a/include/libnsgif.h
+++ b/include/libnsgif.h
@@ -126,8 +126,10 @@ typedef struct gif_animation {
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;
+ /** 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) */
diff --git a/src/libnsgif.c b/src/libnsgif.c
index 80e6c7b..47f02fa 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -849,7 +849,6 @@ static gif_result gif_clear_frame(
uint8_t *gif_data, *gif_end;
int gif_bytes;
uint32_t width, height, offset_x, offset_y;
- uint32_t *colour_table;
uint32_t save_buffer_position;
assert(frame->disposal_method == GIF_FRAME_CLEAR);
@@ -879,7 +878,7 @@ static gif_result gif_clear_frame(
goto gif_decode_frame_exit;
}
- ret = gif__parse_colour_table(gif, frame, true);
+ ret = gif__parse_colour_table(gif, frame, false);
if (ret != GIF_OK) {
goto gif_decode_frame_exit;
}
@@ -891,8 +890,6 @@ static gif_result gif_clear_frame(
width = frame->redraw_width;
height = frame->redraw_height;
- colour_table = gif->colour_table;
-
/* Ensure sufficient data remains */
if (gif_bytes < 1) {
ret = GIF_INSUFFICIENT_FRAME_DATA;
@@ -907,16 +904,14 @@ static gif_result gif_clear_frame(
/* Clear our frame */
for (uint32_t y = 0; y < height; y++) {
- uint32_t *frame_scanline;
- frame_scanline = bitmap + offset_x + ((offset_y + y) * gif->width);
+ uint32_t *scanline;
+ scanline = bitmap + offset_x + ((offset_y + y) * gif->width);
if (frame->transparency) {
- memset(frame_scanline,
- GIF_TRANSPARENT_COLOUR,
- width * 4);
+ memset(scanline, GIF_TRANSPARENT_COLOUR, width * 4);
} else {
- memset(frame_scanline,
- colour_table[gif->background_index],
- width * 4);
+ for (uint32_t x = 0; x < width; x++) {
+ scanline[x] = gif->bg_colour;
+ }
}
}
@@ -1208,7 +1203,7 @@ gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data)
gif->height = gif_data[2] | (gif_data[3] << 8);
gif->global_colours = (gif_data[4] & GIF_COLOUR_TABLE_MASK);
gif->colour_table_size = (2 << (gif_data[4] & GIF_COLOUR_TABLE_SIZE_MASK));
- gif->background_index = gif_data[5];
+ gif->bg_index = gif_data[5];
gif->aspect_ratio = gif_data[6];
gif->loop_count = 1;
gif_data += 7;
@@ -1312,6 +1307,14 @@ gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data)
entry[1] = 0xffffffff;
}
+
+ if (gif->global_colours &&
+ gif->bg_index < gif->colour_table_size) {
+ size_t bg_idx = gif->bg_index;
+ gif->bg_colour = gif->global_colour_table[bg_idx];
+ } else {
+ gif->bg_colour = gif->global_colour_table[0];
+ }
}
/* Repeatedly try to initialise frames */