Gitweb links:

...log 
http://git.netsurf-browser.org/libnsgif.git/shortlog/d96f028f305b5286618dcfc682e0de2515b3b7bd
...commit 
http://git.netsurf-browser.org/libnsgif.git/commit/d96f028f305b5286618dcfc682e0de2515b3b7bd
...tree 
http://git.netsurf-browser.org/libnsgif.git/tree/d96f028f305b5286618dcfc682e0de2515b3b7bd

The branch, tlsa/rewrite has been created
        at  d96f028f305b5286618dcfc682e0de2515b3b7bd (commit)

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=d96f028f305b5286618dcfc682e0de2515b3b7bd
commit d96f028f305b5286618dcfc682e0de2515b3b7bd
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Store transparancy index on the frame.
    
    If the frame has no transparency, it is set to an invalid value.

diff --git a/include/libnsgif.h b/include/libnsgif.h
index a11c3a5..ae6691c 100644
--- a/include/libnsgif.h
+++ b/include/libnsgif.h
@@ -53,7 +53,7 @@ typedef struct gif_frame {
         /** whether we acknoledge transparency */
         bool transparency;
         /** the index designating a transparent pixel */
-        unsigned char transparency_index;
+        unsigned int transparency_index;
         /** x co-ordinate of redraw rectangle */
         unsigned int redraw_x;
         /** y co-ordinate of redraw rectangle */
diff --git a/src/libnsgif.c b/src/libnsgif.c
index 85a72b7..6ee7ab3 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -475,6 +475,7 @@ static gif_result gif_initialise_frame(gif_animation *gif,
        gif->frames[frame_idx].virgin = true;
        gif->frames[frame_idx].disposal_method = 0;
        gif->frames[frame_idx].transparency = false;
+       gif->frames[frame_idx].transparency_index = GIF_NO_TRANSPARENCY;
        gif->frames[frame_idx].frame_delay = 100;
        gif->frames[frame_idx].redraw_required = false;
 
@@ -808,14 +809,8 @@ static inline gif_result gif__decode(
        uint32_t width = frame->redraw_width;
        uint32_t height = frame->redraw_height;
        uint32_t interlace = frame->flags & GIF_INTERLACE_MASK;
+       uint32_t transparency_index = frame->transparency_index;
        uint32_t *restrict colour_table = gif->colour_table;
-       uint32_t transparency_index;
-
-       if (frame->transparency) {
-               transparency_index = frame->transparency_index;
-       } else {
-               transparency_index = GIF_NO_TRANSPARENCY;
-       }
 
        if (interlace == false && width == gif->width && offset_x == 0) {
                ret = gif__decode_simple(gif, height, offset_y,


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=2d440af6eed4d0ff82b8ef5143c7d2aee3856cc8
commit 2d440af6eed4d0ff82b8ef5143c7d2aee3856cc8
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Pass frame index into frame initialiser.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index c95753d..85a72b7 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -411,7 +411,8 @@ static gif_result gif__parse_colour_table(
 /**
  * Attempts to initialise the next frame
  *
- * \param gif The animation context
+ * \param[in] gif       The animation context
+ * \param[in] frame_idx The frame number to decode.
  * \return error code
  *         - GIF_INSUFFICIENT_DATA for insufficient data to do anything
  *         - GIF_FRAME_DATA_ERROR for GIF frame data error
@@ -421,18 +422,15 @@ static gif_result gif__parse_colour_table(
  *         - GIF_OK for successful decoding
  *         - GIF_WORKING for successful decoding if more frames are expected
 */
-static gif_result gif_initialise_frame(gif_animation *gif)
+static gif_result gif_initialise_frame(gif_animation *gif,
+               uint32_t frame_idx)
 {
        gif_result ret;
-       int frame;
        gif_frame *temp_buf;
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t block_size;
 
-       /* Get the frame to decode and our data position */
-       frame = gif->frame_count;
-
        /* Get our buffer position etc. */
        gif_data = (uint8_t *)(gif->gif_data + gif->buffer_position);
        gif_end = (uint8_t *)(gif->gif_data + gif->buffer_size);
@@ -454,34 +452,34 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        /* 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 > 4096) {
+       if (frame_idx > 4096) {
                return GIF_FRAME_DATA_ERROR;
        }
 
        /* Get some memory to store our pointers in etc. */
-       if ((int)gif->frame_holders <= frame) {
+       if (gif->frame_holders <= frame_idx) {
                /* Allocate more memory */
-               temp_buf = (gif_frame *)realloc(gif->frames, (frame + 1) * 
sizeof(gif_frame));
+               temp_buf = (gif_frame *)realloc(gif->frames, (frame_idx + 1) * 
sizeof(gif_frame));
                if (temp_buf == NULL) {
                        return GIF_INSUFFICIENT_MEMORY;
                }
                gif->frames = temp_buf;
-               gif->frame_holders = frame + 1;
+               gif->frame_holders = frame_idx + 1;
        }
 
        /* Store our frame pointer. We would do it when allocating except we
         * start off with one frame allocated so we can always use realloc.
         */
-       gif->frames[frame].frame_pointer = gif->buffer_position;
-       gif->frames[frame].display = false;
-       gif->frames[frame].virgin = true;
-       gif->frames[frame].disposal_method = 0;
-       gif->frames[frame].transparency = false;
-       gif->frames[frame].frame_delay = 100;
-       gif->frames[frame].redraw_required = false;
+       gif->frames[frame_idx].frame_pointer = gif->buffer_position;
+       gif->frames[frame_idx].display = false;
+       gif->frames[frame_idx].virgin = true;
+       gif->frames[frame_idx].disposal_method = 0;
+       gif->frames[frame_idx].transparency = false;
+       gif->frames[frame_idx].frame_delay = 100;
+       gif->frames[frame_idx].redraw_required = false;
 
        /* Invalidate any previous decoding we have of this frame */
-       if (gif->decoded_frame == frame) {
+       if (gif->decoded_frame == (int)frame_idx) {
                gif->decoded_frame = GIF_INVALID_FRAME;
        }
 
@@ -493,17 +491,17 @@ static gif_result gif_initialise_frame(gif_animation *gif)
 
        /* Initialise any extensions */
        gif->buffer_position = gif_data - gif->gif_data;
-       ret = gif__parse_frame_extensions(gif, &gif->frames[frame], true);
+       ret = gif__parse_frame_extensions(gif, &gif->frames[frame_idx], true);
        if (ret != GIF_OK) {
                return ret;
        }
 
-       ret = gif__parse_image_descriptor(gif, &gif->frames[frame], true);
+       ret = gif__parse_image_descriptor(gif, &gif->frames[frame_idx], true);
        if (ret != GIF_OK) {
                return ret;
        }
 
-       ret = gif__parse_colour_table(gif, &gif->frames[frame], false);
+       ret = gif__parse_colour_table(gif, &gif->frames[frame_idx], false);
        if (ret != GIF_OK) {
                return ret;
        }
@@ -511,7 +509,7 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        gif_bytes = (gif_end - gif_data);
 
        /* Move our data onwards and remember we've got a bit of this frame */
-       gif->frame_count_partial = frame + 1;
+       gif->frame_count_partial = frame_idx + 1;
 
        /* Ensure we have a correct code size */
        if (gif_bytes < 1) {
@@ -556,8 +554,8 @@ static gif_result gif_initialise_frame(gif_animation *gif)
 
        /* Add the frame and set the display flag */
        gif->buffer_position = gif_data - gif->gif_data;
-       gif->frame_count = frame + 1;
-       gif->frames[frame].display = true;
+       gif->frame_count = frame_idx + 1;
+       gif->frames[frame_idx].display = true;
 
        /* Check if we've finished */
        if (gif_bytes < 1) {
@@ -1262,7 +1260,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_WORKING);
+       while ((ret = gif_initialise_frame(gif, gif->frame_count)) == 
GIF_WORKING);
 
        /* If there was a memory error tell the caller */
        if ((ret == GIF_INSUFFICIENT_MEMORY) ||


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=ea368d768fa12bffd51b0c8f38c374c5d398c859
commit ea368d768fa12bffd51b0c8f38c374c5d398c859
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Move frame parameter extraction into decode wrapper.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index d69b8c7..c95753d 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -801,16 +801,16 @@ gif__decode_simple(
 static inline gif_result gif__decode(
                struct gif_animation *gif,
                struct gif_frame *frame,
-               uint32_t width,
-               uint32_t height,
-               uint32_t offset_x,
-               uint32_t offset_y,
-               uint32_t interlace,
                uint8_t minimum_code_size,
-               uint32_t *restrict frame_data,
-               uint32_t *restrict colour_table)
+               uint32_t *restrict frame_data)
 {
        gif_result ret;
+       uint32_t offset_x = frame->redraw_x;
+       uint32_t offset_y = frame->redraw_y;
+       uint32_t width = frame->redraw_width;
+       uint32_t height = frame->redraw_height;
+       uint32_t interlace = frame->flags & GIF_INTERLACE_MASK;
+       uint32_t *restrict colour_table = gif->colour_table;
        uint32_t transparency_index;
 
        if (frame->transparency) {
@@ -846,7 +846,10 @@ static gif_result gif_clear_frame(
                struct gif_frame *frame,
                uint32_t *bitmap)
 {
-       uint32_t width, height, offset_x, offset_y;
+       uint32_t width;
+       uint32_t height;
+       uint32_t offset_x;
+       uint32_t offset_y;
 
        assert(frame->disposal_method == GIF_FRAME_CLEAR);
 
@@ -905,9 +908,6 @@ gif_internal_decode_frame(gif_animation *gif,
        struct gif_frame *frame;
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
-       uint32_t width, height, offset_x, offset_y;
-       uint32_t interlace;
-       uint32_t *colour_table;
        uint32_t *frame_data = 0; // Set to 0 for no warnings
        uint32_t save_buffer_position;
 
@@ -955,14 +955,6 @@ gif_internal_decode_frame(gif_animation *gif,
        gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
 
-       offset_x = frame->redraw_x;
-       offset_y = frame->redraw_y;
-       width = frame->redraw_width;
-       height = frame->redraw_height;
-       interlace = frame->flags & GIF_INTERLACE_MASK;
-
-       colour_table = gif->colour_table;
-
        /* Ensure sufficient data remains */
        if (gif_bytes < 1) {
                ret = GIF_INSUFFICIENT_FRAME_DATA;
@@ -1038,9 +1030,7 @@ gif_internal_decode_frame(gif_animation *gif,
        gif->decoded_frame = frame_idx;
        gif->buffer_position = (gif_data - gif->gif_data) + 1;
 
-       ret = gif__decode(gif, frame, width, height,
-                       offset_x, offset_y, interlace, gif_data[0],
-                       frame_data, colour_table);
+       ret = gif__decode(gif, frame, gif_data[0], frame_data);
 
 gif_decode_frame_exit:
 


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=999dd692409595601648495543e16e70bc946e45
commit 999dd692409595601648495543e16e70bc946e45
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Clear: Don't need to decode the previous frame metadata now.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 352bbb9..d69b8c7 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -846,11 +846,7 @@ static gif_result gif_clear_frame(
                struct gif_frame *frame,
                uint32_t *bitmap)
 {
-       gif_result ret;
-       uint8_t *gif_data, *gif_end;
-       int gif_bytes;
        uint32_t width, height, offset_x, offset_y;
-       uint32_t save_buffer_position;
 
        assert(frame->disposal_method == GIF_FRAME_CLEAR);
 
@@ -859,50 +855,11 @@ static gif_result gif_clear_frame(
                return GIF_OK;
        }
 
-       /* Get the start of our frame data and the end of the GIF data */
-       gif_data = gif->gif_data + frame->frame_pointer;
-       gif_end = gif->gif_data + gif->buffer_size;
-       gif_bytes = (gif_end - gif_data);
-
-       /* Save the buffer position */
-       save_buffer_position = gif->buffer_position;
-       gif->buffer_position = gif_data - gif->gif_data;
-
-       /* Skip any extensions because they have already been processed */
-       ret = gif__parse_frame_extensions(gif, frame, false);
-       if (ret != GIF_OK) {
-               goto gif_decode_frame_exit;
-       }
-
-       ret = gif__parse_image_descriptor(gif, frame, false);
-       if (ret != GIF_OK) {
-               goto gif_decode_frame_exit;
-       }
-
-       ret = gif__parse_colour_table(gif, frame, false);
-       if (ret != GIF_OK) {
-               goto gif_decode_frame_exit;
-       }
-       gif_data = gif->gif_data + gif->buffer_position;
-       gif_bytes = (gif_end - gif_data);
-
        offset_x = frame->redraw_x;
        offset_y = frame->redraw_y;
        width = frame->redraw_width;
        height = frame->redraw_height;
 
-       /* Ensure sufficient data remains */
-       if (gif_bytes < 1) {
-               ret = GIF_INSUFFICIENT_FRAME_DATA;
-               goto gif_decode_frame_exit;
-       }
-
-       /* check for an end marker */
-       if (gif_data[0] == GIF_TRAILER) {
-               ret = GIF_OK;
-               goto gif_decode_frame_exit;
-       }
-
        /* Clear our frame */
        for (uint32_t y = 0; y < height; y++) {
                uint32_t *scanline;
@@ -916,11 +873,7 @@ static gif_result gif_clear_frame(
                }
        }
 
-gif_decode_frame_exit:
-       /* Restore the buffer position */
-       gif->buffer_position = save_buffer_position;
-
-       return ret;
+       return GIF_OK;
 }
 
 /**


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=1fbc97ea763c3f76eea43695637fe283ce831746
commit 1fbc97ea763c3f76eea43695637fe283ce831746
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Unify calculation of transparency index.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 47f02fa..352bbb9 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -673,18 +673,18 @@ static gif_result gif__recover_frame(const gif_animation 
*gif)
 }
 
 static gif_result
-gif__decode_complex(gif_animation *gif,
-               uint32_t frame,
+gif__decode_complex(
+               struct gif_animation *gif,
                uint32_t width,
                uint32_t height,
                uint32_t offset_x,
                uint32_t offset_y,
                uint32_t interlace,
                uint8_t minimum_code_size,
+               uint32_t transparency_index,
                uint32_t *restrict frame_data,
                uint32_t *restrict colour_table)
 {
-       uint32_t transparency_index;
        uint32_t available = 0;
        gif_result ret = GIF_OK;
        lzw_result res;
@@ -696,10 +696,6 @@ gif__decode_complex(gif_animation *gif,
                return gif_error_from_lzw(res);
        }
 
-       transparency_index = gif->frames[frame].transparency ?
-                       gif->frames[frame].transparency_index :
-                       GIF_NO_TRANSPARENCY;
-
        for (uint32_t y = 0; y < height; y++) {
                uint32_t x;
                uint32_t decode_y;
@@ -755,24 +751,20 @@ gif__decode_complex(gif_animation *gif,
 }
 
 static gif_result
-gif__decode_simple(gif_animation *gif,
-               uint32_t frame,
+gif__decode_simple(
+               struct gif_animation *gif,
                uint32_t height,
                uint32_t offset_y,
                uint8_t minimum_code_size,
+               uint32_t transparency_index,
                uint32_t *restrict frame_data,
                uint32_t *restrict colour_table)
 {
-       uint32_t transparency_index;
        uint32_t pixels = gif->width * height;
        uint32_t written = 0;
        gif_result ret = GIF_OK;
        lzw_result res;
 
-       transparency_index = gif->frames[frame].transparency ?
-                       gif->frames[frame].transparency_index :
-                       GIF_NO_TRANSPARENCY;
-
        /* Initialise the LZW decoding */
        res = lzw_decode_init_map(gif->lzw_ctx,
                        minimum_code_size, transparency_index, colour_table,
@@ -806,9 +798,9 @@ gif__decode_simple(gif_animation *gif,
        return ret;
 }
 
-static inline gif_result
-gif__decode(gif_animation *gif,
-               uint32_t frame,
+static inline gif_result gif__decode(
+               struct gif_animation *gif,
+               struct gif_frame *frame,
                uint32_t width,
                uint32_t height,
                uint32_t offset_x,
@@ -819,14 +811,23 @@ gif__decode(gif_animation *gif,
                uint32_t *restrict colour_table)
 {
        gif_result ret;
+       uint32_t transparency_index;
+
+       if (frame->transparency) {
+               transparency_index = frame->transparency_index;
+       } else {
+               transparency_index = GIF_NO_TRANSPARENCY;
+       }
 
        if (interlace == false && width == gif->width && offset_x == 0) {
-               ret = gif__decode_simple(gif, frame, height, offset_y,
-                               minimum_code_size, frame_data, colour_table);
+               ret = gif__decode_simple(gif, height, offset_y,
+                               minimum_code_size, transparency_index,
+                               frame_data, colour_table);
        } else {
-               ret = gif__decode_complex(gif, frame, width, height,
+               ret = gif__decode_complex(gif, width, height,
                                offset_x, offset_y, interlace,
-                               minimum_code_size, frame_data, colour_table);
+                               minimum_code_size, transparency_index,
+                               frame_data, colour_table);
        }
 
        return ret;
@@ -1084,7 +1085,7 @@ gif_internal_decode_frame(gif_animation *gif,
        gif->decoded_frame = frame_idx;
        gif->buffer_position = (gif_data - gif->gif_data) + 1;
 
-       ret = gif__decode(gif, frame_idx, width, height,
+       ret = gif__decode(gif, frame, width, height,
                        offset_x, offset_y, interlace, gif_data[0],
                        frame_data, colour_table);
 


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=41f33c7495e7b83b40a93e4a76481d770f0c5f7b
commit 41f33c7495e7b83b40a93e4a76481d770f0c5f7b
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    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.

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 */


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=42cfb0d9a5b4e6dbf0981262916e160be438157b
commit 42cfb0d9a5b4e6dbf0981262916e160be438157b
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Rename frame record/recover functions.
    
    Calling it "previous" frame doesn't really make sense.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 2fd1bd7..80e6c7b 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -604,7 +604,7 @@ static gif_result gif_error_from_lzw(lzw_result l_res)
        return g_res[l_res];
 }
 
-static void gif__record_previous_frame(gif_animation *gif)
+static void gif__record_frame(gif_animation *gif)
 {
        bool need_alloc = gif->prev_frame == NULL;
        const uint32_t *frame_data;
@@ -645,7 +645,7 @@ static void gif__record_previous_frame(gif_animation *gif)
        gif->prev_index  = gif->decoded_frame;
 }
 
-static gif_result gif__recover_previous_frame(const gif_animation *gif)
+static gif_result gif__recover_frame(const gif_animation *gif)
 {
        const uint32_t *prev_frame = gif->prev_frame;
        unsigned height = gif->height < gif->prev_height ? gif->height : 
gif->prev_height;
@@ -1074,7 +1074,7 @@ gif_internal_decode_frame(gif_animation *gif,
                         * If the previous frame's disposal method requires we
                         * restore the previous image, restore our saved image.
                         */
-                       ret = gif__recover_previous_frame(gif);
+                       ret = gif__recover_frame(gif);
                        if (ret != GIF_OK) {
                                gif__wipe_bitmap(gif, frame_data);
                        }
@@ -1083,7 +1083,7 @@ gif_internal_decode_frame(gif_animation *gif,
 
        if (frame->disposal_method == GIF_FRAME_RESTORE) {
                /* Store the previous frame for later restoration */
-               gif__record_previous_frame(gif);
+               gif__record_frame(gif);
        }
 
        gif->decoded_frame = frame_idx;


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=6765615f800be363c88f085f7b2ebf1dd3d68b26
commit 6765615f800be363c88f085f7b2ebf1dd3d68b26
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Decode: Split out bitmap wipe to transparent.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 1f8c25e..2fd1bd7 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -928,6 +928,20 @@ gif_decode_frame_exit:
 }
 
 /**
+ * Wipe bitmap to transparent.
+ *
+ * \param[in] gif     The gif object we're decoding.
+ * \param[in] bitmap  The bitmap to wipe.
+ */
+static inline void gif__wipe_bitmap(
+               const struct gif_animation *gif,
+               uint32_t *bitmap)
+{
+       memset((char*)bitmap, GIF_TRANSPARENT_COLOUR,
+                       gif->width * gif->height * sizeof(*bitmap));
+}
+
+/**
  * decode a gif frame
  *
  * \param gif gif animation context.
@@ -1045,9 +1059,7 @@ gif_internal_decode_frame(gif_animation *gif,
        /* Handle any bitmap clearing/restoration required before decoding this
         * frame. */
        if (frame_idx == 0 || gif->decoded_frame == GIF_INVALID_FRAME) {
-               memset((char*)frame_data,
-                      GIF_TRANSPARENT_COLOUR,
-                      gif->width * gif->height * sizeof(*frame_data));
+               gif__wipe_bitmap(gif, frame_data);
 
        } else {
                struct gif_frame *prev = &gif->frames[frame_idx - 1];
@@ -1064,12 +1076,7 @@ gif_internal_decode_frame(gif_animation *gif,
                         */
                        ret = gif__recover_previous_frame(gif);
                        if (ret != GIF_OK) {
-                               /* see notes above on transparency
-                                * vs. background color
-                                */
-                               memset((char*)frame_data,
-                                      GIF_TRANSPARENT_COLOUR,
-                                      gif->width * gif->height * sizeof(int));
+                               gif__wipe_bitmap(gif, frame_data);
                        }
                }
        }


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=58efffc9ec484899333458746bc169b03d69293b
commit 58efffc9ec484899333458746bc169b03d69293b
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Decode: Clean up frame clearing/restoration.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 0784adb..1f8c25e 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -1042,36 +1042,35 @@ gif_internal_decode_frame(gif_animation *gif,
                goto gif_decode_frame_exit;
        }
 
-       /* If the previous frame's disposal method requires we restore
-        * the background colour or this is the first frame, clear
-        * the frame data
-        */
+       /* Handle any bitmap clearing/restoration required before decoding this
+        * frame. */
        if (frame_idx == 0 || gif->decoded_frame == GIF_INVALID_FRAME) {
                memset((char*)frame_data,
                       GIF_TRANSPARENT_COLOUR,
                       gif->width * gif->height * sizeof(*frame_data));
 
-       } else if ((frame_idx != 0) &&
-                  (gif->frames[frame_idx - 1].disposal_method == 
GIF_FRAME_CLEAR)) {
-               ret = gif_clear_frame(gif, &gif->frames[frame_idx - 1], 
frame_data);
-               if (ret != GIF_OK) {
-                       goto gif_decode_frame_exit;
-               }
+       } else {
+               struct gif_frame *prev = &gif->frames[frame_idx - 1];
 
-       } else if ((frame_idx != 0) &&
-                  (gif->frames[frame_idx - 1].disposal_method == 
GIF_FRAME_RESTORE)) {
-               /*
-                * If the previous frame's disposal method requires we
-                * restore the previous image, restore our saved image.
-                */
-               ret = gif__recover_previous_frame(gif);
-               if (ret != GIF_OK) {
-                       /* see notes above on transparency
-                        * vs. background color
+               if (prev->disposal_method == GIF_FRAME_CLEAR) {
+                       ret = gif_clear_frame(gif, prev, frame_data);
+                       if (ret != GIF_OK) {
+                               goto gif_decode_frame_exit;
+                       }
+               } else if (prev->disposal_method == GIF_FRAME_RESTORE) {
+                       /*
+                        * If the previous frame's disposal method requires we
+                        * restore the previous image, restore our saved image.
                         */
-                       memset((char*)frame_data,
-                              GIF_TRANSPARENT_COLOUR,
-                              gif->width * gif->height * sizeof(int));
+                       ret = gif__recover_previous_frame(gif);
+                       if (ret != GIF_OK) {
+                               /* see notes above on transparency
+                                * vs. background color
+                                */
+                               memset((char*)frame_data,
+                                      GIF_TRANSPARENT_COLOUR,
+                                      gif->width * gif->height * sizeof(int));
+                       }
                }
        }
 


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=b8ae276840d1ad997d2400b001d2ca47b94ed4a7
commit b8ae276840d1ad997d2400b001d2ca47b94ed4a7
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Decode: Avoid indexing to frame structue.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index aa8fc83..0784adb 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -939,6 +939,7 @@ gif_internal_decode_frame(gif_animation *gif,
                          uint32_t frame_idx)
 {
        gif_result ret;
+       struct gif_frame *frame;
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t width, height, offset_x, offset_y;
@@ -947,23 +948,25 @@ gif_internal_decode_frame(gif_animation *gif,
        uint32_t *frame_data = 0; // Set to 0 for no warnings
        uint32_t save_buffer_position;
 
-       /* Ensure this frame is supposed to be decoded */
-       if (gif->frames[frame_idx].display == false) {
-               return GIF_OK;
-       }
-
        /* 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 */
+       /* Done if frame is already decoded */
        if (((int)frame_idx == gif->decoded_frame)) {
                return GIF_OK;
        }
 
+       frame = &gif->frames[frame_idx];
+
+       /* Ensure this frame is supposed to be decoded */
+       if (frame->display == false) {
+               return GIF_OK;
+       }
+
        /* Get the start of our frame data and the end of the GIF data */
-       gif_data = gif->gif_data + gif->frames[frame_idx].frame_pointer;
+       gif_data = gif->gif_data + frame->frame_pointer;
        gif_end = gif->gif_data + gif->buffer_size;
        gif_bytes = (gif_end - gif_data);
 
@@ -972,28 +975,28 @@ gif_internal_decode_frame(gif_animation *gif,
        gif->buffer_position = gif_data - gif->gif_data;
 
        /* Skip any extensions because they have already been processed */
-       ret = gif__parse_frame_extensions(gif, &gif->frames[frame_idx], false);
+       ret = gif__parse_frame_extensions(gif, frame, false);
        if (ret != GIF_OK) {
                goto gif_decode_frame_exit;
        }
 
-       ret = gif__parse_image_descriptor(gif, &gif->frames[frame_idx], false);
+       ret = gif__parse_image_descriptor(gif, frame, false);
        if (ret != GIF_OK) {
                goto gif_decode_frame_exit;
        }
 
-       ret = gif__parse_colour_table(gif, &gif->frames[frame_idx], true);
+       ret = gif__parse_colour_table(gif, frame, true);
        if (ret != GIF_OK) {
                return ret;
        }
        gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
 
-       offset_x = gif->frames[frame_idx].redraw_x;
-       offset_y = gif->frames[frame_idx].redraw_y;
-       width = gif->frames[frame_idx].redraw_width;
-       height = gif->frames[frame_idx].redraw_height;
-       interlace = gif->frames[frame_idx].flags & GIF_INTERLACE_MASK;
+       offset_x = frame->redraw_x;
+       offset_y = frame->redraw_y;
+       width = frame->redraw_width;
+       height = frame->redraw_height;
+       interlace = frame->flags & GIF_INTERLACE_MASK;
 
        colour_table = gif->colour_table;
 
@@ -1072,7 +1075,7 @@ gif_internal_decode_frame(gif_animation *gif,
                }
        }
 
-       if (gif->frames[frame_idx].disposal_method == GIF_FRAME_RESTORE) {
+       if (frame->disposal_method == GIF_FRAME_RESTORE) {
                /* Store the previous frame for later restoration */
                gif__record_previous_frame(gif);
        }
@@ -1091,17 +1094,17 @@ gif_decode_frame_exit:
        }
 
        /* Check if we should test for optimisation */
-       if (gif->frames[frame_idx].virgin) {
+       if (frame->virgin) {
                if (gif->bitmap_callbacks.bitmap_test_opaque) {
-                       gif->frames[frame_idx].opaque = 
gif->bitmap_callbacks.bitmap_test_opaque(gif->frame_image);
+                       frame->opaque = 
gif->bitmap_callbacks.bitmap_test_opaque(gif->frame_image);
                } else {
-                       gif->frames[frame_idx].opaque = false;
+                       frame->opaque = false;
                }
-               gif->frames[frame_idx].virgin = false;
+               frame->virgin = false;
        }
 
        if (gif->bitmap_callbacks.bitmap_set_opaque) {
-               gif->bitmap_callbacks.bitmap_set_opaque(gif->frame_image, 
gif->frames[frame_idx].opaque);
+               gif->bitmap_callbacks.bitmap_set_opaque(gif->frame_image, 
frame->opaque);
        }
 
        /* Restore the buffer position */


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=a13205c215f879c0e63d736fca2f56028b243ffa
commit a13205c215f879c0e63d736fca2f56028b243ffa
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Rename frame to frame_idx through decode function.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index e3cb1b5..aa8fc83 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -936,7 +936,7 @@ gif_decode_frame_exit:
  */
 static gif_result
 gif_internal_decode_frame(gif_animation *gif,
-                         uint32_t frame)
+                         uint32_t frame_idx)
 {
        gif_result ret;
        uint8_t *gif_data, *gif_end;
@@ -948,22 +948,22 @@ gif_internal_decode_frame(gif_animation *gif,
        uint32_t save_buffer_position;
 
        /* Ensure this frame is supposed to be decoded */
-       if (gif->frames[frame].display == false) {
+       if (gif->frames[frame_idx].display == false) {
                return GIF_OK;
        }
 
        /* Ensure the frame is in range to decode */
-       if (frame > gif->frame_count_partial) {
+       if (frame_idx > gif->frame_count_partial) {
                return GIF_INSUFFICIENT_DATA;
        }
 
        /* done if frame is already decoded */
-       if (((int)frame == gif->decoded_frame)) {
+       if (((int)frame_idx == gif->decoded_frame)) {
                return GIF_OK;
        }
 
        /* Get the start of our frame data and the end of the GIF data */
-       gif_data = gif->gif_data + gif->frames[frame].frame_pointer;
+       gif_data = gif->gif_data + gif->frames[frame_idx].frame_pointer;
        gif_end = gif->gif_data + gif->buffer_size;
        gif_bytes = (gif_end - gif_data);
 
@@ -972,28 +972,28 @@ gif_internal_decode_frame(gif_animation *gif,
        gif->buffer_position = gif_data - gif->gif_data;
 
        /* Skip any extensions because they have already been processed */
-       ret = gif__parse_frame_extensions(gif, &gif->frames[frame], false);
+       ret = gif__parse_frame_extensions(gif, &gif->frames[frame_idx], false);
        if (ret != GIF_OK) {
                goto gif_decode_frame_exit;
        }
 
-       ret = gif__parse_image_descriptor(gif, &gif->frames[frame], false);
+       ret = gif__parse_image_descriptor(gif, &gif->frames[frame_idx], false);
        if (ret != GIF_OK) {
                goto gif_decode_frame_exit;
        }
 
-       ret = gif__parse_colour_table(gif, &gif->frames[frame], true);
+       ret = gif__parse_colour_table(gif, &gif->frames[frame_idx], true);
        if (ret != GIF_OK) {
                return ret;
        }
        gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
 
-       offset_x = gif->frames[frame].redraw_x;
-       offset_y = gif->frames[frame].redraw_y;
-       width = gif->frames[frame].redraw_width;
-       height = gif->frames[frame].redraw_height;
-       interlace = gif->frames[frame].flags & GIF_INTERLACE_MASK;
+       offset_x = gif->frames[frame_idx].redraw_x;
+       offset_y = gif->frames[frame_idx].redraw_y;
+       width = gif->frames[frame_idx].redraw_width;
+       height = gif->frames[frame_idx].redraw_height;
+       interlace = gif->frames[frame_idx].flags & GIF_INTERLACE_MASK;
 
        colour_table = gif->colour_table;
 
@@ -1043,20 +1043,20 @@ gif_internal_decode_frame(gif_animation *gif,
         * the background colour or this is the first frame, clear
         * the frame data
         */
-       if (frame == 0 || gif->decoded_frame == GIF_INVALID_FRAME) {
+       if (frame_idx == 0 || gif->decoded_frame == GIF_INVALID_FRAME) {
                memset((char*)frame_data,
                       GIF_TRANSPARENT_COLOUR,
                       gif->width * gif->height * sizeof(*frame_data));
 
-       } else if ((frame != 0) &&
-                  (gif->frames[frame - 1].disposal_method == GIF_FRAME_CLEAR)) 
{
-               ret = gif_clear_frame(gif, &gif->frames[frame - 1], frame_data);
+       } else if ((frame_idx != 0) &&
+                  (gif->frames[frame_idx - 1].disposal_method == 
GIF_FRAME_CLEAR)) {
+               ret = gif_clear_frame(gif, &gif->frames[frame_idx - 1], 
frame_data);
                if (ret != GIF_OK) {
                        goto gif_decode_frame_exit;
                }
 
-       } else if ((frame != 0) &&
-                  (gif->frames[frame - 1].disposal_method == 
GIF_FRAME_RESTORE)) {
+       } else if ((frame_idx != 0) &&
+                  (gif->frames[frame_idx - 1].disposal_method == 
GIF_FRAME_RESTORE)) {
                /*
                 * If the previous frame's disposal method requires we
                 * restore the previous image, restore our saved image.
@@ -1072,15 +1072,15 @@ gif_internal_decode_frame(gif_animation *gif,
                }
        }
 
-       if (gif->frames[frame].disposal_method == GIF_FRAME_RESTORE) {
+       if (gif->frames[frame_idx].disposal_method == GIF_FRAME_RESTORE) {
                /* Store the previous frame for later restoration */
                gif__record_previous_frame(gif);
        }
 
-       gif->decoded_frame = frame;
+       gif->decoded_frame = frame_idx;
        gif->buffer_position = (gif_data - gif->gif_data) + 1;
 
-       ret = gif__decode(gif, frame, width, height,
+       ret = gif__decode(gif, frame_idx, width, height,
                        offset_x, offset_y, interlace, gif_data[0],
                        frame_data, colour_table);
 
@@ -1091,17 +1091,17 @@ gif_decode_frame_exit:
        }
 
        /* Check if we should test for optimisation */
-       if (gif->frames[frame].virgin) {
+       if (gif->frames[frame_idx].virgin) {
                if (gif->bitmap_callbacks.bitmap_test_opaque) {
-                       gif->frames[frame].opaque = 
gif->bitmap_callbacks.bitmap_test_opaque(gif->frame_image);
+                       gif->frames[frame_idx].opaque = 
gif->bitmap_callbacks.bitmap_test_opaque(gif->frame_image);
                } else {
-                       gif->frames[frame].opaque = false;
+                       gif->frames[frame_idx].opaque = false;
                }
-               gif->frames[frame].virgin = false;
+               gif->frames[frame_idx].virgin = false;
        }
 
        if (gif->bitmap_callbacks.bitmap_set_opaque) {
-               gif->bitmap_callbacks.bitmap_set_opaque(gif->frame_image, 
gif->frames[frame].opaque);
+               gif->bitmap_callbacks.bitmap_set_opaque(gif->frame_image, 
gif->frames[frame_idx].opaque);
        }
 
        /* Restore the buffer position */


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=1f87439ecacaecbf70fdd740708745b1b90cad89
commit 1f87439ecacaecbf70fdd740708745b1b90cad89
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Clean up preparation for first frame.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index fa9d8d0..e3cb1b5 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -1043,15 +1043,11 @@ gif_internal_decode_frame(gif_animation *gif,
         * the background colour or this is the first frame, clear
         * the frame data
         */
-       if ((frame == 0) || (gif->decoded_frame == GIF_INVALID_FRAME)) {
+       if (frame == 0 || gif->decoded_frame == GIF_INVALID_FRAME) {
                memset((char*)frame_data,
                       GIF_TRANSPARENT_COLOUR,
-                      gif->width * gif->height * sizeof(int));
-               gif->decoded_frame = frame;
-               /* The line below would fill the image with its
-                * background color, but because GIFs support
-                * transparency we likely wouldn't want to do that. */
-               /* memset((char*)frame_data, 
colour_table[gif->background_index], gif->width * gif->height * sizeof(int)); */
+                      gif->width * gif->height * sizeof(*frame_data));
+
        } else if ((frame != 0) &&
                   (gif->frames[frame - 1].disposal_method == GIF_FRAME_CLEAR)) 
{
                ret = gif_clear_frame(gif, &gif->frames[frame - 1], frame_data);


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=827903b2cc1222b476c7f47bb462f526cb14a52c
commit 827903b2cc1222b476c7f47bb462f526cb14a52c
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Fix inconsistent function return value handling.
    
    This uses the proper enum type, a consistent name for return
    values, and corects cleanup on error.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index daf4628..fa9d8d0 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -423,13 +423,12 @@ static gif_result gif__parse_colour_table(
 */
 static gif_result gif_initialise_frame(gif_animation *gif)
 {
+       gif_result ret;
        int frame;
        gif_frame *temp_buf;
-
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t block_size;
-       gif_result return_value;
 
        /* Get the frame to decode and our data position */
        frame = gif->frame_count;
@@ -494,19 +493,19 @@ static gif_result gif_initialise_frame(gif_animation *gif)
 
        /* Initialise any extensions */
        gif->buffer_position = gif_data - gif->gif_data;
-       return_value = gif__parse_frame_extensions(gif, &gif->frames[frame], 
true);
-       if (return_value != GIF_OK) {
-               return return_value;
+       ret = gif__parse_frame_extensions(gif, &gif->frames[frame], true);
+       if (ret != GIF_OK) {
+               return ret;
        }
 
-       return_value = gif__parse_image_descriptor(gif, &gif->frames[frame], 
true);
-       if (return_value != GIF_OK) {
-               return return_value;
+       ret = gif__parse_image_descriptor(gif, &gif->frames[frame], true);
+       if (ret != GIF_OK) {
+               return ret;
        }
 
-       return_value = gif__parse_colour_table(gif, &gif->frames[frame], false);
-       if (return_value != GIF_OK) {
-               return return_value;
+       ret = gif__parse_colour_table(gif, &gif->frames[frame], false);
+       if (ret != GIF_OK) {
+               return ret;
        }
        gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
@@ -846,12 +845,12 @@ static gif_result gif_clear_frame(
                struct gif_frame *frame,
                uint32_t *bitmap)
 {
+       gif_result ret;
        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;
-       uint32_t return_value = 0;
 
        assert(frame->disposal_method == GIF_FRAME_CLEAR);
 
@@ -870,19 +869,19 @@ static gif_result gif_clear_frame(
        gif->buffer_position = gif_data - gif->gif_data;
 
        /* Skip any extensions because they have already been processed */
-       return_value = gif__parse_frame_extensions(gif, frame, false);
-       if (return_value != GIF_OK) {
+       ret = gif__parse_frame_extensions(gif, frame, false);
+       if (ret != GIF_OK) {
                goto gif_decode_frame_exit;
        }
 
-       return_value = gif__parse_image_descriptor(gif, frame, false);
-       if (return_value != GIF_OK) {
-               return return_value;
+       ret = gif__parse_image_descriptor(gif, frame, false);
+       if (ret != GIF_OK) {
+               goto gif_decode_frame_exit;
        }
 
-       return_value = gif__parse_colour_table(gif, frame, true);
-       if (return_value != GIF_OK) {
-               return return_value;
+       ret = gif__parse_colour_table(gif, frame, true);
+       if (ret != GIF_OK) {
+               goto gif_decode_frame_exit;
        }
        gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
@@ -896,13 +895,13 @@ static gif_result gif_clear_frame(
 
        /* Ensure sufficient data remains */
        if (gif_bytes < 1) {
-               return_value = GIF_INSUFFICIENT_FRAME_DATA;
+               ret = GIF_INSUFFICIENT_FRAME_DATA;
                goto gif_decode_frame_exit;
        }
 
        /* check for an end marker */
        if (gif_data[0] == GIF_TRAILER) {
-               return_value = GIF_OK;
+               ret = GIF_OK;
                goto gif_decode_frame_exit;
        }
 
@@ -925,7 +924,7 @@ gif_decode_frame_exit:
        /* Restore the buffer position */
        gif->buffer_position = save_buffer_position;
 
-       return return_value;
+       return ret;
 }
 
 /**
@@ -939,7 +938,7 @@ static gif_result
 gif_internal_decode_frame(gif_animation *gif,
                          uint32_t frame)
 {
-       gif_result err;
+       gif_result ret;
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t width, height, offset_x, offset_y;
@@ -947,7 +946,6 @@ gif_internal_decode_frame(gif_animation *gif,
        uint32_t *colour_table;
        uint32_t *frame_data = 0; // Set to 0 for no warnings
        uint32_t save_buffer_position;
-       uint32_t return_value = 0;
 
        /* Ensure this frame is supposed to be decoded */
        if (gif->frames[frame].display == false) {
@@ -974,19 +972,19 @@ gif_internal_decode_frame(gif_animation *gif,
        gif->buffer_position = gif_data - gif->gif_data;
 
        /* Skip any extensions because they have already been processed */
-       return_value = gif__parse_frame_extensions(gif, &gif->frames[frame], 
false);
-       if (return_value != GIF_OK) {
+       ret = gif__parse_frame_extensions(gif, &gif->frames[frame], false);
+       if (ret != GIF_OK) {
                goto gif_decode_frame_exit;
        }
 
-       return_value = gif__parse_image_descriptor(gif, &gif->frames[frame], 
false);
-       if (return_value != GIF_OK) {
-               return return_value;
+       ret = gif__parse_image_descriptor(gif, &gif->frames[frame], false);
+       if (ret != GIF_OK) {
+               goto gif_decode_frame_exit;
        }
 
-       return_value = gif__parse_colour_table(gif, &gif->frames[frame], true);
-       if (return_value != GIF_OK) {
-               return return_value;
+       ret = gif__parse_colour_table(gif, &gif->frames[frame], true);
+       if (ret != GIF_OK) {
+               return ret;
        }
        gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
@@ -1001,33 +999,35 @@ gif_internal_decode_frame(gif_animation *gif,
 
        /* Ensure sufficient data remains */
        if (gif_bytes < 1) {
-               return_value = GIF_INSUFFICIENT_FRAME_DATA;
+               ret = GIF_INSUFFICIENT_FRAME_DATA;
                goto gif_decode_frame_exit;
        }
 
        /* check for an end marker */
        if (gif_data[0] == GIF_TRAILER) {
-               return_value = GIF_OK;
+               ret = GIF_OK;
                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;
+               ret = GIF_INSUFFICIENT_MEMORY;
+               goto gif_decode_frame_exit;
        }
 
        /* Get the frame data */
        assert(gif->bitmap_callbacks.bitmap_get_buffer);
        frame_data = (void 
*)gif->bitmap_callbacks.bitmap_get_buffer(gif->frame_image);
        if (!frame_data) {
-               return GIF_INSUFFICIENT_MEMORY;
+               ret = GIF_INSUFFICIENT_MEMORY;
+               goto gif_decode_frame_exit;
        }
 
        /* Ensure we have enough data for a 1-byte LZW code size +
         * 1-byte gif trailer
         */
        if (gif_bytes < 2) {
-               return_value = GIF_INSUFFICIENT_FRAME_DATA;
+               ret = GIF_INSUFFICIENT_FRAME_DATA;
                goto gif_decode_frame_exit;
        }
 
@@ -1035,7 +1035,7 @@ gif_internal_decode_frame(gif_animation *gif,
         * we're finished
         */
        if ((gif_bytes == 2) && (gif_data[1] == GIF_TRAILER)) {
-               return_value = GIF_OK;
+               ret = GIF_OK;
                goto gif_decode_frame_exit;
        }
 
@@ -1054,8 +1054,8 @@ gif_internal_decode_frame(gif_animation *gif,
                /* memset((char*)frame_data, 
colour_table[gif->background_index], gif->width * gif->height * sizeof(int)); */
        } else if ((frame != 0) &&
                   (gif->frames[frame - 1].disposal_method == GIF_FRAME_CLEAR)) 
{
-               return_value = gif_clear_frame(gif, &gif->frames[frame - 1], 
frame_data);
-               if (return_value != GIF_OK) {
+               ret = gif_clear_frame(gif, &gif->frames[frame - 1], frame_data);
+               if (ret != GIF_OK) {
                        goto gif_decode_frame_exit;
                }
 
@@ -1065,8 +1065,8 @@ gif_internal_decode_frame(gif_animation *gif,
                 * If the previous frame's disposal method requires we
                 * restore the previous image, restore our saved image.
                 */
-               err = gif__recover_previous_frame(gif);
-               if (err != GIF_OK) {
+               ret = gif__recover_previous_frame(gif);
+               if (ret != GIF_OK) {
                        /* see notes above on transparency
                         * vs. background color
                         */
@@ -1084,7 +1084,7 @@ gif_internal_decode_frame(gif_animation *gif,
        gif->decoded_frame = frame;
        gif->buffer_position = (gif_data - gif->gif_data) + 1;
 
-       return_value = gif__decode(gif, frame, width, height,
+       ret = gif__decode(gif, frame, width, height,
                        offset_x, offset_y, interlace, gif_data[0],
                        frame_data, colour_table);
 
@@ -1111,7 +1111,7 @@ gif_decode_frame_exit:
        /* Restore the buffer position */
        gif->buffer_position = save_buffer_position;
 
-       return return_value;
+       return ret;
 }
 
 
@@ -1130,7 +1130,7 @@ gif_result gif_initialise(gif_animation *gif, size_t 
size, unsigned char *data)
 {
        uint8_t *gif_data;
        uint32_t index;
-       gif_result return_value;
+       gif_result ret;
 
        /* Initialize values */
        gif->buffer_size = size;
@@ -1310,24 +1310,23 @@ gif_result gif_initialise(gif_animation *gif, size_t 
size, unsigned char *data)
        }
 
        /* Repeatedly try to initialise frames */
-       while ((return_value = gif_initialise_frame(gif)) == GIF_WORKING);
+       while ((ret = gif_initialise_frame(gif)) == GIF_WORKING);
 
        /* If there was a memory error tell the caller */
-       if ((return_value == GIF_INSUFFICIENT_MEMORY) ||
-           (return_value == GIF_DATA_ERROR)) {
-               return return_value;
+       if ((ret == GIF_INSUFFICIENT_MEMORY) ||
+           (ret == GIF_DATA_ERROR)) {
+               return ret;
        }
 
        /* If we didn't have some frames then a GIF_INSUFFICIENT_DATA becomes a
         * GIF_INSUFFICIENT_FRAME_DATA
         */
-       if ((return_value == GIF_INSUFFICIENT_DATA) &&
-           (gif->frame_count_partial > 0)) {
+       if (ret == GIF_INSUFFICIENT_DATA && gif->frame_count_partial > 0) {
                return GIF_INSUFFICIENT_FRAME_DATA;
        }
 
        /* Return how many we got */
-       return return_value;
+       return ret;
 }
 
 


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=eb855e5e40417b0c3c54c937df7b35940288fd00
commit eb855e5e40417b0c3c54c937df7b35940288fd00
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Clear: Don't request bitmap again.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 4739b18..daf4628 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -836,19 +836,20 @@ gif__decode(gif_animation *gif,
 /**
  * Clear a gif frame.
  *
- * \param[in] gif    The gif object we're decoding.
- * \param[in] frame  The frame to clear.
+ * \param[in] gif     The gif object we're decoding.
+ * \param[in] frame   The frame to clear.
+ * \param[in] bitmap  The bitmap to clear the frame in.
  * \return GIF_OK on success, appropriate error otherwise.
  */
 static gif_result gif_clear_frame(
                struct gif_animation *gif,
-               struct gif_frame *frame)
+               struct gif_frame *frame,
+               uint32_t *bitmap)
 {
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t width, height, offset_x, offset_y;
        uint32_t *colour_table;
-       uint32_t *frame_data = 0; // Set to 0 for no warnings
        uint32_t save_buffer_position;
        uint32_t return_value = 0;
 
@@ -905,17 +906,10 @@ static gif_result gif_clear_frame(
                goto gif_decode_frame_exit;
        }
 
-       /* Get the frame data */
-       assert(gif->bitmap_callbacks.bitmap_get_buffer);
-       frame_data = (void 
*)gif->bitmap_callbacks.bitmap_get_buffer(gif->frame_image);
-       if (!frame_data) {
-               return GIF_INSUFFICIENT_MEMORY;
-       }
-
        /* Clear our frame */
        for (uint32_t y = 0; y < height; y++) {
                uint32_t *frame_scanline;
-               frame_scanline = frame_data + offset_x + ((offset_y + y) * 
gif->width);
+               frame_scanline = bitmap + offset_x + ((offset_y + y) * 
gif->width);
                if (frame->transparency) {
                        memset(frame_scanline,
                               GIF_TRANSPARENT_COLOUR,
@@ -1060,7 +1054,7 @@ gif_internal_decode_frame(gif_animation *gif,
                /* memset((char*)frame_data, 
colour_table[gif->background_index], gif->width * gif->height * sizeof(int)); */
        } else if ((frame != 0) &&
                   (gif->frames[frame - 1].disposal_method == GIF_FRAME_CLEAR)) 
{
-               return_value = gif_clear_frame(gif, &gif->frames[frame - 1]);
+               return_value = gif_clear_frame(gif, &gif->frames[frame - 1], 
frame_data);
                if (return_value != GIF_OK) {
                        goto gif_decode_frame_exit;
                }


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=496870618e9977cfcac4b0433bf17b6e8e4d2434
commit 496870618e9977cfcac4b0433bf17b6e8e4d2434
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Clear: Pass frame structure instead of index.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index a12e128..4739b18 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -834,13 +834,15 @@ gif__decode(gif_animation *gif,
 }
 
 /**
- * decode a gif frame
+ * Clear a gif frame.
  *
- * \param gif gif animation context.
- * \param frame The frame number to decode.
+ * \param[in] gif    The gif object we're decoding.
+ * \param[in] frame  The frame to clear.
+ * \return GIF_OK on success, appropriate error otherwise.
  */
-static gif_result
-gif_clear_frame(gif_animation *gif, uint32_t frame)
+static gif_result gif_clear_frame(
+               struct gif_animation *gif,
+               struct gif_frame *frame)
 {
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
@@ -850,20 +852,15 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
        uint32_t save_buffer_position;
        uint32_t return_value = 0;
 
-       assert(gif->frames[frame].disposal_method == GIF_FRAME_CLEAR);
+       assert(frame->disposal_method == GIF_FRAME_CLEAR);
 
        /* Ensure this frame is supposed to be decoded */
-       if (gif->frames[frame].display == false) {
+       if (frame->display == false) {
                return GIF_OK;
        }
 
-       /* Ensure the frame is in range to decode */
-       if (frame > gif->frame_count_partial) {
-               return GIF_INSUFFICIENT_DATA;
-       }
-
        /* Get the start of our frame data and the end of the GIF data */
-       gif_data = gif->gif_data + gif->frames[frame].frame_pointer;
+       gif_data = gif->gif_data + frame->frame_pointer;
        gif_end = gif->gif_data + gif->buffer_size;
        gif_bytes = (gif_end - gif_data);
 
@@ -872,27 +869,27 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
        gif->buffer_position = gif_data - gif->gif_data;
 
        /* Skip any extensions because they have already been processed */
-       return_value = gif__parse_frame_extensions(gif, &gif->frames[frame], 
false);
+       return_value = gif__parse_frame_extensions(gif, frame, false);
        if (return_value != GIF_OK) {
                goto gif_decode_frame_exit;
        }
 
-       return_value = gif__parse_image_descriptor(gif, &gif->frames[frame], 
false);
+       return_value = gif__parse_image_descriptor(gif, frame, false);
        if (return_value != GIF_OK) {
                return return_value;
        }
 
-       return_value = gif__parse_colour_table(gif, &gif->frames[frame], true);
+       return_value = gif__parse_colour_table(gif, frame, true);
        if (return_value != GIF_OK) {
                return return_value;
        }
        gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
 
-       offset_x = gif->frames[frame].redraw_x;
-       offset_y = gif->frames[frame].redraw_y;
-       width = gif->frames[frame].redraw_width;
-       height = gif->frames[frame].redraw_height;
+       offset_x = frame->redraw_x;
+       offset_y = frame->redraw_y;
+       width = frame->redraw_width;
+       height = frame->redraw_height;
 
        colour_table = gif->colour_table;
 
@@ -919,7 +916,7 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
        for (uint32_t y = 0; y < height; y++) {
                uint32_t *frame_scanline;
                frame_scanline = frame_data + offset_x + ((offset_y + y) * 
gif->width);
-               if (gif->frames[frame].transparency) {
+               if (frame->transparency) {
                        memset(frame_scanline,
                               GIF_TRANSPARENT_COLOUR,
                               width * 4);
@@ -1063,7 +1060,7 @@ gif_internal_decode_frame(gif_animation *gif,
                /* memset((char*)frame_data, 
colour_table[gif->background_index], gif->width * gif->height * sizeof(int)); */
        } else if ((frame != 0) &&
                   (gif->frames[frame - 1].disposal_method == GIF_FRAME_CLEAR)) 
{
-               return_value = gif_clear_frame(gif, frame - 1);
+               return_value = gif_clear_frame(gif, &gif->frames[frame - 1]);
                if (return_value != GIF_OK) {
                        goto gif_decode_frame_exit;
                }


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=8b30f0709564df422c549cccc1a7868588c30a67
commit 8b30f0709564df422c549cccc1a7868588c30a67
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Clear: Remove redundant disposal method check.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index f68c15d..a12e128 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -850,6 +850,8 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
        uint32_t save_buffer_position;
        uint32_t return_value = 0;
 
+       assert(gif->frames[frame].disposal_method == GIF_FRAME_CLEAR);
+
        /* Ensure this frame is supposed to be decoded */
        if (gif->frames[frame].display == false) {
                return GIF_OK;
@@ -914,22 +916,20 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
        }
 
        /* Clear our frame */
-       if (gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) {
-               uint32_t y;
-               for (y = 0; y < height; y++) {
-                       uint32_t *frame_scanline;
-                       frame_scanline = frame_data + offset_x + ((offset_y + 
y) * gif->width);
-                       if (gif->frames[frame].transparency) {
-                               memset(frame_scanline,
-                                      GIF_TRANSPARENT_COLOUR,
-                                      width * 4);
-                       } else {
-                               memset(frame_scanline,
-                                      colour_table[gif->background_index],
-                                      width * 4);
-                       }
+       for (uint32_t y = 0; y < height; y++) {
+               uint32_t *frame_scanline;
+               frame_scanline = frame_data + offset_x + ((offset_y + y) * 
gif->width);
+               if (gif->frames[frame].transparency) {
+                       memset(frame_scanline,
+                              GIF_TRANSPARENT_COLOUR,
+                              width * 4);
+               } else {
+                       memset(frame_scanline,
+                              colour_table[gif->background_index],
+                              width * 4);
                }
        }
+
 gif_decode_frame_exit:
        /* Restore the buffer position */
        gif->buffer_position = save_buffer_position;


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=eb0aa2326fd1da0bf4c74d083f889eec1632e1dd
commit eb0aa2326fd1da0bf4c74d083f889eec1632e1dd
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Remove special case for trailer after extension block.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 5f68bcf..f68c15d 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -498,14 +498,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        if (return_value != GIF_OK) {
                return return_value;
        }
-       gif_data = (gif->gif_data + gif->buffer_position);
-       gif_bytes = (gif_end - gif_data);
-
-       if (gif_data[0] == GIF_TRAILER) {
-               gif->buffer_position = (gif_data - gif->gif_data);
-               gif->frame_count = frame + 1;
-               return GIF_OK;
-       }
 
        return_value = gif__parse_image_descriptor(gif, &gif->frames[frame], 
true);
        if (return_value != GIF_OK) {


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=811922e7a5c7de1a83a016ce76d0ea009b26d9fa
commit 811922e7a5c7de1a83a016ce76d0ea009b26d9fa
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Postpone initialisation of sprite until required.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 3870b15..5f68bcf 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -996,14 +996,6 @@ 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 */
-
        return_value = gif__parse_image_descriptor(gif, &gif->frames[frame], 
false);
        if (return_value != GIF_OK) {
                return return_value;
@@ -1036,6 +1028,11 @@ 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;
+       }
+
        /* Get the frame data */
        assert(gif->bitmap_callbacks.bitmap_get_buffer);
        frame_data = (void 
*)gif->bitmap_callbacks.bitmap_get_buffer(gif->frame_image);


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=e1c7bbf7fa9e762ac406310c62c3e30cde40f998
commit e1c7bbf7fa9e762ac406310c62c3e30cde40f998
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Don't need to initialise sprite when clearing.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index c5eca6e..3870b15 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -883,12 +883,6 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
                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;
-       }
-
        return_value = gif__parse_image_descriptor(gif, &gif->frames[frame], 
false);
        if (return_value != GIF_OK) {
                return return_value;


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=d78b6d12479e2567da7e078d52d9bc8fd0ad587c
commit d78b6d12479e2567da7e078d52d9bc8fd0ad587c
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Rewrite extension parsing and skipping.
    
    New code is shared between initialisation and decoding.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 53a3484..c5eca6e 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -95,109 +95,165 @@ gif_initialise_sprite(gif_animation *gif,
        return GIF_OK;
 }
 
+/**
+ * Parse the application extension
+ *
+ * \param[in] frame  The gif object we're decoding.
+ * \param[in] data   The data to decode.
+ * \param[in] len    Byte length of data.
+ * \return GIF_INSUFFICIENT_FRAME_DATA if more data is needed,
+ *         GIF_OK for success.
+ */
+static gif_result gif__parse_extension_graphic_control(
+               struct gif_frame *frame,
+               uint8_t *data,
+               size_t len)
+{
+       /* 6-byte Graphic Control Extension is:
+        *
+        *  +0  CHAR    Graphic Control Label
+        *  +1  CHAR    Block Size
+        *  +2  CHAR    __Packed Fields__
+        *              3BITS   Reserved
+        *              3BITS   Disposal Method
+        *              1BIT    User Input Flag
+        *              1BIT    Transparent Color Flag
+        *  +3  SHORT   Delay Time
+        *  +5  CHAR    Transparent Color Index
+        */
+       if (len < 6) {
+               return GIF_INSUFFICIENT_FRAME_DATA;
+       }
+
+       frame->frame_delay = data[3] | (data[4] << 8);
+       if (data[2] & GIF_TRANSPARENCY_MASK) {
+               frame->transparency = true;
+               frame->transparency_index = data[5];
+       }
+
+       frame->disposal_method = ((data[2] & GIF_DISPOSAL_MASK) >> 2);
+       /* I have encountered documentation and GIFs in the
+        * wild that use 0x04 to restore the previous frame,
+        * rather than the officially documented 0x03.  I
+        * believe some (older?)  software may even actually
+        * export this way.  We handle this as a type of
+        * "quirks" mode. */
+       if (frame->disposal_method == GIF_FRAME_QUIRKS_RESTORE) {
+               frame->disposal_method = GIF_FRAME_RESTORE;
+       }
+
+       /* if we are clearing the background then we need to
+        * redraw enough to cover the previous frame too. */
+       frame->redraw_required =
+                       frame->disposal_method == GIF_FRAME_CLEAR ||
+                       frame->disposal_method == GIF_FRAME_RESTORE;
+
+       return GIF_OK;
+}
 
 /**
- * Attempts to initialise the frame's extensions
+ * Parse the application extension
  *
- * \param gif The animation context
- * \param frame The frame number
- * @return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the
- *         frame GIF_OK for successful initialisation.
+ * \param[in] gif   The gif object we're decoding.
+ * \param[in] data  The data to decode.
+ * \param[in] len   Byte length of data.
+ * \return GIF_INSUFFICIENT_FRAME_DATA if more data is needed,
+ *         GIF_OK for success.
  */
-static gif_result
-gif_initialise_frame_extensions(
+static gif_result gif__parse_extension_application(
                struct gif_animation *gif,
-               struct gif_frame *frame)
+               uint8_t *data,
+               size_t len)
+{
+       /* 14-byte+ Application Extension is:
+        *
+        *  +0    CHAR    Application Extension Label
+        *  +1    CHAR    Block Size
+        *  +2    8CHARS  Application Identifier
+        *  +10   3CHARS  Appl. Authentication Code
+        *  +13   1-256   Application Data (Data sub-blocks)
+        */
+       if (len < 17) {
+               return GIF_INSUFFICIENT_FRAME_DATA;
+       }
+
+       if ((data[1] == 0x0b) &&
+           (strncmp((const char *)data + 2, "NETSCAPE2.0", 11) == 0) &&
+           (data[13] == 0x03) && (data[14] == 0x01)) {
+               gif->loop_count = data[15] | (data[16] << 8);
+       }
+
+       return GIF_OK;
+}
+
+/**
+ * Parse the frame's extensions
+ *
+ * \param[in] gif     The gif object we're decoding.
+ * \param[in] frame   The frame to parse extensions for.
+ * \param[in] decode  Whether to decode or skip over the extension.
+ * \return GIF_INSUFFICIENT_FRAME_DATA if more data is needed,
+ *         GIF_OK for success.
+ */
+static gif_result gif__parse_frame_extensions(
+               struct gif_animation *gif,
+               struct gif_frame *frame,
+               bool decode)
 {
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
 
        /* Get our buffer position etc. */
-       gif_data = (uint8_t *)(gif->gif_data + gif->buffer_position);
-       gif_end = (uint8_t *)(gif->gif_data + gif->buffer_size);
+       gif_data = gif->gif_data + gif->buffer_position;
+       gif_end = gif->gif_data + gif->buffer_size;
+       gif_bytes = gif_end - gif_data;
 
        /* Initialise the extensions */
-       while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) {
-               ++gif_data;
-               if ((gif_bytes = (gif_end - gif_data)) < 1) {
+       while (gif_bytes > 0 && gif_data[0] == GIF_EXTENSION_INTRODUCER) {
+               bool block_step = true;
+               gif_result ret;
+
+               gif_data++;
+               gif_bytes--;
+
+               if (gif_bytes == 0) {
                        return GIF_INSUFFICIENT_FRAME_DATA;
                }
 
                /* Switch on extension label */
                switch (gif_data[0]) {
                case GIF_EXTENSION_GRAPHIC_CONTROL:
-                       /* 6-byte Graphic Control Extension is:
-                        *
-                        *  +0  CHAR    Graphic Control Label
-                        *  +1  CHAR    Block Size
-                        *  +2  CHAR    __Packed Fields__
-                        *              3BITS   Reserved
-                        *              3BITS   Disposal Method
-                        *              1BIT    User Input Flag
-                        *              1BIT    Transparent Color Flag
-                        *  +3  SHORT   Delay Time
-                        *  +5  CHAR    Transparent Color Index
-                        */
-                       if (gif_bytes < 6) {
-                               return GIF_INSUFFICIENT_FRAME_DATA;
-                       }
-
-                       frame->frame_delay = gif_data[3] | (gif_data[4] << 8);
-                       if (gif_data[2] & GIF_TRANSPARENCY_MASK) {
-                               frame->transparency = true;
-                               frame->transparency_index = gif_data[5];
-                       }
-                       frame->disposal_method = ((gif_data[2] & 
GIF_DISPOSAL_MASK) >> 2);
-                       /* I have encountered documentation and GIFs in the
-                        * wild that use 0x04 to restore the previous frame,
-                        * rather than the officially documented 0x03.  I
-                        * believe some (older?)  software may even actually
-                        * export this way.  We handle this as a type of
-                        * "quirks" mode.
-                        */
-                       if (frame->disposal_method == GIF_FRAME_QUIRKS_RESTORE) 
{
-                               frame->disposal_method = GIF_FRAME_RESTORE;
+                       if (decode) {
+                               ret = gif__parse_extension_graphic_control(
+                                               frame, gif_data, gif_bytes);
+                               if (ret != GIF_OK) {
+                                       return ret;
+                               }
                        }
-
-                       /* if we are clearing the background then we need to
-                        * redraw enough to cover the previous frame too
-                        */
-                       frame->redraw_required =
-                               ((frame->disposal_method == GIF_FRAME_CLEAR) ||
-                                (frame->disposal_method == GIF_FRAME_RESTORE));
-                       gif_data += (2 + gif_data[1]);
                        break;
 
                case GIF_EXTENSION_APPLICATION:
-                       /* 14-byte+ Application Extension is:
-                        *
-                        *  +0    CHAR    Application Extension Label
-                        *  +1    CHAR    Block Size
-                        *  +2    8CHARS  Application Identifier
-                        *  +10   3CHARS  Appl. Authentication Code
-                        *  +13   1-256   Application Data (Data sub-blocks)
-                        */
-                       if (gif_bytes < 17) {
-                               return GIF_INSUFFICIENT_FRAME_DATA;
-                       }
-                       if ((gif_data[1] == 0x0b) &&
-                           (strncmp((const char *) gif_data + 2,
-                                    "NETSCAPE2.0", 11) == 0) &&
-                           (gif_data[13] == 0x03) &&
-                           (gif_data[14] == 0x01)) {
-                               gif->loop_count = gif_data[15] | (gif_data[16] 
<< 8);
+                       if (decode) {
+                               ret = gif__parse_extension_application(
+                                               gif, gif_data, gif_bytes);
+                               if (ret != GIF_OK) {
+                                       return ret;
+                               }
                        }
-                       gif_data += (2 + gif_data[1]);
                        break;
 
                case GIF_EXTENSION_COMMENT:
                        /* Move the pointer to the first data sub-block Skip 1
-                        * byte for the extension label
-                        */
+                        * byte for the extension label. */
                        ++gif_data;
+                       block_step = false;
                        break;
 
                default:
+                       break;
+               }
+
+               if (block_step) {
                        /* Move the pointer to the first data sub-block Skip 2
                         * bytes for the extension label and size fields Skip
                         * the extension size itself
@@ -205,25 +261,27 @@ gif_initialise_frame_extensions(
                        if (gif_bytes < 2) {
                                return GIF_INSUFFICIENT_FRAME_DATA;
                        }
-                       gif_data += (2 + gif_data[1]);
+                       gif_data += 2 + gif_data[1];
                }
 
                /* Repeatedly skip blocks until we get a zero block or run out
-                * of data This data is ignored by this gif decoder
-                */
-               gif_bytes = (gif_end - gif_data);
+                * of data.  This data is ignored by this gif decoder. */
                while (gif_data < gif_end && gif_data[0] != 
GIF_BLOCK_TERMINATOR) {
-                       uint32_t block_size = gif_data[0] + 1;
-                       if ((gif_bytes -= block_size) < 0) {
+                       gif_data += gif_data[0] + 1;
+                       if (gif_data >= gif_end) {
                                return GIF_INSUFFICIENT_FRAME_DATA;
                        }
-                       gif_data += block_size;
                }
-               ++gif_data;
+               gif_data++;
+               gif_bytes = gif_end - gif_data;
+       }
+
+       if (gif_data > gif_end) {
+               gif_data = gif_end;
        }
 
        /* Set buffer position and return */
-       gif->buffer_position = (gif_data - gif->gif_data);
+       gif->buffer_position = gif_data - gif->gif_data;
        return GIF_OK;
 }
 
@@ -436,7 +494,7 @@ static gif_result gif_initialise_frame(gif_animation *gif)
 
        /* Initialise any extensions */
        gif->buffer_position = gif_data - gif->gif_data;
-       return_value = gif_initialise_frame_extensions(gif, 
&gif->frames[frame]);
+       return_value = gif__parse_frame_extensions(gif, &gif->frames[frame], 
true);
        if (return_value != GIF_OK) {
                return return_value;
        }
@@ -521,68 +579,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        return GIF_WORKING;
 }
 
-
-/**
- * Skips the frame's extensions (which have been previously initialised)
- *
- * \param gif The animation context
- * \return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the
- *         frame GIF_OK for successful decoding
- */
-static gif_result gif_skip_frame_extensions(gif_animation *gif)
-{
-       uint8_t *gif_data, *gif_end;
-
-       /* Get our buffer position etc. */
-       gif_data = (uint8_t *)(gif->gif_data + gif->buffer_position);
-       gif_end = (uint8_t *)(gif->gif_data + gif->buffer_size);
-
-       /* Skip the extensions */
-       while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) {
-               ++gif_data;
-               if (gif_data >= gif_end) {
-                       return GIF_INSUFFICIENT_FRAME_DATA;
-               }
-
-               /* Switch on extension label */
-               switch(gif_data[0]) {
-               case GIF_EXTENSION_COMMENT:
-                       /* Move the pointer to the first data sub-block
-                        * 1 byte for the extension label
-                        */
-                       ++gif_data;
-                       break;
-
-               default:
-                       /* Move the pointer to the first data sub-block 2 bytes
-                        * for the extension label and size fields Skip the
-                        * extension size itself
-                        */
-                       if (gif_data + 1 >= gif_end) {
-                               return GIF_INSUFFICIENT_FRAME_DATA;
-                       }
-                       gif_data += (2 + gif_data[1]);
-               }
-
-               /* Repeatedly skip blocks until we get a zero block or run out
-                * of data This data is ignored by this gif decoder
-                */
-               while (gif_data < gif_end && gif_data[0] != 
GIF_BLOCK_TERMINATOR) {
-                       uint32_t block_size = gif_data[0] + 1;
-
-                       gif_data += block_size;
-                       if (gif_data >= gif_end) {
-                               return GIF_INSUFFICIENT_FRAME_DATA;
-                       }
-               }
-               ++gif_data;
-       }
-
-       /* Set buffer position and return */
-       gif->buffer_position = (gif_data - gif->gif_data);
-       return GIF_OK;
-}
-
 static uint32_t gif_interlaced_line(int height, int y)
 {
        if ((y << 3) < height) {
@@ -882,11 +878,10 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
        gif->buffer_position = gif_data - gif->gif_data;
 
        /* Skip any extensions because they have already been processed */
-       if ((return_value = gif_skip_frame_extensions(gif)) != GIF_OK) {
+       return_value = gif__parse_frame_extensions(gif, &gif->frames[frame], 
false);
+       if (return_value != GIF_OK) {
                goto gif_decode_frame_exit;
        }
-       gif_data = (gif->gif_data + gif->buffer_position);
-       gif_bytes = (gif_end - gif_data);
 
        /* Make sure we have a buffer to decode to.
         */
@@ -1002,11 +997,10 @@ gif_internal_decode_frame(gif_animation *gif,
        gif->buffer_position = gif_data - gif->gif_data;
 
        /* Skip any extensions because they have already been processed */
-       if ((return_value = gif_skip_frame_extensions(gif)) != GIF_OK) {
+       return_value = gif__parse_frame_extensions(gif, &gif->frames[frame], 
false);
+       if (return_value != GIF_OK) {
                goto gif_decode_frame_exit;
        }
-       gif_data = (gif->gif_data + gif->buffer_position);
-       gif_bytes = (gif_end - gif_data);
 
        /* Make sure we have a buffer to decode to.
         */


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=838a69e759309db257c2ece5102ad732590847db
commit 838a69e759309db257c2ece5102ad732590847db
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Minor style change to brace position.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 8c524cc..53a3484 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -583,7 +583,8 @@ static gif_result gif_skip_frame_extensions(gif_animation 
*gif)
        return GIF_OK;
 }
 
-static uint32_t gif_interlaced_line(int height, int y) {
+static uint32_t gif_interlaced_line(int height, int y)
+{
        if ((y << 3) < height) {
                return (y << 3);
        }


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=bca8f74754f2316f40374368edad191a6803a1aa
commit bca8f74754f2316f40374368edad191a6803a1aa
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Remove redundant buffer check.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index a71d4db..8c524cc 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -996,14 +996,6 @@ gif_internal_decode_frame(gif_animation *gif,
        gif_end = gif->gif_data + gif->buffer_size;
        gif_bytes = (gif_end - gif_data);
 
-       /*
-        * Ensure there is a minimal amount of data to proceed.  The shortest
-        * block of data is a 10-byte image descriptor + 1-byte gif trailer
-        */
-       if (gif_bytes < 12) {
-               return GIF_INSUFFICIENT_FRAME_DATA;
-       }
-
        /* Save the buffer position */
        save_buffer_position = gif->buffer_position;
        gif->buffer_position = gif_data - gif->gif_data;
@@ -1015,14 +1007,6 @@ gif_internal_decode_frame(gif_animation *gif,
        gif_data = (gif->gif_data + gif->buffer_position);
        gif_bytes = (gif_end - gif_data);
 
-       /* Ensure we have enough data for the 10-byte image descriptor + 1-byte
-        * gif trailer
-        */
-       if (gif_bytes < 12) {
-               return_value = GIF_INSUFFICIENT_FRAME_DATA;
-               goto gif_decode_frame_exit;
-       }
-
        /* Make sure we have a buffer to decode to.
         */
        if (gif_initialise_sprite(gif, gif->width, gif->height)) {


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=6661c46dc8f836052785ef5db1d363b4a0bfcf25
commit 6661c46dc8f836052785ef5db1d363b4a0bfcf25
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Remove redundant buffer check.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 4da811b..a71d4db 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -876,14 +876,6 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
        gif_end = gif->gif_data + gif->buffer_size;
        gif_bytes = (gif_end - gif_data);
 
-       /*
-        * Ensure there is a minimal amount of data to proceed.  The shortest
-        * block of data is a 10-byte image descriptor + 1-byte gif trailer
-        */
-       if (gif_bytes < 12) {
-               return GIF_INSUFFICIENT_FRAME_DATA;
-       }
-
        /* Save the buffer position */
        save_buffer_position = gif->buffer_position;
        gif->buffer_position = gif_data - gif->gif_data;


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=b6d35c01d3955c4c247c710187f14c1ca2e4cd94
commit b6d35c01d3955c4c247c710187f14c1ca2e4cd94
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Pass frame into extension parser.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index bf1e87a..4da811b 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -105,7 +105,9 @@ gif_initialise_sprite(gif_animation *gif,
  *         frame GIF_OK for successful initialisation.
  */
 static gif_result
-gif_initialise_frame_extensions(gif_animation *gif, const int frame)
+gif_initialise_frame_extensions(
+               struct gif_animation *gif,
+               struct gif_frame *frame)
 {
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
@@ -140,12 +142,12 @@ gif_initialise_frame_extensions(gif_animation *gif, const 
int frame)
                                return GIF_INSUFFICIENT_FRAME_DATA;
                        }
 
-                       gif->frames[frame].frame_delay = gif_data[3] | 
(gif_data[4] << 8);
+                       frame->frame_delay = gif_data[3] | (gif_data[4] << 8);
                        if (gif_data[2] & GIF_TRANSPARENCY_MASK) {
-                               gif->frames[frame].transparency = true;
-                               gif->frames[frame].transparency_index = 
gif_data[5];
+                               frame->transparency = true;
+                               frame->transparency_index = gif_data[5];
                        }
-                       gif->frames[frame].disposal_method = ((gif_data[2] & 
GIF_DISPOSAL_MASK) >> 2);
+                       frame->disposal_method = ((gif_data[2] & 
GIF_DISPOSAL_MASK) >> 2);
                        /* I have encountered documentation and GIFs in the
                         * wild that use 0x04 to restore the previous frame,
                         * rather than the officially documented 0x03.  I
@@ -153,16 +155,16 @@ gif_initialise_frame_extensions(gif_animation *gif, const 
int frame)
                         * export this way.  We handle this as a type of
                         * "quirks" mode.
                         */
-                       if (gif->frames[frame].disposal_method == 
GIF_FRAME_QUIRKS_RESTORE) {
-                               gif->frames[frame].disposal_method = 
GIF_FRAME_RESTORE;
+                       if (frame->disposal_method == GIF_FRAME_QUIRKS_RESTORE) 
{
+                               frame->disposal_method = GIF_FRAME_RESTORE;
                        }
 
                        /* if we are clearing the background then we need to
                         * redraw enough to cover the previous frame too
                         */
-                       gif->frames[frame].redraw_required =
-                               ((gif->frames[frame].disposal_method == 
GIF_FRAME_CLEAR) ||
-                                (gif->frames[frame].disposal_method == 
GIF_FRAME_RESTORE));
+                       frame->redraw_required =
+                               ((frame->disposal_method == GIF_FRAME_CLEAR) ||
+                                (frame->disposal_method == GIF_FRAME_RESTORE));
                        gif_data += (2 + gif_data[1]);
                        break;
 
@@ -434,7 +436,7 @@ static gif_result gif_initialise_frame(gif_animation *gif)
 
        /* Initialise any extensions */
        gif->buffer_position = gif_data - gif->gif_data;
-       return_value = gif_initialise_frame_extensions(gif, frame);
+       return_value = gif_initialise_frame_extensions(gif, 
&gif->frames[frame]);
        if (return_value != GIF_OK) {
                return return_value;
        }


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=623953b935cc9910e3cb7df178773a6092723913
commit 623953b935cc9910e3cb7df178773a6092723913
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Move image dimension check to image descriptor handler.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index a67e87f..bf1e87a 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -266,15 +266,26 @@ static gif_result gif__parse_image_descriptor(
        }
 
        if (decode) {
+               unsigned x, y, w, h;
+
                if (data[0] != GIF_IMAGE_SEPARATOR) {
                        return GIF_FRAME_DATA_ERROR;
                }
 
-               frame->redraw_x      = data[1] | (data[2] << 8);
-               frame->redraw_y      = data[3] | (data[4] << 8);
-               frame->redraw_width  = data[5] | (data[6] << 8);
-               frame->redraw_height = data[7] | (data[8] << 8);
-               frame->flags         = data[9];
+               x = data[1] | (data[2] << 8);
+               y = data[3] | (data[4] << 8);
+               w = data[5] | (data[6] << 8);
+               h = data[7] | (data[8] << 8);
+               frame->flags = data[9];
+
+               frame->redraw_x      = x;
+               frame->redraw_y      = y;
+               frame->redraw_width  = w;
+               frame->redraw_height = h;
+
+               /* Frame size may have grown. */
+               gif->width  = (x + w > gif->width ) ? x + w : gif->width;
+               gif->height = (y + h > gif->height) ? y + h : gif->height;
        }
 
        gif->buffer_position += GIF_IMAGE_DESCRIPTOR_LEN;
@@ -357,7 +368,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
 
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
-       uint32_t width, height, offset_x, offset_y;
        uint32_t block_size;
        gif_result return_value;
 
@@ -449,18 +459,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
 
-       offset_x = gif->frames[frame].redraw_x;
-       offset_y = gif->frames[frame].redraw_y;
-       width = gif->frames[frame].redraw_width;
-       height = gif->frames[frame].redraw_height;
-
-       /* 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;
-
        /* Move our data onwards and remember we've got a bit of this frame */
        gif->frame_count_partial = frame + 1;
 


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=6a5c2a60d82fa39d1d653ced3c25eb15b3a0007f
commit 6a5c2a60d82fa39d1d653ced3c25eb15b3a0007f
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Move redraw-required check to extension handler.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index c886bf8..a67e87f 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -156,6 +156,13 @@ gif_initialise_frame_extensions(gif_animation *gif, const 
int frame)
                        if (gif->frames[frame].disposal_method == 
GIF_FRAME_QUIRKS_RESTORE) {
                                gif->frames[frame].disposal_method = 
GIF_FRAME_RESTORE;
                        }
+
+                       /* if we are clearing the background then we need to
+                        * redraw enough to cover the previous frame too
+                        */
+                       gif->frames[frame].redraw_required =
+                               ((gif->frames[frame].disposal_method == 
GIF_FRAME_CLEAR) ||
+                                (gif->frames[frame].disposal_method == 
GIF_FRAME_RESTORE));
                        gif_data += (2 + gif_data[1]);
                        break;
 
@@ -447,13 +454,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        width = gif->frames[frame].redraw_width;
        height = gif->frames[frame].redraw_height;
 
-       /* if we are clearing the background then we need to redraw enough to
-        * cover the previous frame too
-        */
-       gif->frames[frame].redraw_required =
-                       ((gif->frames[frame].disposal_method == 
GIF_FRAME_CLEAR) ||
-                        (gif->frames[frame].disposal_method == 
GIF_FRAME_RESTORE));
-
        /* Frame size may have grown.
         */
        gif->width = (offset_x + width > gif->width) ?


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=2aa9bae406866de8dfeea142e4e02c619a20ae23
commit 2aa9bae406866de8dfeea142e4e02c619a20ae23
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Unify decode and skip.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 24c08ed..c886bf8 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -241,7 +241,8 @@ gif_initialise_frame_extensions(gif_animation *gif, const 
int frame)
  */
 static gif_result gif__parse_image_descriptor(
                struct gif_animation *gif,
-               struct gif_frame *frame)
+               struct gif_frame *frame,
+               bool decode)
 {
        const uint8_t *data = gif->gif_data + gif->buffer_position;
        size_t len = gif->buffer_size - gif->buffer_position;
@@ -257,15 +258,17 @@ static gif_result gif__parse_image_descriptor(
                return GIF_INSUFFICIENT_FRAME_DATA;
        }
 
-       if (data[0] != GIF_IMAGE_SEPARATOR) {
-               return GIF_FRAME_DATA_ERROR;
-       }
+       if (decode) {
+               if (data[0] != GIF_IMAGE_SEPARATOR) {
+                       return GIF_FRAME_DATA_ERROR;
+               }
 
-       frame->redraw_x      = data[1] | (data[2] << 8);
-       frame->redraw_y      = data[3] | (data[4] << 8);
-       frame->redraw_width  = data[5] | (data[6] << 8);
-       frame->redraw_height = data[7] | (data[8] << 8);
-       frame->flags         = data[9];
+               frame->redraw_x      = data[1] | (data[2] << 8);
+               frame->redraw_y      = data[3] | (data[4] << 8);
+               frame->redraw_width  = data[5] | (data[6] << 8);
+               frame->redraw_height = data[7] | (data[8] << 8);
+               frame->flags         = data[9];
+       }
 
        gif->buffer_position += GIF_IMAGE_DESCRIPTOR_LEN;
        return GIF_OK;
@@ -282,12 +285,12 @@ static gif_result gif__parse_image_descriptor(
  */
 static gif_result gif__parse_colour_table(
                struct gif_animation *gif,
-               struct gif_frame *frame)
+               struct gif_frame *frame,
+               bool decode)
 {
        const uint8_t *data = gif->gif_data + gif->buffer_position;
        size_t len = gif->buffer_size - gif->buffer_position;
        unsigned colour_table_size;
-       uint8_t *entry;
 
        assert(gif != NULL);
        assert(frame != NULL);
@@ -302,26 +305,28 @@ static gif_result gif__parse_colour_table(
                return GIF_INSUFFICIENT_FRAME_DATA;
        }
 
-       entry = (uint8_t *)gif->local_colour_table;
+       if (decode) {
+               int count = colour_table_size;
+               uint8_t *entry = (uint8_t *)gif->local_colour_table;
 
-       while (colour_table_size--) {
-               /* Gif colour map contents are r,g,b.
-                *
-                * We want to pack them bytewise into the
-                * colour table, such that the red component
-                * is in byte 0 and the alpha component is in
-                * byte 3.
-                */
+               while (count--) {
+                       /* Gif colour map contents are r,g,b.
+                        *
+                        * We want to pack them bytewise into the
+                        * colour table, such that the red component
+                        * is in byte 0 and the alpha component is in
+                        * byte 3.
+                        */
 
-               *entry++ = *data++; /* r */
-               *entry++ = *data++; /* g */
-               *entry++ = *data++; /* b */
-               *entry++ = 0xff;    /* a */
+                       *entry++ = *data++; /* r */
+                       *entry++ = *data++; /* g */
+                       *entry++ = *data++; /* b */
+                       *entry++ = 0xff;    /* a */
+               }
        }
 
+       gif->buffer_position += colour_table_size * 3;
        gif->colour_table = gif->local_colour_table;
-       gif->buffer_position = data - gif->gif_data;
-
        return GIF_OK;
 }
 
@@ -345,7 +350,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
 
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
-       uint32_t flags = 0;
        uint32_t width, height, offset_x, offset_y;
        uint32_t block_size;
        gif_result return_value;
@@ -426,11 +430,15 @@ static gif_result gif_initialise_frame(gif_animation *gif)
                return GIF_OK;
        }
 
-       return_value = gif__parse_image_descriptor(gif, &gif->frames[frame]);
+       return_value = gif__parse_image_descriptor(gif, &gif->frames[frame], 
true);
        if (return_value != GIF_OK) {
                return return_value;
        }
 
+       return_value = gif__parse_colour_table(gif, &gif->frames[frame], false);
+       if (return_value != GIF_OK) {
+               return return_value;
+       }
        gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
 
@@ -438,7 +446,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        offset_y = gif->frames[frame].redraw_y;
        width = gif->frames[frame].redraw_width;
        height = gif->frames[frame].redraw_height;
-       flags = gif->frames[frame].flags;
 
        /* if we are clearing the background then we need to redraw enough to
         * cover the previous frame too
@@ -457,16 +464,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        /* Move our data onwards and remember we've got a bit of this frame */
        gif->frame_count_partial = frame + 1;
 
-       /* Skip the local colour table */
-       if (flags & GIF_COLOUR_TABLE_MASK) {
-               int colour_table_size;
-               colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
-               gif_data += 3 * colour_table_size;
-               if ((gif_bytes = (gif_end - gif_data)) < 0) {
-                       return GIF_INSUFFICIENT_FRAME_DATA;
-               }
-       }
-
        /* Ensure we have a correct code size */
        if (gif_bytes < 1) {
                return GIF_INSUFFICIENT_FRAME_DATA;
@@ -859,7 +856,6 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t width, height, offset_x, offset_y;
-       uint32_t flags;
        uint32_t *colour_table;
        uint32_t *frame_data = 0; // Set to 0 for no warnings
        uint32_t save_buffer_position;
@@ -899,47 +895,30 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
        gif_data = (gif->gif_data + gif->buffer_position);
        gif_bytes = (gif_end - gif_data);
 
-       /* Ensure we have enough data for the 10-byte image descriptor + 1-byte
-        * gif trailer
-        */
-       if (gif_bytes < 12) {
-               return_value = GIF_INSUFFICIENT_FRAME_DATA;
-               goto gif_decode_frame_exit;
-       }
-
-       offset_x = gif->frames[frame].redraw_x;
-       offset_y = gif->frames[frame].redraw_y;
-       width = gif->frames[frame].redraw_width;
-       height = gif->frames[frame].redraw_height;
-       flags = gif->frames[frame].flags;
-
        /* Make sure we have a buffer to decode to.
         */
        if (gif_initialise_sprite(gif, gif->width, gif->height)) {
                return GIF_INSUFFICIENT_MEMORY;
        }
 
-       /* Advance data pointer to next block either colour table or image
-        * data.
-        */
-       gif_data += 10;
+       return_value = gif__parse_image_descriptor(gif, &gif->frames[frame], 
false);
+       if (return_value != GIF_OK) {
+               return return_value;
+       }
+
+       return_value = gif__parse_colour_table(gif, &gif->frames[frame], true);
+       if (return_value != GIF_OK) {
+               return return_value;
+       }
+       gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
 
-       /* Set up the colour table */
-       if (flags & GIF_COLOUR_TABLE_MASK) {
-               int colour_table_size;
-               colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
-               if (gif_bytes < (3 * colour_table_size)) {
-                       return_value = GIF_INSUFFICIENT_FRAME_DATA;
-                       goto gif_decode_frame_exit;
-               }
-               colour_table = gif->local_colour_table;
-               gif_data += 3 * colour_table_size;
+       offset_x = gif->frames[frame].redraw_x;
+       offset_y = gif->frames[frame].redraw_y;
+       width = gif->frames[frame].redraw_width;
+       height = gif->frames[frame].redraw_height;
 
-               gif_bytes = (gif_end - gif_data);
-       } else {
-               colour_table = gif->global_colour_table;
-       }
+       colour_table = gif->colour_table;
 
        /* Ensure sufficient data remains */
        if (gif_bytes < 1) {
@@ -999,7 +978,7 @@ gif_internal_decode_frame(gif_animation *gif,
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t width, height, offset_x, offset_y;
-       uint32_t flags, interlace;
+       uint32_t interlace;
        uint32_t *colour_table;
        uint32_t *frame_data = 0; // Set to 0 for no warnings
        uint32_t save_buffer_position;
@@ -1052,12 +1031,6 @@ gif_internal_decode_frame(gif_animation *gif,
                goto gif_decode_frame_exit;
        }
 
-       offset_x = gif->frames[frame].redraw_x;
-       offset_y = gif->frames[frame].redraw_y;
-       width = gif->frames[frame].redraw_width;
-       height = gif->frames[frame].redraw_height;
-       flags = gif->frames[frame].flags;
-
        /* Make sure we have a buffer to decode to.
         */
        if (gif_initialise_sprite(gif, gif->width, gif->height)) {
@@ -1065,22 +1038,25 @@ gif_internal_decode_frame(gif_animation *gif,
        }
 
        /* Decode the flags */
-       interlace = flags & GIF_INTERLACE_MASK;
 
-       /* Advance data pointer to next block either colour table or image
-        * data.
-        */
-       gif_data += 10;
-       gif_bytes = (gif_end - gif_data);
-       gif->buffer_position = gif_data - gif->gif_data;
+       return_value = gif__parse_image_descriptor(gif, &gif->frames[frame], 
false);
+       if (return_value != GIF_OK) {
+               return return_value;
+       }
 
-       return_value = gif__parse_colour_table(gif, &gif->frames[frame]);
+       return_value = gif__parse_colour_table(gif, &gif->frames[frame], true);
        if (return_value != GIF_OK) {
                return return_value;
        }
        gif_data = gif->gif_data + gif->buffer_position;
        gif_bytes = (gif_end - gif_data);
 
+       offset_x = gif->frames[frame].redraw_x;
+       offset_y = gif->frames[frame].redraw_y;
+       width = gif->frames[frame].redraw_width;
+       height = gif->frames[frame].redraw_height;
+       interlace = gif->frames[frame].flags & GIF_INTERLACE_MASK;
+
        colour_table = gif->colour_table;
 
        /* Ensure sufficient data remains */


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=323d6e3827258c8db1d0e49be9ac154d253efece
commit 323d6e3827258c8db1d0e49be9ac154d253efece
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Abstract colour table decoding.

diff --git a/include/libnsgif.h b/include/libnsgif.h
index f220460..81a67b5 100644
--- a/include/libnsgif.h
+++ b/include/libnsgif.h
@@ -138,6 +138,8 @@ typedef struct gif_animation {
         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;
diff --git a/src/libnsgif.c b/src/libnsgif.c
index 92b700c..24c08ed 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -272,6 +272,60 @@ static gif_result gif__parse_image_descriptor(
 }
 
 /**
+ * Get a frame's 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.
+ * \return GIF_OK on success, appropriate error otherwise.
+ */
+static gif_result gif__parse_colour_table(
+               struct gif_animation *gif,
+               struct gif_frame *frame)
+{
+       const uint8_t *data = gif->gif_data + gif->buffer_position;
+       size_t len = gif->buffer_size - gif->buffer_position;
+       unsigned colour_table_size;
+       uint8_t *entry;
+
+       assert(gif != NULL);
+       assert(frame != NULL);
+
+       if ((frame->flags & GIF_COLOUR_TABLE_MASK) == 0) {
+               gif->colour_table = gif->global_colour_table;
+               return GIF_OK;
+       }
+
+       colour_table_size = 2 << (frame->flags & GIF_COLOUR_TABLE_SIZE_MASK);
+       if (len < colour_table_size * 3) {
+               return GIF_INSUFFICIENT_FRAME_DATA;
+       }
+
+       entry = (uint8_t *)gif->local_colour_table;
+
+       while (colour_table_size--) {
+               /* Gif colour map contents are r,g,b.
+                *
+                * We want to pack them bytewise into the
+                * colour table, such that the red component
+                * is in byte 0 and the alpha component is in
+                * byte 3.
+                */
+
+               *entry++ = *data++; /* r */
+               *entry++ = *data++; /* g */
+               *entry++ = *data++; /* b */
+               *entry++ = 0xff;    /* a */
+       }
+
+       gif->colour_table = gif->local_colour_table;
+       gif->buffer_position = data - gif->gif_data;
+
+       return GIF_OK;
+}
+
+/**
  * Attempts to initialise the next frame
  *
  * \param gif The animation context
@@ -1018,37 +1072,16 @@ gif_internal_decode_frame(gif_animation *gif,
         */
        gif_data += 10;
        gif_bytes = (gif_end - gif_data);
+       gif->buffer_position = gif_data - gif->gif_data;
 
-       /* Set up the colour table */
-       if (flags & GIF_COLOUR_TABLE_MASK) {
-               int colour_table_size;
-               colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
-               if (gif_bytes < (int)(3 * colour_table_size)) {
-                       return_value = GIF_INSUFFICIENT_FRAME_DATA;
-                       goto gif_decode_frame_exit;
-               }
-               colour_table = gif->local_colour_table;
-               for (int index = 0; index < colour_table_size; index++) {
-                       /* Gif colour map contents are r,g,b.
-                        *
-                        * We want to pack them bytewise into the
-                        * colour table, such that the red component
-                        * is in byte 0 and the alpha component is in
-                        * byte 3.
-                        */
-                       uint8_t *entry = (uint8_t *) &colour_table[index];
-
-                       entry[0] = gif_data[0]; /* r */
-                       entry[1] = gif_data[1]; /* g */
-                       entry[2] = gif_data[2]; /* b */
-                       entry[3] = 0xff;        /* a */
-
-                       gif_data += 3;
-               }
-               gif_bytes = (gif_end - gif_data);
-       } else {
-               colour_table = gif->global_colour_table;
+       return_value = gif__parse_colour_table(gif, &gif->frames[frame]);
+       if (return_value != GIF_OK) {
+               return return_value;
        }
+       gif_data = gif->gif_data + gif->buffer_position;
+       gif_bytes = (gif_end - gif_data);
+
+       colour_table = gif->colour_table;
 
        /* Ensure sufficient data remains */
        if (gif_bytes < 1) {


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=cc492166b9988972b87492fb37b92c759de6b4de
commit cc492166b9988972b87492fb37b92c759de6b4de
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Scope reduce colour_table_size veriable.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 11a3344..92b700c 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -293,7 +293,7 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        int gif_bytes;
        uint32_t flags = 0;
        uint32_t width, height, offset_x, offset_y;
-       uint32_t block_size, colour_table_size;
+       uint32_t block_size;
        gif_result return_value;
 
        /* Get the frame to decode and our data position */
@@ -400,14 +400,13 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        gif->height = (offset_y + height > gif->height) ?
                        offset_y + height : gif->height;
 
-       /* Decode the flags */
-       colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
-
        /* Move our data onwards and remember we've got a bit of this frame */
        gif->frame_count_partial = frame + 1;
 
        /* Skip the local colour table */
        if (flags & GIF_COLOUR_TABLE_MASK) {
+               int colour_table_size;
+               colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
                gif_data += 3 * colour_table_size;
                if ((gif_bytes = (gif_end - gif_data)) < 0) {
                        return GIF_INSUFFICIENT_FRAME_DATA;
@@ -806,7 +805,7 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t width, height, offset_x, offset_y;
-       uint32_t flags, colour_table_size;
+       uint32_t flags;
        uint32_t *colour_table;
        uint32_t *frame_data = 0; // Set to 0 for no warnings
        uint32_t save_buffer_position;
@@ -866,9 +865,6 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
                return GIF_INSUFFICIENT_MEMORY;
        }
 
-       /* Decode the flags */
-       colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
-
        /* Advance data pointer to next block either colour table or image
         * data.
         */
@@ -877,7 +873,9 @@ gif_clear_frame(gif_animation *gif, uint32_t frame)
 
        /* Set up the colour table */
        if (flags & GIF_COLOUR_TABLE_MASK) {
-               if (gif_bytes < (int)(3 * colour_table_size)) {
+               int colour_table_size;
+               colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
+               if (gif_bytes < (3 * colour_table_size)) {
                        return_value = GIF_INSUFFICIENT_FRAME_DATA;
                        goto gif_decode_frame_exit;
                }
@@ -944,11 +942,10 @@ gif_internal_decode_frame(gif_animation *gif,
                          uint32_t frame)
 {
        gif_result err;
-       uint32_t index = 0;
        uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t width, height, offset_x, offset_y;
-       uint32_t flags, colour_table_size, interlace;
+       uint32_t flags, interlace;
        uint32_t *colour_table;
        uint32_t *frame_data = 0; // Set to 0 for no warnings
        uint32_t save_buffer_position;
@@ -1014,7 +1011,6 @@ gif_internal_decode_frame(gif_animation *gif,
        }
 
        /* Decode the flags */
-       colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
        interlace = flags & GIF_INTERLACE_MASK;
 
        /* Advance data pointer to next block either colour table or image
@@ -1025,12 +1021,14 @@ gif_internal_decode_frame(gif_animation *gif,
 
        /* Set up the colour table */
        if (flags & GIF_COLOUR_TABLE_MASK) {
+               int colour_table_size;
+               colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
                if (gif_bytes < (int)(3 * colour_table_size)) {
                        return_value = GIF_INSUFFICIENT_FRAME_DATA;
                        goto gif_decode_frame_exit;
                }
                colour_table = gif->local_colour_table;
-               for (index = 0; index < colour_table_size; index++) {
+               for (int index = 0; index < colour_table_size; index++) {
                        /* Gif colour map contents are r,g,b.
                         *
                         * We want to pack them bytewise into the
@@ -1038,8 +1036,7 @@ gif_internal_decode_frame(gif_animation *gif,
                         * is in byte 0 and the alpha component is in
                         * byte 3.
                         */
-                       uint8_t *entry =
-                               (uint8_t *) &colour_table[index];
+                       uint8_t *entry = (uint8_t *) &colour_table[index];
 
                        entry[0] = gif_data[0]; /* r */
                        entry[1] = gif_data[1]; /* g */


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=e60c1f6c8de7e154c12019140f92bd05b8966194
commit e60c1f6c8de7e154c12019140f92bd05b8966194
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Change unsigned char to uint8_t.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 37b728d..11a3344 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -107,12 +107,12 @@ gif_initialise_sprite(gif_animation *gif,
 static gif_result
 gif_initialise_frame_extensions(gif_animation *gif, const int frame)
 {
-       unsigned char *gif_data, *gif_end;
+       uint8_t *gif_data, *gif_end;
        int gif_bytes;
 
        /* Get our buffer position etc. */
-       gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position);
-       gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size);
+       gif_data = (uint8_t *)(gif->gif_data + gif->buffer_position);
+       gif_end = (uint8_t *)(gif->gif_data + gif->buffer_size);
 
        /* Initialise the extensions */
        while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) {
@@ -289,7 +289,7 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        int frame;
        gif_frame *temp_buf;
 
-       unsigned char *gif_data, *gif_end;
+       uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t flags = 0;
        uint32_t width, height, offset_x, offset_y;
@@ -300,8 +300,8 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        frame = gif->frame_count;
 
        /* Get our buffer position etc. */
-       gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position);
-       gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size);
+       gif_data = (uint8_t *)(gif->gif_data + gif->buffer_position);
+       gif_end = (uint8_t *)(gif->gif_data + gif->buffer_size);
        gif_bytes = (gif_end - gif_data);
 
        /* Check if we've finished */
@@ -481,11 +481,11 @@ static gif_result gif_initialise_frame(gif_animation *gif)
  */
 static gif_result gif_skip_frame_extensions(gif_animation *gif)
 {
-       unsigned char *gif_data, *gif_end;
+       uint8_t *gif_data, *gif_end;
 
        /* Get our buffer position etc. */
-       gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position);
-       gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size);
+       gif_data = (uint8_t *)(gif->gif_data + gif->buffer_position);
+       gif_end = (uint8_t *)(gif->gif_data + gif->buffer_size);
 
        /* Skip the extensions */
        while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) {
@@ -803,7 +803,7 @@ gif__decode(gif_animation *gif,
 static gif_result
 gif_clear_frame(gif_animation *gif, uint32_t frame)
 {
-       unsigned char *gif_data, *gif_end;
+       uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t width, height, offset_x, offset_y;
        uint32_t flags, colour_table_size;
@@ -945,7 +945,7 @@ gif_internal_decode_frame(gif_animation *gif,
 {
        gif_result err;
        uint32_t index = 0;
-       unsigned char *gif_data, *gif_end;
+       uint8_t *gif_data, *gif_end;
        int gif_bytes;
        uint32_t width, height, offset_x, offset_y;
        uint32_t flags, colour_table_size, interlace;
@@ -1038,8 +1038,8 @@ gif_internal_decode_frame(gif_animation *gif,
                         * is in byte 0 and the alpha component is in
                         * byte 3.
                         */
-                       unsigned char *entry =
-                               (unsigned char *) &colour_table[index];
+                       uint8_t *entry =
+                               (uint8_t *) &colour_table[index];
 
                        entry[0] = gif_data[0]; /* r */
                        entry[1] = gif_data[1]; /* g */
@@ -1177,7 +1177,7 @@ void gif_create(gif_animation *gif, 
gif_bitmap_callback_vt *bitmap_callbacks)
 /* exported function documented in libnsgif.h */
 gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data)
 {
-       unsigned char *gif_data;
+       uint8_t *gif_data;
        uint32_t index;
        gif_result return_value;
 
@@ -1333,7 +1333,7 @@ gif_result gif_initialise(gif_animation *gif, size_t 
size, unsigned char *data)
                                 * is in byte 0 and the alpha component is in
                                 * byte 3.
                                 */
-                               unsigned char *entry = (unsigned char *) &gif->
+                               uint8_t *entry = (uint8_t *) &gif->
                                                       
global_colour_table[index];
 
                                entry[0] = gif_data[0]; /* r */
@@ -1352,7 +1352,7 @@ gif_result gif_initialise(gif_animation *gif, size_t 
size, unsigned char *data)
 
                        entry[0] = 0x00000000;
                        /* Force Alpha channel to opaque */
-                       ((unsigned char *) entry)[3] = 0xff;
+                       ((uint8_t *) entry)[3] = 0xff;
 
                        entry[1] = 0xffffffff;
                }


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=4e957db96569b680d7db86ac1a072f0805ee512b
commit 4e957db96569b680d7db86ac1a072f0805ee512b
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Change unsigned int to uint32_t.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 054ba9f..37b728d 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -78,8 +78,8 @@
  */
 static gif_result
 gif_initialise_sprite(gif_animation *gif,
-                     unsigned int width,
-                     unsigned int height)
+                     uint32_t width,
+                     uint32_t height)
 {
        /* Already allocated? */
        if (gif->frame_image) {
@@ -204,7 +204,7 @@ gif_initialise_frame_extensions(gif_animation *gif, const 
int frame)
                 */
                gif_bytes = (gif_end - gif_data);
                while (gif_data < gif_end && gif_data[0] != 
GIF_BLOCK_TERMINATOR) {
-                       unsigned int block_size = gif_data[0] + 1;
+                       uint32_t block_size = gif_data[0] + 1;
                        if ((gif_bytes -= block_size) < 0) {
                                return GIF_INSUFFICIENT_FRAME_DATA;
                        }
@@ -291,9 +291,9 @@ static gif_result gif_initialise_frame(gif_animation *gif)
 
        unsigned char *gif_data, *gif_end;
        int gif_bytes;
-       unsigned int flags = 0;
-       unsigned int width, height, offset_x, offset_y;
-       unsigned int block_size, colour_table_size;
+       uint32_t flags = 0;
+       uint32_t width, height, offset_x, offset_y;
+       uint32_t block_size, colour_table_size;
        gif_result return_value;
 
        /* Get the frame to decode and our data position */
@@ -518,7 +518,7 @@ static gif_result gif_skip_frame_extensions(gif_animation 
*gif)
                 * of data This data is ignored by this gif decoder
                 */
                while (gif_data < gif_end && gif_data[0] != 
GIF_BLOCK_TERMINATOR) {
-                       unsigned int block_size = gif_data[0] + 1;
+                       uint32_t block_size = gif_data[0] + 1;
 
                        gif_data += block_size;
                        if (gif_data >= gif_end) {
@@ -533,7 +533,7 @@ static gif_result gif_skip_frame_extensions(gif_animation 
*gif)
        return GIF_OK;
 }
 
-static unsigned int gif_interlaced_line(int height, int y) {
+static uint32_t gif_interlaced_line(int height, int y) {
        if ((y << 3) < height) {
                return (y << 3);
        }
@@ -636,17 +636,17 @@ static gif_result gif__recover_previous_frame(const 
gif_animation *gif)
 
 static gif_result
 gif__decode_complex(gif_animation *gif,
-               unsigned int frame,
-               unsigned int width,
-               unsigned int height,
-               unsigned int offset_x,
-               unsigned int offset_y,
-               unsigned int interlace,
+               uint32_t frame,
+               uint32_t width,
+               uint32_t height,
+               uint32_t offset_x,
+               uint32_t offset_y,
+               uint32_t interlace,
                uint8_t minimum_code_size,
-               unsigned int *restrict frame_data,
-               unsigned int *restrict colour_table)
+               uint32_t *restrict frame_data,
+               uint32_t *restrict colour_table)
 {
-       unsigned int transparency_index;
+       uint32_t transparency_index;
        uint32_t available = 0;
        gif_result ret = GIF_OK;
        lzw_result res;
@@ -662,10 +662,10 @@ gif__decode_complex(gif_animation *gif,
                        gif->frames[frame].transparency_index :
                        GIF_NO_TRANSPARENCY;
 
-       for (unsigned int y = 0; y < height; y++) {
-               unsigned int x;
-               unsigned int decode_y;
-               unsigned int *frame_scanline;
+       for (uint32_t y = 0; y < height; y++) {
+               uint32_t x;
+               uint32_t decode_y;
+               uint32_t *frame_scanline;
 
                if (interlace) {
                        decode_y = gif_interlaced_line(height, y) + offset_y;
@@ -702,7 +702,7 @@ gif__decode_complex(gif_animation *gif,
                                }
                        } else {
                                while (row_available-- > 0) {
-                                       register unsigned int colour;
+                                       register uint32_t colour;
                                        colour = *uncompressed++;
                                        if (colour != transparency_index) {
                                                *frame_scanline =
@@ -718,14 +718,14 @@ gif__decode_complex(gif_animation *gif,
 
 static gif_result
 gif__decode_simple(gif_animation *gif,
-               unsigned int frame,
-               unsigned int height,
-               unsigned int offset_y,
+               uint32_t frame,
+               uint32_t height,
+               uint32_t offset_y,
                uint8_t minimum_code_size,
-               unsigned int *restrict frame_data,
-               unsigned int *restrict colour_table)
+               uint32_t *restrict frame_data,
+               uint32_t *restrict colour_table)
 {
-       unsigned int transparency_index;
+       uint32_t transparency_index;
        uint32_t pixels = gif->width * height;
        uint32_t written = 0;
        gif_result ret = GIF_OK;
@@ -770,15 +770,15 @@ gif__decode_simple(gif_animation *gif,
 
 static inline gif_result
 gif__decode(gif_animation *gif,
-               unsigned int frame,
-               unsigned int width,
-               unsigned int height,
-               unsigned int offset_x,
-               unsigned int offset_y,
-               unsigned int interlace,
+               uint32_t frame,
+               uint32_t width,
+               uint32_t height,
+               uint32_t offset_x,
+               uint32_t offset_y,
+               uint32_t interlace,
                uint8_t minimum_code_size,
-               unsigned int *restrict frame_data,
-               unsigned int *restrict colour_table)
+               uint32_t *restrict frame_data,
+               uint32_t *restrict colour_table)
 {
        gif_result ret;
 
@@ -801,16 +801,16 @@ gif__decode(gif_animation *gif,
  * \param frame The frame number to decode.
  */
 static gif_result
-gif_clear_frame(gif_animation *gif, unsigned int frame)
+gif_clear_frame(gif_animation *gif, uint32_t frame)
 {
        unsigned char *gif_data, *gif_end;
        int gif_bytes;
-       unsigned int width, height, offset_x, offset_y;
-       unsigned int flags, colour_table_size;
-       unsigned int *colour_table;
-       unsigned int *frame_data = 0; // Set to 0 for no warnings
-       unsigned int save_buffer_position;
-       unsigned int return_value = 0;
+       uint32_t width, height, offset_x, offset_y;
+       uint32_t flags, colour_table_size;
+       uint32_t *colour_table;
+       uint32_t *frame_data = 0; // Set to 0 for no warnings
+       uint32_t save_buffer_position;
+       uint32_t return_value = 0;
 
        /* Ensure this frame is supposed to be decoded */
        if (gif->frames[frame].display == false) {
@@ -910,9 +910,9 @@ gif_clear_frame(gif_animation *gif, unsigned int frame)
 
        /* Clear our frame */
        if (gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) {
-               unsigned int y;
+               uint32_t y;
                for (y = 0; y < height; y++) {
-                       unsigned int *frame_scanline;
+                       uint32_t *frame_scanline;
                        frame_scanline = frame_data + offset_x + ((offset_y + 
y) * gif->width);
                        if (gif->frames[frame].transparency) {
                                memset(frame_scanline,
@@ -941,18 +941,18 @@ gif_decode_frame_exit:
  */
 static gif_result
 gif_internal_decode_frame(gif_animation *gif,
-                         unsigned int frame)
+                         uint32_t frame)
 {
        gif_result err;
-       unsigned int index = 0;
+       uint32_t index = 0;
        unsigned char *gif_data, *gif_end;
        int gif_bytes;
-       unsigned int width, height, offset_x, offset_y;
-       unsigned int flags, colour_table_size, interlace;
-       unsigned int *colour_table;
-       unsigned int *frame_data = 0; // Set to 0 for no warnings
-       unsigned int save_buffer_position;
-       unsigned int return_value = 0;
+       uint32_t width, height, offset_x, offset_y;
+       uint32_t flags, colour_table_size, interlace;
+       uint32_t *colour_table;
+       uint32_t *frame_data = 0; // Set to 0 for no warnings
+       uint32_t save_buffer_position;
+       uint32_t return_value = 0;
 
        /* Ensure this frame is supposed to be decoded */
        if (gif->frames[frame].display == false) {
@@ -1178,7 +1178,7 @@ void gif_create(gif_animation *gif, 
gif_bitmap_callback_vt *bitmap_callbacks)
 gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data)
 {
        unsigned char *gif_data;
-       unsigned int index;
+       uint32_t index;
        gif_result return_value;
 
        /* Initialize values */
@@ -1279,8 +1279,8 @@ gif_result gif_initialise(gif_animation *gif, size_t 
size, unsigned char *data)
                 * is lying to us. It's far better to give the wrong colours
                 * than to trample over some memory somewhere.
                */
-               gif->global_colour_table = calloc(GIF_MAX_COLOURS, 
sizeof(unsigned int));
-               gif->local_colour_table = calloc(GIF_MAX_COLOURS, 
sizeof(unsigned int));
+               gif->global_colour_table = calloc(GIF_MAX_COLOURS, 
sizeof(uint32_t));
+               gif->local_colour_table = calloc(GIF_MAX_COLOURS, 
sizeof(uint32_t));
                if ((gif->global_colour_table == NULL) ||
                    (gif->local_colour_table == NULL)) {
                        gif_finalise(gif);
@@ -1348,7 +1348,7 @@ gif_result gif_initialise(gif_animation *gif, size_t 
size, unsigned char *data)
                        /* Create a default colour table with the first two
                         * colours as black and white
                         */
-                       unsigned int *entry = gif->global_colour_table;
+                       uint32_t *entry = gif->global_colour_table;
 
                        entry[0] = 0x00000000;
                        /* Force Alpha channel to opaque */


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=e9a47faf8062f9b7db406c273fcbafa2aa6388e1
commit e9a47faf8062f9b7db406c273fcbafa2aa6388e1
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Split out image descriptor parsing.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index e744bcf..054ba9f 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -51,7 +51,6 @@
 #define GIF_FRAME_RESTORE 3
 #define GIF_FRAME_QUIRKS_RESTORE 4
 
-#define GIF_IMAGE_SEPARATOR 0x2c
 #define GIF_INTERLACE_MASK 0x40
 #define GIF_COLOUR_TABLE_MASK 0x80
 #define GIF_COLOUR_TABLE_SIZE_MASK 0x07
@@ -220,6 +219,59 @@ gif_initialise_frame_extensions(gif_animation *gif, const 
int frame)
 }
 
 /**
+ * Parse a GIF Image Descriptor.
+ *
+ * The format is:
+ *
+ *  +0   CHAR   Image Separator (0x2c)
+ *  +1   SHORT  Image Left Position
+ *  +3   SHORT  Image Top Position
+ *  +5   SHORT  Width
+ *  +7   SHORT  Height
+ *  +9   CHAR   __Packed Fields__
+ *              1BIT    Local Colour Table Flag
+ *              1BIT    Interlace Flag
+ *              1BIT    Sort Flag
+ *              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.
+ * \return GIF_OK on success, appropriate error otherwise.
+ */
+static gif_result gif__parse_image_descriptor(
+               struct gif_animation *gif,
+               struct gif_frame *frame)
+{
+       const uint8_t *data = gif->gif_data + gif->buffer_position;
+       size_t len = gif->buffer_size - gif->buffer_position;
+       enum {
+               GIF_IMAGE_DESCRIPTOR_LEN = 10u,
+               GIF_IMAGE_SEPARATOR      = 0x2Cu,
+       };
+
+       assert(gif != NULL);
+       assert(frame != NULL);
+
+       if (len < GIF_IMAGE_DESCRIPTOR_LEN) {
+               return GIF_INSUFFICIENT_FRAME_DATA;
+       }
+
+       if (data[0] != GIF_IMAGE_SEPARATOR) {
+               return GIF_FRAME_DATA_ERROR;
+       }
+
+       frame->redraw_x      = data[1] | (data[2] << 8);
+       frame->redraw_y      = data[3] | (data[4] << 8);
+       frame->redraw_width  = data[5] | (data[6] << 8);
+       frame->redraw_height = data[7] | (data[8] << 8);
+       frame->flags         = data[9];
+
+       gif->buffer_position += GIF_IMAGE_DESCRIPTOR_LEN;
+       return GIF_OK;
+}
+
+/**
  * Attempts to initialise the next frame
  *
  * \param gif The animation context
@@ -314,53 +366,25 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        gif_data = (gif->gif_data + gif->buffer_position);
        gif_bytes = (gif_end - gif_data);
 
-       /* Check if we've finished */
-       if (gif_bytes < 1) {
-               return GIF_INSUFFICIENT_FRAME_DATA;
-       }
-
        if (gif_data[0] == GIF_TRAILER) {
                gif->buffer_position = (gif_data - gif->gif_data);
                gif->frame_count = frame + 1;
                return GIF_OK;
        }
 
-       /* 10-byte Image Descriptor is:
-        *
-        *  +0   CHAR   Image Separator (0x2c)
-        *  +1   SHORT  Image Left Position
-        *  +3   SHORT  Image Top Position
-        *  +5   SHORT  Width
-        *  +7   SHORT  Height
-        *  +9   CHAR   __Packed Fields__
-        *              1BIT    Local Colour Table Flag
-        *              1BIT    Interlace Flag
-        *              1BIT    Sort Flag
-        *              2BITS   Reserved
-        *              3BITS   Size of Local Colour Table
-        */
-
-       /* If we're not done, there should be an image descriptor */
-       if (gif_data[0] != GIF_IMAGE_SEPARATOR) {
-               return GIF_FRAME_DATA_ERROR;
+       return_value = gif__parse_image_descriptor(gif, &gif->frames[frame]);
+       if (return_value != GIF_OK) {
+               return return_value;
        }
 
-       /* Do some simple boundary checking */
-       if (gif_bytes < 10) {
-               return GIF_INSUFFICIENT_FRAME_DATA;
-       }
-       offset_x = gif_data[1] | (gif_data[2] << 8);
-       offset_y = gif_data[3] | (gif_data[4] << 8);
-       width = gif_data[5] | (gif_data[6] << 8);
-       height = gif_data[7] | (gif_data[8] << 8);
-       flags = gif_data[9];
+       gif_data = gif->gif_data + gif->buffer_position;
+       gif_bytes = (gif_end - gif_data);
 
-       /* Set up the redraw area. */
-       gif->frames[frame].redraw_x = offset_x;
-       gif->frames[frame].redraw_y = offset_y;
-       gif->frames[frame].redraw_width = width;
-       gif->frames[frame].redraw_height = height;
-       gif->frames[frame].flags = flags;
+       offset_x = gif->frames[frame].redraw_x;
+       offset_y = gif->frames[frame].redraw_y;
+       width = gif->frames[frame].redraw_width;
+       height = gif->frames[frame].redraw_height;
+       flags = gif->frames[frame].flags;
 
        /* if we are clearing the background then we need to redraw enough to
         * cover the previous frame too
@@ -380,8 +404,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
 
        /* Move our data onwards and remember we've got a bit of this frame */
-       gif_data += 10;
-       gif_bytes = (gif_end - gif_data);
        gif->frame_count_partial = frame + 1;
 
        /* Skip the local colour table */


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=46d7a0bb13a36dabaa5ede2158d22e3e702f5ad2
commit 46d7a0bb13a36dabaa5ede2158d22e3e702f5ad2
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Use cached frame details for clear disposal handling.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 3cb1135..e744bcf 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -832,37 +832,11 @@ gif_clear_frame(gif_animation *gif, unsigned int frame)
                goto gif_decode_frame_exit;
        }
 
-       /* 10-byte Image Descriptor is:
-        *
-        *  +0   CHAR   Image Separator (0x2c)
-        *  +1   SHORT  Image Left Position
-        *  +3   SHORT  Image Top Position
-        *  +5   SHORT  Width
-        *  +7   SHORT  Height
-        *  +9   CHAR   __Packed Fields__
-        *              1BIT    Local Colour Table Flag
-        *              1BIT    Interlace Flag
-        *              1BIT    Sort Flag
-        *              2BITS   Reserved
-        *              3BITS   Size of Local Colour Table
-        */
-       if (gif_data[0] != GIF_IMAGE_SEPARATOR) {
-               return_value = GIF_DATA_ERROR;
-               goto gif_decode_frame_exit;
-       }
-       offset_x = gif_data[1] | (gif_data[2] << 8);
-       offset_y = gif_data[3] | (gif_data[4] << 8);
-       width = gif_data[5] | (gif_data[6] << 8);
-       height = gif_data[7] | (gif_data[8] << 8);
-
-       /* Boundary checking - shouldn't ever happen except unless the data has
-        * been modified since initialisation.
-        */
-       if ((offset_x + width > gif->width) ||
-           (offset_y + height > gif->height)) {
-               return_value = GIF_DATA_ERROR;
-               goto gif_decode_frame_exit;
-       }
+       offset_x = gif->frames[frame].redraw_x;
+       offset_y = gif->frames[frame].redraw_y;
+       width = gif->frames[frame].redraw_width;
+       height = gif->frames[frame].redraw_height;
+       flags = gif->frames[frame].flags;
 
        /* Make sure we have a buffer to decode to.
         */
@@ -871,7 +845,6 @@ gif_clear_frame(gif_animation *gif, unsigned int frame)
        }
 
        /* Decode the flags */
-       flags = gif_data[9];
        colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
 
        /* Advance data pointer to next block either colour table or image


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=8eac839eed55432446077659c052b6459509af2a
commit 8eac839eed55432446077659c052b6459509af2a
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Move image descriptor parsing to frame initialisation.

diff --git a/include/libnsgif.h b/include/libnsgif.h
index 50dc688..f220460 100644
--- a/include/libnsgif.h
+++ b/include/libnsgif.h
@@ -62,6 +62,8 @@ typedef struct gif_frame {
         unsigned int redraw_width;
         /** height of redraw rectangle */
         unsigned int redraw_height;
+        /* Frame flags */
+        unsigned int flags;
 } gif_frame;
 
 /* API for Bitmap callbacks */
diff --git a/src/libnsgif.c b/src/libnsgif.c
index 3678083..3cb1135 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -219,7 +219,6 @@ gif_initialise_frame_extensions(gif_animation *gif, const 
int frame)
        return GIF_OK;
 }
 
-
 /**
  * Attempts to initialise the next frame
  *
@@ -326,6 +325,21 @@ static gif_result gif_initialise_frame(gif_animation *gif)
                return GIF_OK;
        }
 
+       /* 10-byte Image Descriptor is:
+        *
+        *  +0   CHAR   Image Separator (0x2c)
+        *  +1   SHORT  Image Left Position
+        *  +3   SHORT  Image Top Position
+        *  +5   SHORT  Width
+        *  +7   SHORT  Height
+        *  +9   CHAR   __Packed Fields__
+        *              1BIT    Local Colour Table Flag
+        *              1BIT    Interlace Flag
+        *              1BIT    Sort Flag
+        *              2BITS   Reserved
+        *              3BITS   Size of Local Colour Table
+        */
+
        /* If we're not done, there should be an image descriptor */
        if (gif_data[0] != GIF_IMAGE_SEPARATOR) {
                return GIF_FRAME_DATA_ERROR;
@@ -339,12 +353,14 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        offset_y = gif_data[3] | (gif_data[4] << 8);
        width = gif_data[5] | (gif_data[6] << 8);
        height = gif_data[7] | (gif_data[8] << 8);
+       flags = gif_data[9];
 
        /* Set up the redraw area. */
        gif->frames[frame].redraw_x = offset_x;
        gif->frames[frame].redraw_y = offset_y;
        gif->frames[frame].redraw_width = width;
        gif->frames[frame].redraw_height = height;
+       gif->frames[frame].flags = flags;
 
        /* if we are clearing the background then we need to redraw enough to
         * cover the previous frame too
@@ -361,7 +377,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
                        offset_y + height : gif->height;
 
        /* Decode the flags */
-       flags = gif_data[9];
        colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
 
        /* Move our data onwards and remember we've got a bit of this frame */
@@ -991,37 +1006,11 @@ gif_internal_decode_frame(gif_animation *gif,
                goto gif_decode_frame_exit;
        }
 
-       /* 10-byte Image Descriptor is:
-        *
-        *  +0   CHAR   Image Separator (0x2c)
-        *  +1   SHORT  Image Left Position
-        *  +3   SHORT  Image Top Position
-        *  +5   SHORT  Width
-        *  +7   SHORT  Height
-        *  +9   CHAR   __Packed Fields__
-        *              1BIT    Local Colour Table Flag
-        *              1BIT    Interlace Flag
-        *              1BIT    Sort Flag
-        *              2BITS   Reserved
-        *              3BITS   Size of Local Colour Table
-        */
-       if (gif_data[0] != GIF_IMAGE_SEPARATOR) {
-               return_value = GIF_DATA_ERROR;
-               goto gif_decode_frame_exit;
-       }
-       offset_x = gif_data[1] | (gif_data[2] << 8);
-       offset_y = gif_data[3] | (gif_data[4] << 8);
-       width = gif_data[5] | (gif_data[6] << 8);
-       height = gif_data[7] | (gif_data[8] << 8);
-
-       /* Boundary checking - shouldn't ever happen except unless the data has
-        * been modified since initialisation.
-        */
-       if ((offset_x + width > gif->width) ||
-           (offset_y + height > gif->height)) {
-               return_value = GIF_DATA_ERROR;
-               goto gif_decode_frame_exit;
-       }
+       offset_x = gif->frames[frame].redraw_x;
+       offset_y = gif->frames[frame].redraw_y;
+       width = gif->frames[frame].redraw_width;
+       height = gif->frames[frame].redraw_height;
+       flags = gif->frames[frame].flags;
 
        /* Make sure we have a buffer to decode to.
         */
@@ -1030,7 +1019,6 @@ gif_internal_decode_frame(gif_animation *gif,
        }
 
        /* Decode the flags */
-       flags = gif_data[9];
        colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK);
        interlace = flags & GIF_INTERLACE_MASK;
 


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=12580f6d6737c7a549f465cd76183798cb6539bc
commit 12580f6d6737c7a549f465cd76183798cb6539bc
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Clean up block skipping in frame extension skip.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 0d84032..3678083 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -445,13 +445,10 @@ static gif_result gif_initialise_frame(gif_animation *gif)
 static gif_result gif_skip_frame_extensions(gif_animation *gif)
 {
        unsigned char *gif_data, *gif_end;
-       int gif_bytes;
-       unsigned int block_size;
 
        /* Get our buffer position etc. */
        gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position);
        gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size);
-       gif_bytes = (gif_end - gif_data);
 
        /* Skip the extensions */
        while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) {
@@ -483,14 +480,13 @@ static gif_result gif_skip_frame_extensions(gif_animation 
*gif)
                /* Repeatedly skip blocks until we get a zero block or run out
                 * of data This data is ignored by this gif decoder
                 */
-               gif_bytes = (gif_end - gif_data);
-               block_size = 0;
                while (gif_data < gif_end && gif_data[0] != 
GIF_BLOCK_TERMINATOR) {
-                       block_size = gif_data[0] + 1;
-                       if ((gif_bytes -= block_size) < 0) {
+                       unsigned int block_size = gif_data[0] + 1;
+
+                       gif_data += block_size;
+                       if (gif_data >= gif_end) {
                                return GIF_INSUFFICIENT_FRAME_DATA;
                        }
-                       gif_data += block_size;
                }
                ++gif_data;
        }


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=6344f78d4faac7f141edd2ecb21223f95988f582
commit 6344f78d4faac7f141edd2ecb21223f95988f582
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Remove redundant redraw box complexity.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 94b07af..0d84032 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -243,7 +243,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        unsigned int flags = 0;
        unsigned int width, height, offset_x, offset_y;
        unsigned int block_size, colour_table_size;
-       bool first_image = true;
        gif_result return_value;
 
        /* Get the frame to decode and our data position */
@@ -341,34 +340,11 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        width = gif_data[5] | (gif_data[6] << 8);
        height = gif_data[7] | (gif_data[8] << 8);
 
-       /* Set up the redraw characteristics. We have to check for extending
-        * the area due to multi-image frames.
-        */
-       if (!first_image) {
-               if (gif->frames[frame].redraw_x > offset_x) {
-                       gif->frames[frame].redraw_width += 
(gif->frames[frame].redraw_x - offset_x);
-                       gif->frames[frame].redraw_x = offset_x;
-               }
-
-               if (gif->frames[frame].redraw_y > offset_y) {
-                       gif->frames[frame].redraw_height += 
(gif->frames[frame].redraw_y - offset_y);
-                       gif->frames[frame].redraw_y = offset_y;
-               }
-
-               if ((offset_x + width) > (gif->frames[frame].redraw_x + 
gif->frames[frame].redraw_width)) {
-                       gif->frames[frame].redraw_width = (offset_x + width) - 
gif->frames[frame].redraw_x;
-               }
-
-               if ((offset_y + height) > (gif->frames[frame].redraw_y + 
gif->frames[frame].redraw_height)) {
-                       gif->frames[frame].redraw_height = (offset_y + height) 
- gif->frames[frame].redraw_y;
-               }
-       } else {
-               first_image = false;
-               gif->frames[frame].redraw_x = offset_x;
-               gif->frames[frame].redraw_y = offset_y;
-               gif->frames[frame].redraw_width = width;
-               gif->frames[frame].redraw_height = height;
-       }
+       /* Set up the redraw area. */
+       gif->frames[frame].redraw_x = offset_x;
+       gif->frames[frame].redraw_y = offset_y;
+       gif->frames[frame].redraw_width = width;
+       gif->frames[frame].redraw_height = height;
 
        /* if we are clearing the background then we need to redraw enough to
         * cover the previous frame too


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=5af2a3dddfebff63742bfd83618d037b4d95bca2
commit 5af2a3dddfebff63742bfd83618d037b4d95bca2
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Clean up ugly redundant assignment in comparison.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 64db9b1..94b07af 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -317,7 +317,7 @@ static gif_result gif_initialise_frame(gif_animation *gif)
        gif_bytes = (gif_end - gif_data);
 
        /* Check if we've finished */
-       if ((gif_bytes = (gif_end - gif_data)) < 1) {
+       if (gif_bytes < 1) {
                return GIF_INSUFFICIENT_FRAME_DATA;
        }
 


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=bd01b79660e5c41e04180ad291bf82619d420c79
commit bd01b79660e5c41e04180ad291bf82619d420c79
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Reduce scope of block_size variable.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 87911cb..64db9b1 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -110,7 +110,6 @@ gif_initialise_frame_extensions(gif_animation *gif, const 
int frame)
 {
        unsigned char *gif_data, *gif_end;
        int gif_bytes;
-       unsigned int block_size;
 
        /* Get our buffer position etc. */
        gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position);
@@ -205,9 +204,8 @@ gif_initialise_frame_extensions(gif_animation *gif, const 
int frame)
                 * of data This data is ignored by this gif decoder
                 */
                gif_bytes = (gif_end - gif_data);
-               block_size = 0;
                while (gif_data < gif_end && gif_data[0] != 
GIF_BLOCK_TERMINATOR) {
-                       block_size = gif_data[0] + 1;
+                       unsigned int block_size = gif_data[0] + 1;
                        if ((gif_bytes -= block_size) < 0) {
                                return GIF_INSUFFICIENT_FRAME_DATA;
                        }


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=3d3dd3d63af6aa0c7ee126978c4ee39d2dd7e817
commit 3d3dd3d63af6aa0c7ee126978c4ee39d2dd7e817
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Split out handling of clear frame disposal method.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 16bb78a..87911cb 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -792,12 +792,176 @@ gif__decode(gif_animation *gif,
  *
  * \param gif gif animation context.
  * \param frame The frame number to decode.
+ */
+static gif_result
+gif_clear_frame(gif_animation *gif, unsigned int frame)
+{
+       unsigned char *gif_data, *gif_end;
+       int gif_bytes;
+       unsigned int width, height, offset_x, offset_y;
+       unsigned int flags, colour_table_size;
+       unsigned int *colour_table;
+       unsigned int *frame_data = 0; // Set to 0 for no warnings
+       unsigned int save_buffer_position;
+       unsigned int return_value = 0;
+
+       /* Ensure this frame is supposed to be decoded */
+       if (gif->frames[frame].display == false) {
+               return GIF_OK;
+       }
+
+       /* Ensure the frame is in range to decode */
+       if (frame > gif->frame_count_partial) {
+               return GIF_INSUFFICIENT_DATA;
+       }
+
+       /* Get the start of our frame data and the end of the GIF data */
+       gif_data = gif->gif_data + gif->frames[frame].frame_pointer;
+       gif_end = gif->gif_data + gif->buffer_size;
+       gif_bytes = (gif_end - gif_data);
+
+       /*
+        * Ensure there is a minimal amount of data to proceed.  The shortest
+        * block of data is a 10-byte image descriptor + 1-byte gif trailer
+        */
+       if (gif_bytes < 12) {
+               return GIF_INSUFFICIENT_FRAME_DATA;
+       }
+
+       /* Save the buffer position */
+       save_buffer_position = gif->buffer_position;
+       gif->buffer_position = gif_data - gif->gif_data;
+
+       /* Skip any extensions because they have already been processed */
+       if ((return_value = gif_skip_frame_extensions(gif)) != GIF_OK) {
+               goto gif_decode_frame_exit;
+       }
+       gif_data = (gif->gif_data + gif->buffer_position);
+       gif_bytes = (gif_end - gif_data);
+
+       /* Ensure we have enough data for the 10-byte image descriptor + 1-byte
+        * gif trailer
+        */
+       if (gif_bytes < 12) {
+               return_value = GIF_INSUFFICIENT_FRAME_DATA;
+               goto gif_decode_frame_exit;
+       }
+
+       /* 10-byte Image Descriptor is:
+        *
+        *  +0   CHAR   Image Separator (0x2c)
+        *  +1   SHORT  Image Left Position
+        *  +3   SHORT  Image Top Position
+        *  +5   SHORT  Width
+        *  +7   SHORT  Height
+        *  +9   CHAR   __Packed Fields__
+        *              1BIT    Local Colour Table Flag
+        *              1BIT    Interlace Flag
+        *              1BIT    Sort Flag
+        *              2BITS   Reserved
+        *              3BITS   Size of Local Colour Table
+        */
+       if (gif_data[0] != GIF_IMAGE_SEPARATOR) {
+               return_value = GIF_DATA_ERROR;
+               goto gif_decode_frame_exit;
+       }
+       offset_x = gif_data[1] | (gif_data[2] << 8);
+       offset_y = gif_data[3] | (gif_data[4] << 8);
+       width = gif_data[5] | (gif_data[6] << 8);
+       height = gif_data[7] | (gif_data[8] << 8);
+
+       /* Boundary checking - shouldn't ever happen except unless the data has
+        * been modified since initialisation.
+        */
+       if ((offset_x + width > gif->width) ||
+           (offset_y + height > gif->height)) {
+               return_value = GIF_DATA_ERROR;
+               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);
+
+       /* Advance data pointer to next block either colour table or image
+        * data.
+        */
+       gif_data += 10;
+       gif_bytes = (gif_end - gif_data);
+
+       /* Set up the colour table */
+       if (flags & GIF_COLOUR_TABLE_MASK) {
+               if (gif_bytes < (int)(3 * colour_table_size)) {
+                       return_value = GIF_INSUFFICIENT_FRAME_DATA;
+                       goto gif_decode_frame_exit;
+               }
+               colour_table = gif->local_colour_table;
+               gif_data += 3 * colour_table_size;
+
+               gif_bytes = (gif_end - gif_data);
+       } else {
+               colour_table = gif->global_colour_table;
+       }
+
+       /* Ensure sufficient data remains */
+       if (gif_bytes < 1) {
+               return_value = GIF_INSUFFICIENT_FRAME_DATA;
+               goto gif_decode_frame_exit;
+       }
+
+       /* check for an end marker */
+       if (gif_data[0] == GIF_TRAILER) {
+               return_value = GIF_OK;
+               goto gif_decode_frame_exit;
+       }
+
+       /* Get the frame data */
+       assert(gif->bitmap_callbacks.bitmap_get_buffer);
+       frame_data = (void 
*)gif->bitmap_callbacks.bitmap_get_buffer(gif->frame_image);
+       if (!frame_data) {
+               return GIF_INSUFFICIENT_MEMORY;
+       }
+
+       /* Clear our frame */
+       if (gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) {
+               unsigned int y;
+               for (y = 0; y < height; y++) {
+                       unsigned int *frame_scanline;
+                       frame_scanline = frame_data + offset_x + ((offset_y + 
y) * gif->width);
+                       if (gif->frames[frame].transparency) {
+                               memset(frame_scanline,
+                                      GIF_TRANSPARENT_COLOUR,
+                                      width * 4);
+                       } else {
+                               memset(frame_scanline,
+                                      colour_table[gif->background_index],
+                                      width * 4);
+                       }
+               }
+       }
+gif_decode_frame_exit:
+       /* Restore the buffer position */
+       gif->buffer_position = save_buffer_position;
+
+       return return_value;
+}
+
+/**
+ * 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(gif_animation *gif,
-                         unsigned int frame,
-                         bool clear_image)
+                         unsigned int frame)
 {
        gif_result err;
        unsigned int index = 0;
@@ -821,8 +985,7 @@ gif_internal_decode_frame(gif_animation *gif,
        }
 
        /* done if frame is already decoded */
-       if ((!clear_image) &&
-           ((int)frame == gif->decoded_frame)) {
+       if (((int)frame == gif->decoded_frame)) {
                return GIF_OK;
        }
 
@@ -914,27 +1077,23 @@ gif_internal_decode_frame(gif_animation *gif,
                        goto gif_decode_frame_exit;
                }
                colour_table = gif->local_colour_table;
-               if (!clear_image) {
-                       for (index = 0; index < colour_table_size; index++) {
-                               /* Gif colour map contents are r,g,b.
-                                *
-                                * We want to pack them bytewise into the
-                                * colour table, such that the red component
-                                * is in byte 0 and the alpha component is in
-                                * byte 3.
-                                */
-                               unsigned char *entry =
-                                       (unsigned char *) &colour_table[index];
+               for (index = 0; index < colour_table_size; index++) {
+                       /* Gif colour map contents are r,g,b.
+                        *
+                        * We want to pack them bytewise into the
+                        * colour table, such that the red component
+                        * is in byte 0 and the alpha component is in
+                        * byte 3.
+                        */
+                       unsigned char *entry =
+                               (unsigned char *) &colour_table[index];
 
-                               entry[0] = gif_data[0]; /* r */
-                               entry[1] = gif_data[1]; /* g */
-                               entry[2] = gif_data[2]; /* b */
-                               entry[3] = 0xff;        /* a */
+                       entry[0] = gif_data[0]; /* r */
+                       entry[1] = gif_data[1]; /* g */
+                       entry[2] = gif_data[2]; /* b */
+                       entry[3] = 0xff;        /* a */
 
-                               gif_data += 3;
-                       }
-               } else {
-                       gif_data += 3 * colour_table_size;
+                       gif_data += 3;
                }
                gif_bytes = (gif_end - gif_data);
        } else {
@@ -960,113 +1119,89 @@ gif_internal_decode_frame(gif_animation *gif,
                return GIF_INSUFFICIENT_MEMORY;
        }
 
-       /* If we are clearing the image we just clear, if not decode */
-       if (!clear_image) {
-               /* Ensure we have enough data for a 1-byte LZW code size +
-                * 1-byte gif trailer
-                */
-               if (gif_bytes < 2) {
-                       return_value = GIF_INSUFFICIENT_FRAME_DATA;
-                       goto gif_decode_frame_exit;
-               }
+       /* Ensure we have enough data for a 1-byte LZW code size +
+        * 1-byte gif trailer
+        */
+       if (gif_bytes < 2) {
+               return_value = GIF_INSUFFICIENT_FRAME_DATA;
+               goto gif_decode_frame_exit;
+       }
 
-               /* If we only have a 1-byte LZW code size + 1-byte gif trailer,
-                * we're finished
-                */
-               if ((gif_bytes == 2) && (gif_data[1] == GIF_TRAILER)) {
-                       return_value = GIF_OK;
+       /* If we only have a 1-byte LZW code size + 1-byte gif trailer,
+        * we're finished
+        */
+       if ((gif_bytes == 2) && (gif_data[1] == GIF_TRAILER)) {
+               return_value = GIF_OK;
+               goto gif_decode_frame_exit;
+       }
+
+       /* If the previous frame's disposal method requires we restore
+        * the background colour or this is the first frame, clear
+        * the frame data
+        */
+       if ((frame == 0) || (gif->decoded_frame == GIF_INVALID_FRAME)) {
+               memset((char*)frame_data,
+                      GIF_TRANSPARENT_COLOUR,
+                      gif->width * gif->height * sizeof(int));
+               gif->decoded_frame = frame;
+               /* The line below would fill the image with its
+                * background color, but because GIFs support
+                * transparency we likely wouldn't want to do that. */
+               /* memset((char*)frame_data, 
colour_table[gif->background_index], gif->width * gif->height * sizeof(int)); */
+       } else if ((frame != 0) &&
+                  (gif->frames[frame - 1].disposal_method == GIF_FRAME_CLEAR)) 
{
+               return_value = gif_clear_frame(gif, frame - 1);
+               if (return_value != GIF_OK) {
                        goto gif_decode_frame_exit;
                }
 
-               /* If the previous frame's disposal method requires we restore
-                * the background colour or this is the first frame, clear
-                * the frame data
+       } else if ((frame != 0) &&
+                  (gif->frames[frame - 1].disposal_method == 
GIF_FRAME_RESTORE)) {
+               /*
+                * If the previous frame's disposal method requires we
+                * restore the previous image, restore our saved image.
                 */
-               if ((frame == 0) || (gif->decoded_frame == GIF_INVALID_FRAME)) {
+               err = gif__recover_previous_frame(gif);
+               if (err != GIF_OK) {
+                       /* see notes above on transparency
+                        * vs. background color
+                        */
                        memset((char*)frame_data,
                               GIF_TRANSPARENT_COLOUR,
                               gif->width * gif->height * sizeof(int));
-                       gif->decoded_frame = frame;
-                       /* The line below would fill the image with its
-                        * background color, but because GIFs support
-                        * transparency we likely wouldn't want to do that. */
-                       /* memset((char*)frame_data, 
colour_table[gif->background_index], gif->width * gif->height * sizeof(int)); */
-               } else if ((frame != 0) &&
-                          (gif->frames[frame - 1].disposal_method == 
GIF_FRAME_CLEAR)) {
-                       return_value = gif_internal_decode_frame(gif,
-                                                                (frame - 1),
-                                                                true);
-                       if (return_value != GIF_OK) {
-                               goto gif_decode_frame_exit;
-                       }
-
-               } else if ((frame != 0) &&
-                          (gif->frames[frame - 1].disposal_method == 
GIF_FRAME_RESTORE)) {
-                       /*
-                        * If the previous frame's disposal method requires we
-                        * restore the previous image, restore our saved image.
-                        */
-                       err = gif__recover_previous_frame(gif);
-                       if (err != GIF_OK) {
-                               /* see notes above on transparency
-                                * vs. background color
-                                */
-                               memset((char*)frame_data,
-                                      GIF_TRANSPARENT_COLOUR,
-                                      gif->width * gif->height * sizeof(int));
-                       }
                }
+       }
 
-               if (gif->frames[frame].disposal_method == GIF_FRAME_RESTORE) {
-                       /* Store the previous frame for later restoration */
-                       gif__record_previous_frame(gif);
-               }
+       if (gif->frames[frame].disposal_method == GIF_FRAME_RESTORE) {
+               /* Store the previous frame for later restoration */
+               gif__record_previous_frame(gif);
+       }
 
-               gif->decoded_frame = frame;
-               gif->buffer_position = (gif_data - gif->gif_data) + 1;
+       gif->decoded_frame = frame;
+       gif->buffer_position = (gif_data - gif->gif_data) + 1;
+
+       return_value = gif__decode(gif, frame, width, height,
+                       offset_x, offset_y, interlace, gif_data[0],
+                       frame_data, colour_table);
 
-               return_value = gif__decode(gif, frame, width, height,
-                               offset_x, offset_y, interlace, gif_data[0],
-                               frame_data, colour_table);
-       } else {
-               /* Clear our frame */
-               if (gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) {
-                       unsigned int y;
-                       for (y = 0; y < height; y++) {
-                               unsigned int *frame_scanline;
-                               frame_scanline = frame_data + offset_x + 
((offset_y + y) * gif->width);
-                               if (gif->frames[frame].transparency) {
-                                       memset(frame_scanline,
-                                              GIF_TRANSPARENT_COLOUR,
-                                              width * 4);
-                               } else {
-                                       memset(frame_scanline,
-                                              
colour_table[gif->background_index],
-                                              width * 4);
-                               }
-                       }
-               }
-       }
 gif_decode_frame_exit:
 
-       if (!clear_image) {
-               if (gif->bitmap_callbacks.bitmap_modified) {
-                       gif->bitmap_callbacks.bitmap_modified(gif->frame_image);
-               }
+       if (gif->bitmap_callbacks.bitmap_modified) {
+               gif->bitmap_callbacks.bitmap_modified(gif->frame_image);
+       }
 
-               /* Check if we should test for optimisation */
-               if (gif->frames[frame].virgin) {
-                       if (gif->bitmap_callbacks.bitmap_test_opaque) {
-                               gif->frames[frame].opaque = 
gif->bitmap_callbacks.bitmap_test_opaque(gif->frame_image);
-                       } else {
-                               gif->frames[frame].opaque = false;
-                       }
-                       gif->frames[frame].virgin = false;
+       /* Check if we should test for optimisation */
+       if (gif->frames[frame].virgin) {
+               if (gif->bitmap_callbacks.bitmap_test_opaque) {
+                       gif->frames[frame].opaque = 
gif->bitmap_callbacks.bitmap_test_opaque(gif->frame_image);
+               } else {
+                       gif->frames[frame].opaque = false;
                }
+               gif->frames[frame].virgin = false;
+       }
 
-               if (gif->bitmap_callbacks.bitmap_set_opaque) {
-                       
gif->bitmap_callbacks.bitmap_set_opaque(gif->frame_image, 
gif->frames[frame].opaque);
-               }
+       if (gif->bitmap_callbacks.bitmap_set_opaque) {
+               gif->bitmap_callbacks.bitmap_set_opaque(gif->frame_image, 
gif->frames[frame].opaque);
        }
 
        /* Restore the buffer position */
@@ -1295,7 +1430,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, false);
+       return gif_internal_decode_frame(gif, frame);
 }
 
 


-----------------------------------------------------------------------


-- 
NetSurf GIF Decoder
_______________________________________________
netsurf-commits mailing list -- netsurf-commits@netsurf-browser.org
To unsubscribe send an email to netsurf-commits-le...@netsurf-browser.org

Reply via email to