summaryrefslogtreecommitdiff
path: root/src/libnsgif.c
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2021-11-04 15:03:40 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2021-11-04 15:03:40 +0000
commit5e0642811e2edce8d8845fdf0bcb8f9eefc71f80 (patch)
tree17186f6a9c5b3c1e0043ee393829d22b6de7221d /src/libnsgif.c
parent9f5e2f1af86d35247895dd57bf03f32c5539a04d (diff)
downloadlibnsgif-5e0642811e2edce8d8845fdf0bcb8f9eefc71f80.tar.gz
libnsgif-5e0642811e2edce8d8845fdf0bcb8f9eefc71f80.tar.bz2
GIF: Use same function for frame initialisation and decoding.
Now there aren't two entirely separate code paths that must be kept in sync.
Diffstat (limited to 'src/libnsgif.c')
-rw-r--r--src/libnsgif.c125
1 files changed, 42 insertions, 83 deletions
diff --git a/src/libnsgif.c b/src/libnsgif.c
index ce13041..2a1fdfe 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -967,6 +967,7 @@ static struct gif_frame *gif__get_frame(
*
* \param[in] gif The animation context
* \param[in] frame_idx The frame number to decode.
+ * \param[in] decode Whether to decode the graphical image data.
* \return error code
* - GIF_INSUFFICIENT_DATA for insufficient data to do anything
* - GIF_FRAME_DATA_ERROR for GIF frame data error
@@ -976,127 +977,85 @@ static struct gif_frame *gif__get_frame(
* - GIF_OK for successful decoding
* - GIF_WORKING for successful decoding if more frames are expected
*/
-static gif_result gif_initialise_frame(
+static gif_result gif__process_frame(
struct gif_animation *gif,
- uint32_t frame_idx)
+ uint32_t frame_idx,
+ bool decode)
{
uint8_t *pos;
uint8_t *end;
gif_result ret;
struct gif_frame *frame;
- /* Get our buffer position etc. */
- pos = (uint8_t *)(gif->gif_data + gif->buffer_position);
- end = (uint8_t *)(gif->gif_data + gif->buffer_size);
-
- /* Check if we've finished */
- if (pos < end && pos[0] == GIF_TRAILER) {
- return GIF_OK;
- }
-
- /* We could theoretically get some junk data that gives us millions of
- * frames, so we ensure that we don't have a silly number
- */
- if (frame_idx > 4096) {
- return GIF_FRAME_DATA_ERROR;
- }
-
frame = gif__get_frame(gif, frame_idx);
if (frame == NULL) {
return GIF_INSUFFICIENT_MEMORY;
}
- /* Initialise any extensions */
- ret = gif__parse_frame_extensions(gif, frame, &pos, true);
- if (ret != GIF_OK) {
- goto cleanup;
- }
-
- ret = gif__parse_image_descriptor(gif, frame, &pos, true);
- if (ret != GIF_OK) {
- goto cleanup;
- }
-
- ret = gif__parse_colour_table(gif, frame, &pos, false);
- if (ret != GIF_OK) {
- goto cleanup;
- }
-
- ret = gif__parse_image_data(gif, frame, &pos, false);
- if (ret != GIF_OK) {
- goto cleanup;
- }
-
-cleanup:
- gif->buffer_position = pos - gif->gif_data;
+ end = (uint8_t *)(gif->gif_data + gif->buffer_size);
- return ret;
-}
+ if (decode) {
+ pos = gif->gif_data + frame->frame_pointer;
-/**
- * decode a gif frame
- *
- * \param gif gif animation context.
- * \param frame The frame number to decode.
- * \param clear_image flag for image data being cleared instead of plotted.
- */
-static gif_result gif_internal_decode_frame(
- struct gif_animation *gif,
- uint32_t frame_idx)
-{
- uint8_t *pos;
- gif_result ret;
- struct gif_frame *frame;
+ /* Ensure this frame is supposed to be decoded */
+ if (frame->display == false) {
+ return GIF_OK;
+ }
- /* Ensure the frame is in range to decode */
- if (frame_idx > gif->frame_count_partial) {
- return GIF_INSUFFICIENT_DATA;
- }
+ /* Ensure the frame is in range to decode */
+ if (frame_idx > gif->frame_count_partial) {
+ return GIF_INSUFFICIENT_DATA;
+ }
- /* Done if frame is already decoded */
- if (((int)frame_idx == gif->decoded_frame)) {
- return GIF_OK;
- }
+ /* Done if frame is already decoded */
+ if ((int)frame_idx == gif->decoded_frame) {
+ return GIF_OK;
+ }
+ } else {
+ pos = (uint8_t *)(gif->gif_data + gif->buffer_position);
- frame = gif__get_frame(gif, frame_idx);
- if (frame == NULL) {
- return GIF_INSUFFICIENT_MEMORY;
- }
+ /* Check if we've finished */
+ if (pos < end && pos[0] == GIF_TRAILER) {
+ return GIF_OK;
+ }
- /* Ensure this frame is supposed to be decoded */
- if (frame->display == false) {
- return GIF_OK;
+ /* We could theoretically get some junk data that gives us
+ * millions of frames, so we ensure that we don't have a
+ * silly number. */
+ if (frame_idx > 4096) {
+ return GIF_FRAME_DATA_ERROR;
+ }
}
- /* Get the start of our frame data and the end of the GIF data. */
- pos = gif->gif_data + frame->frame_pointer;
-
- /* Skip any extensions because they have already been processed */
- ret = gif__parse_frame_extensions(gif, frame, &pos, false);
+ /* Initialise any extensions */
+ ret = gif__parse_frame_extensions(gif, frame, &pos, !decode);
if (ret != GIF_OK) {
goto cleanup;
}
- ret = gif__parse_image_descriptor(gif, frame, &pos, false);
+ ret = gif__parse_image_descriptor(gif, frame, &pos, !decode);
if (ret != GIF_OK) {
goto cleanup;
}
- ret = gif__parse_colour_table(gif, frame, &pos, true);
+ ret = gif__parse_colour_table(gif, frame, &pos, decode);
if (ret != GIF_OK) {
goto cleanup;
}
- ret = gif__parse_image_data(gif, frame, &pos, true);
+ ret = gif__parse_image_data(gif, frame, &pos, decode);
if (ret != GIF_OK) {
goto cleanup;
}
cleanup:
+ if (!decode) {
+ gif->buffer_position = pos - gif->gif_data;
+ }
+
return ret;
}
-
/* exported function documented in libnsgif.h */
void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks)
{
@@ -1294,7 +1253,7 @@ gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data)
}
/* Repeatedly try to initialise frames */
- while ((ret = gif_initialise_frame(gif, gif->frame_count)) == GIF_WORKING);
+ while ((ret = gif__process_frame(gif, gif->frame_count, false)) == GIF_WORKING);
/* If there was a memory error tell the caller */
if ((ret == GIF_INSUFFICIENT_MEMORY) ||
@@ -1317,7 +1276,7 @@ gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data)
/* exported function documented in libnsgif.h */
gif_result gif_decode_frame(gif_animation *gif, unsigned int frame)
{
- return gif_internal_decode_frame(gif, frame);
+ return gif__process_frame(gif, frame, true);
}