summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Cupitt <jcupitt@gmail.com>2021-04-01 12:53:57 +0100
committerMichael Drake <tlsa@netsurf-browser.org>2021-04-05 14:07:53 +0100
commitc817c6f1e48ffe98bf65d381f8b11cd4f82c83c6 (patch)
tree3f7ebfb6c2203db6bb1696121b6a9c23e0d791c8
parent6e42a2495ac64e41434f5ec3164bf5786d8d02ee (diff)
downloadlibnsgif-c817c6f1e48ffe98bf65d381f8b11cd4f82c83c6.tar.gz
libnsgif-c817c6f1e48ffe98bf65d381f8b11cd4f82c83c6.tar.bz2
Delay bitmap allocation until needed for frame decode.
Gives the client a chance to detect memory bombs.
-rw-r--r--src/libnsgif.c49
1 files changed, 16 insertions, 33 deletions
diff --git a/src/libnsgif.c b/src/libnsgif.c
index 7c40eeb..512ebfe 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -79,34 +79,17 @@ gif_initialise_sprite(gif_animation *gif,
unsigned int width,
unsigned int height)
{
- unsigned int max_width;
- unsigned int max_height;
- struct bitmap *buffer;
-
- /* Check if we've changed */
- if ((width <= gif->width) && (height <= gif->height)) {
+ /* Already allocated? */
+ if (gif->frame_image) {
return GIF_OK;
}
- /* Get our maximum values */
- max_width = (width > gif->width) ? width : gif->width;
- max_height = (height > gif->height) ? height : gif->height;
-
- /* Allocate some more memory */
assert(gif->bitmap_callbacks.bitmap_create);
- buffer = gif->bitmap_callbacks.bitmap_create(max_width, max_height);
- if (buffer == NULL) {
+ gif->frame_image = gif->bitmap_callbacks.bitmap_create(width, height);
+ if (gif->frame_image == NULL) {
return GIF_INSUFFICIENT_MEMORY;
}
- assert(gif->bitmap_callbacks.bitmap_destroy);
- gif->bitmap_callbacks.bitmap_destroy(gif->frame_image);
- gif->frame_image = buffer;
- gif->width = max_width;
- gif->height = max_height;
-
- /* Invalidate our currently decoded image */
- gif->decoded_frame = GIF_INVALID_FRAME;
return GIF_OK;
}
@@ -392,10 +375,12 @@ static gif_result gif_initialise_frame(gif_animation *gif)
gif->frames[frame].redraw_required = ((gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) ||
(gif->frames[frame].disposal_method == GIF_FRAME_RESTORE));
- /* Boundary checking - shouldn't ever happen except with junk data */
- if (gif_initialise_sprite(gif, (offset_x + width), (offset_y + height))) {
- return GIF_INSUFFICIENT_MEMORY;
- }
+ /* Frame size may have grown.
+ */
+ gif->width = (offset_x + width > gif->width) ?
+ offset_x + width : gif->width;
+ gif->height = (offset_y + height > gif->height) ?
+ offset_y + height : gif->height;
/* Decode the flags */
flags = gif_data[9];
@@ -744,6 +729,12 @@ gif_internal_decode_frame(gif_animation *gif,
goto gif_decode_frame_exit;
}
+ /* Make sure we have a buffer to decode to.
+ */
+ if (gif_initialise_sprite(gif, gif->width, gif->height)) {
+ return GIF_INSUFFICIENT_MEMORY;
+ }
+
/* Decode the flags */
flags = gif_data[9];
colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
@@ -1120,14 +1111,6 @@ gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data)
}
gif->frame_holders = 1;
- /* Initialise the bitmap header */
- assert(gif->bitmap_callbacks.bitmap_create);
- gif->frame_image = gif->bitmap_callbacks.bitmap_create(gif->width, gif->height);
- if (gif->frame_image == NULL) {
- gif_finalise(gif);
- return GIF_INSUFFICIENT_MEMORY;
- }
-
/* Remember we've done this now */
gif->buffer_position = gif_data - gif->gif_data;
}