Gitweb links:

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

The branch, master has been updated
       via  9a2562eab7be22a6c1d58308c473f8ed4468e1df (commit)
       via  5cf46c9369a4272ef4f22b15f08c559aee710d4a (commit)
       via  b76c51120f4556a27092b2f107cf0e3aabf2ec16 (commit)
       via  f429a4f329cfaebc3e6644cac9610b89c74d9ba2 (commit)
       via  cb7f357b58c85bc089221060aa57a6c4ea5e9c06 (commit)
      from  a1c436270011cb3770f3d74bf08347289feb1273 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=9a2562eab7be22a6c1d58308c473f8ed4468e1df
commit 9a2562eab7be22a6c1d58308c473f8ed4468e1df
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>

    Docs: README: Update to mention nsgif_data_complete

diff --git a/README.md b/README.md
index e6219aa..5007da9 100644
--- a/README.md
+++ b/README.md
@@ -67,6 +67,10 @@ it has reached the end of the source data.
 > buffer. Just be sure to call `nsgif_data_scan()` again with the new pointer
 > before making any other calls against that nsgif object.
 
+When all the source data has been provided to `nsgif_data_scan()` it is
+advisable to call `nsgif_data_complete()` (see below), although this is not
+necessary to start decoding frames.
+
 To decode the frames, you can call `nsgif_get_info()` to get the frame_count,
 and then call `nsgif_frame_decode()` for each frame, and manage the animation,
 and non-displayable frames yourself, or you can use the helper function,
@@ -122,6 +126,20 @@ on-demand with:
 Note that this will be a no-op if the requested frame already happens to be
 the decoded frame.
 
+You can call `nsgif_frame_prepare()` and `nsgif_frame_decode()` before all
+of the GIF data has been provided using `nsgif_data_scan()` calls. For example
+if you want to make a start decoding and displaying the early frames of the GIF
+before the entire animation file has been downloaded.
+
+When you do this, `nsgif_frame_prepare()` will not loop the animation back to
+the start unless you call `nsgif_data_complete()` to indicate all of the data
+has been fetched. Calling `nsgif_data_complete()` also lets libnsgif display
+any trailing truncated frame.
+
+```c
+       nsgif_data_complete(gif);
+```
+
 Once you are done with the GIF, free up the nsgif object with:
 
 ```c


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=5cf46c9369a4272ef4f22b15f08c559aee710d4a
commit 5cf46c9369a4272ef4f22b15f08c559aee710d4a
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>

    Tests: Decoder: Mark the gif data complete after scanning input

diff --git a/test/nsgif.c b/test/nsgif.c
index 5ad9116..7d61504 100644
--- a/test/nsgif.c
+++ b/test/nsgif.c
@@ -384,6 +384,8 @@ int main(int argc, char *argv[])
                warning("nsgif_data_scan", err);
        }
 
+       nsgif_data_complete(gif);
+
        if (nsgif_options.loops == 0) {
                nsgif_options.loops = 1;
        }


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=b76c51120f4556a27092b2f107cf0e3aabf2ec16
commit b76c51120f4556a27092b2f107cf0e3aabf2ec16
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>

    Tests: Decoder: Improve warning logging

diff --git a/test/nsgif.c b/test/nsgif.c
index 4a9e31c..5ad9116 100644
--- a/test/nsgif.c
+++ b/test/nsgif.c
@@ -137,8 +137,7 @@ static uint8_t *load_file(const char *path, size_t 
*data_size)
 
 static void warning(const char *context, nsgif_error err)
 {
-       fprintf(stderr, "%s failed: %s\n",
-                       context, nsgif_strerror(err));
+       fprintf(stderr, "%s: %s\n", context, nsgif_strerror(err));
 }
 
 static void print_gif_info(const nsgif_info_t *info)


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=f429a4f329cfaebc3e6644cac9610b89c74d9ba2
commit f429a4f329cfaebc3e6644cac9610b89c74d9ba2
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>

    API: Add call to indicate input data is complete
    
    By distinguising between waiting for more data and a broken
    truncated file, we can decode what we can of any final truncated
    frame.

diff --git a/include/nsgif.h b/include/nsgif.h
index 208bc27..7e6aa83 100644
--- a/include/nsgif.h
+++ b/include/nsgif.h
@@ -90,6 +90,11 @@ typedef enum {
        NSGIF_ERR_END_OF_DATA,
 
        /**
+        * Can't supply more data after calling \ref nsgif_data_complete.
+        */
+       NSGIF_ERR_DATA_COMPLETE,
+
+       /**
         * The current frame cannot be displayed.
         */
        NSGIF_ERR_FRAME_DISPLAY,
@@ -277,6 +282,8 @@ void nsgif_destroy(nsgif_t *gif);
  * several times, as more data is available (e.g. slow network fetch) the data
  * already given to \ref nsgif_data_scan must be provided each time.
  *
+ * Once all the data has been provided, call \ref nsgif_data_complete.
+ *
  * For example, if you call \ref nsgif_data_scan with 25 bytes of data, and 
then
  * fetch another 10 bytes, you would need to call \ref nsgif_data_scan with a
  * size of 35 bytes, and the whole 35 bytes must be contiguous memory. It is
@@ -300,12 +307,34 @@ nsgif_error nsgif_data_scan(
                const uint8_t *data);
 
 /**
+ * Tell libnsgif that all the gif data has been provided.
+ *
+ * Call this after calling \ref nsgif_data_scan with the the entire GIF
+ * source data. You can call \ref nsgif_data_scan multiple times up until
+ * this is called, and after this is called, \ref nsgif_data_scan will
+ * return an error.
+ *
+ * You can decode a GIF before this is called, however, it will fail to
+ * decode any truncated final frame data and will not perform loops when
+ * driven via \ref nsgif_frame_prepare (because it doesn't know if there
+ * will be more frames supplied in future data).
+ *
+ * \param[in]  gif     The \ref nsgif_t object.
+ */
+void nsgif_data_complete(
+               nsgif_t *gif);
+
+/**
  * Prepare to show a frame.
  *
  * If this is the last frame of an animation with a finite loop count, the
  * returned `delay_cs` will be \ref NSGIF_INFINITE, indicating that the frame
  * should be shown forever.
  *
+ * Note that if \ref nsgif_data_complete has not been called on this gif,
+ * animated GIFs will not loop back to the start. Instead it will return
+ * \ref NSGIF_ERR_END_OF_DATA.
+ *
  * \param[in]  gif        The \ref nsgif_t object.
  * \param[out] area       The area in pixels that must be redrawn.
  * \param[out] delay_cs   Time to wait after frame_new before next frame in cs.
diff --git a/src/gif.c b/src/gif.c
index a5c44ee..2dc631e 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -40,6 +40,9 @@ typedef struct nsgif_frame {
        /** whether a full image redraw is required */
        bool redraw_required;
 
+       /** Amount of LZW data found in scan */
+       uint32_t lzw_data_length;
+
        /** the index designating a transparent pixel */
        uint32_t transparency_index;
 
@@ -90,6 +93,12 @@ struct nsgif {
        /** number of frames partially decoded */
        uint32_t frame_count_partial;
 
+       /**
+        * Whether all the GIF data has been supplied, or if there may be
+        * more to come.
+        */
+       bool data_complete;
+
        /** pointer to GIF data */
        const uint8_t *buf;
        /** current index into GIF data */
@@ -613,6 +622,11 @@ static inline nsgif_error nsgif__decode(
                                frame_data, colour_table);
        }
 
+       if (gif->data_complete && ret == NSGIF_ERR_END_OF_DATA) {
+               /* This is all the data there is, so make do. */
+               ret = NSGIF_OK;
+       }
+
        return ret;
 }
 
@@ -1213,16 +1227,19 @@ static nsgif_error nsgif__parse_image_data(
                len--;
 
                while (block_size != 1) {
-                       if (len < 1) return NSGIF_ERR_END_OF_DATA;
+                       if (len < 1) {
+                               return NSGIF_ERR_END_OF_DATA;
+                       }
                        block_size = data[0] + 1;
                        /* Check if the frame data runs off the end of the file 
*/
                        if (block_size > len) {
-                               block_size = len;
+                               frame->lzw_data_length += len;
                                return NSGIF_OK;
                        }
 
                        len -= block_size;
                        data += block_size;
+                       frame->lzw_data_length += block_size;
                }
 
                *pos = data;
@@ -1258,14 +1275,16 @@ static struct nsgif_frame *nsgif__get_frame(
 
                frame = &gif->frames[frame_idx];
 
-               frame->transparency_index = NSGIF_NO_TRANSPARENCY;
-               frame->frame_offset = gif->buf_pos;
                frame->info.local_palette = false;
                frame->info.transparency = false;
-               frame->redraw_required = false;
                frame->info.display = false;
                frame->info.disposal = 0;
                frame->info.delay = 10;
+
+               frame->transparency_index = NSGIF_NO_TRANSPARENCY;
+               frame->frame_offset = gif->buf_pos;
+               frame->redraw_required = false;
+               frame->lzw_data_length = 0;
                frame->decoded = false;
        }
 
@@ -1593,6 +1612,10 @@ nsgif_error nsgif_data_scan(
        nsgif_error ret;
        uint32_t frames;
 
+       if (gif->data_complete) {
+               return NSGIF_ERR_DATA_COMPLETE;
+       }
+
        /* Initialize values */
        gif->buf_len = size;
        gif->buf = data;
@@ -1734,6 +1757,32 @@ nsgif_error nsgif_data_scan(
        return ret;
 }
 
+/* exported function documented in nsgif.h */
+void nsgif_data_complete(
+               nsgif_t *gif)
+{
+       if (gif->data_complete == false) {
+               uint32_t start = gif->info.frame_count;
+               uint32_t end = gif->frame_count_partial;
+
+               for (uint32_t f = start; f < end; f++) {
+                       nsgif_frame *frame = &gif->frames[f];
+
+                       if (frame->lzw_data_length > 0) {
+                               frame->info.display = true;
+                               gif->info.frame_count = f + 1;
+
+                               if (f == 0) {
+                                       frame->info.transparency = true;
+                               }
+                               break;
+                       }
+               }
+       }
+
+       gif->data_complete = true;
+}
+
 static void nsgif__redraw_rect_extend(
                const nsgif_rect_t *frame,
                nsgif_rect_t *redraw)
@@ -1782,7 +1831,11 @@ static nsgif_error nsgif__next_displayable_frame(
 
        do {
                next = nsgif__frame_next(gif, false, next);
-               if (next == *frame || next == NSGIF_FRAME_INVALID) {
+               if (next <= *frame && *frame != NSGIF_FRAME_INVALID &&
+                               gif->data_complete == false) {
+                       return NSGIF_ERR_END_OF_DATA;
+
+               } else if (next == *frame || next == NSGIF_FRAME_INVALID) {
                        return NSGIF_ERR_FRAME_DISPLAY;
                }
 
@@ -1850,21 +1903,26 @@ nsgif_error nsgif_frame_prepare(
                gif->loop_count++;
        }
 
-       if (gif->info.frame_count == 1) {
-               delay = NSGIF_INFINITE;
+       if (gif->data_complete) {
+               /* Check for last frame, which has infinite delay. */
 
-       } else if (gif->info.loop_max != 0) {
-               uint32_t frame_next = frame;
-               ret = nsgif__next_displayable_frame(gif, &frame_next, NULL);
-               if (ret != NSGIF_OK) {
-                       return ret;
-               }
+               if (gif->info.frame_count == 1) {
+                       delay = NSGIF_INFINITE;
+               } else if (gif->info.loop_max != 0) {
+                       uint32_t frame_next = frame;
 
-               if (frame_next < frame) {
-                       if (nsgif__animation_complete(
-                                       gif->loop_count + 1,
-                                       gif->info.loop_max)) {
-                               delay = NSGIF_INFINITE;
+                       ret = nsgif__next_displayable_frame(gif,
+                                       &frame_next, NULL);
+                       if (ret != NSGIF_OK) {
+                               return ret;
+                       }
+
+                       if (gif->data_complete && frame_next < frame) {
+                               if (nsgif__animation_complete(
+                                               gif->loop_count + 1,
+                                               gif->info.loop_max)) {
+                                       delay = NSGIF_INFINITE;
+                               }
                        }
                }
        }
@@ -1986,6 +2044,7 @@ const char *nsgif_strerror(nsgif_error err)
                [NSGIF_ERR_DATA_FRAME]    = "Invalid frame data",
                [NSGIF_ERR_FRAME_COUNT]   = "Excessive number of frames",
                [NSGIF_ERR_END_OF_DATA]   = "Unexpected end of GIF source data",
+               [NSGIF_ERR_DATA_COMPLETE] = "Can't add data to completed GIF",
                [NSGIF_ERR_FRAME_DISPLAY] = "Frame can't be displayed",
                [NSGIF_ERR_ANIMATION_END] = "Animation complete",
        };


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=cb7f357b58c85bc089221060aa57a6c4ea5e9c06
commit cb7f357b58c85bc089221060aa57a6c4ea5e9c06
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>

    GIF: Constify gif structure through next frame getters

diff --git a/src/gif.c b/src/gif.c
index d2b6054..a5c44ee 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -1757,7 +1757,7 @@ static void nsgif__redraw_rect_extend(
 }
 
 static uint32_t nsgif__frame_next(
-               nsgif_t *gif,
+               const nsgif_t *gif,
                bool partial,
                uint32_t frame)
 {
@@ -1774,7 +1774,7 @@ static uint32_t nsgif__frame_next(
 }
 
 static nsgif_error nsgif__next_displayable_frame(
-               nsgif_t *gif,
+               const nsgif_t *gif,
                uint32_t *frame,
                uint32_t *delay)
 {


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

Summary of changes:
 README.md       |   18 ++++++++++
 include/nsgif.h |   29 ++++++++++++++++
 src/gif.c       |  101 +++++++++++++++++++++++++++++++++++++++++++------------
 test/nsgif.c    |    5 +--
 4 files changed, 130 insertions(+), 23 deletions(-)

diff --git a/README.md b/README.md
index e6219aa..5007da9 100644
--- a/README.md
+++ b/README.md
@@ -67,6 +67,10 @@ it has reached the end of the source data.
 > buffer. Just be sure to call `nsgif_data_scan()` again with the new pointer
 > before making any other calls against that nsgif object.
 
+When all the source data has been provided to `nsgif_data_scan()` it is
+advisable to call `nsgif_data_complete()` (see below), although this is not
+necessary to start decoding frames.
+
 To decode the frames, you can call `nsgif_get_info()` to get the frame_count,
 and then call `nsgif_frame_decode()` for each frame, and manage the animation,
 and non-displayable frames yourself, or you can use the helper function,
@@ -122,6 +126,20 @@ on-demand with:
 Note that this will be a no-op if the requested frame already happens to be
 the decoded frame.
 
+You can call `nsgif_frame_prepare()` and `nsgif_frame_decode()` before all
+of the GIF data has been provided using `nsgif_data_scan()` calls. For example
+if you want to make a start decoding and displaying the early frames of the GIF
+before the entire animation file has been downloaded.
+
+When you do this, `nsgif_frame_prepare()` will not loop the animation back to
+the start unless you call `nsgif_data_complete()` to indicate all of the data
+has been fetched. Calling `nsgif_data_complete()` also lets libnsgif display
+any trailing truncated frame.
+
+```c
+       nsgif_data_complete(gif);
+```
+
 Once you are done with the GIF, free up the nsgif object with:
 
 ```c
diff --git a/include/nsgif.h b/include/nsgif.h
index 208bc27..7e6aa83 100644
--- a/include/nsgif.h
+++ b/include/nsgif.h
@@ -90,6 +90,11 @@ typedef enum {
        NSGIF_ERR_END_OF_DATA,
 
        /**
+        * Can't supply more data after calling \ref nsgif_data_complete.
+        */
+       NSGIF_ERR_DATA_COMPLETE,
+
+       /**
         * The current frame cannot be displayed.
         */
        NSGIF_ERR_FRAME_DISPLAY,
@@ -277,6 +282,8 @@ void nsgif_destroy(nsgif_t *gif);
  * several times, as more data is available (e.g. slow network fetch) the data
  * already given to \ref nsgif_data_scan must be provided each time.
  *
+ * Once all the data has been provided, call \ref nsgif_data_complete.
+ *
  * For example, if you call \ref nsgif_data_scan with 25 bytes of data, and 
then
  * fetch another 10 bytes, you would need to call \ref nsgif_data_scan with a
  * size of 35 bytes, and the whole 35 bytes must be contiguous memory. It is
@@ -300,12 +307,34 @@ nsgif_error nsgif_data_scan(
                const uint8_t *data);
 
 /**
+ * Tell libnsgif that all the gif data has been provided.
+ *
+ * Call this after calling \ref nsgif_data_scan with the the entire GIF
+ * source data. You can call \ref nsgif_data_scan multiple times up until
+ * this is called, and after this is called, \ref nsgif_data_scan will
+ * return an error.
+ *
+ * You can decode a GIF before this is called, however, it will fail to
+ * decode any truncated final frame data and will not perform loops when
+ * driven via \ref nsgif_frame_prepare (because it doesn't know if there
+ * will be more frames supplied in future data).
+ *
+ * \param[in]  gif     The \ref nsgif_t object.
+ */
+void nsgif_data_complete(
+               nsgif_t *gif);
+
+/**
  * Prepare to show a frame.
  *
  * If this is the last frame of an animation with a finite loop count, the
  * returned `delay_cs` will be \ref NSGIF_INFINITE, indicating that the frame
  * should be shown forever.
  *
+ * Note that if \ref nsgif_data_complete has not been called on this gif,
+ * animated GIFs will not loop back to the start. Instead it will return
+ * \ref NSGIF_ERR_END_OF_DATA.
+ *
  * \param[in]  gif        The \ref nsgif_t object.
  * \param[out] area       The area in pixels that must be redrawn.
  * \param[out] delay_cs   Time to wait after frame_new before next frame in cs.
diff --git a/src/gif.c b/src/gif.c
index d2b6054..2dc631e 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -40,6 +40,9 @@ typedef struct nsgif_frame {
        /** whether a full image redraw is required */
        bool redraw_required;
 
+       /** Amount of LZW data found in scan */
+       uint32_t lzw_data_length;
+
        /** the index designating a transparent pixel */
        uint32_t transparency_index;
 
@@ -90,6 +93,12 @@ struct nsgif {
        /** number of frames partially decoded */
        uint32_t frame_count_partial;
 
+       /**
+        * Whether all the GIF data has been supplied, or if there may be
+        * more to come.
+        */
+       bool data_complete;
+
        /** pointer to GIF data */
        const uint8_t *buf;
        /** current index into GIF data */
@@ -613,6 +622,11 @@ static inline nsgif_error nsgif__decode(
                                frame_data, colour_table);
        }
 
+       if (gif->data_complete && ret == NSGIF_ERR_END_OF_DATA) {
+               /* This is all the data there is, so make do. */
+               ret = NSGIF_OK;
+       }
+
        return ret;
 }
 
@@ -1213,16 +1227,19 @@ static nsgif_error nsgif__parse_image_data(
                len--;
 
                while (block_size != 1) {
-                       if (len < 1) return NSGIF_ERR_END_OF_DATA;
+                       if (len < 1) {
+                               return NSGIF_ERR_END_OF_DATA;
+                       }
                        block_size = data[0] + 1;
                        /* Check if the frame data runs off the end of the file 
*/
                        if (block_size > len) {
-                               block_size = len;
+                               frame->lzw_data_length += len;
                                return NSGIF_OK;
                        }
 
                        len -= block_size;
                        data += block_size;
+                       frame->lzw_data_length += block_size;
                }
 
                *pos = data;
@@ -1258,14 +1275,16 @@ static struct nsgif_frame *nsgif__get_frame(
 
                frame = &gif->frames[frame_idx];
 
-               frame->transparency_index = NSGIF_NO_TRANSPARENCY;
-               frame->frame_offset = gif->buf_pos;
                frame->info.local_palette = false;
                frame->info.transparency = false;
-               frame->redraw_required = false;
                frame->info.display = false;
                frame->info.disposal = 0;
                frame->info.delay = 10;
+
+               frame->transparency_index = NSGIF_NO_TRANSPARENCY;
+               frame->frame_offset = gif->buf_pos;
+               frame->redraw_required = false;
+               frame->lzw_data_length = 0;
                frame->decoded = false;
        }
 
@@ -1593,6 +1612,10 @@ nsgif_error nsgif_data_scan(
        nsgif_error ret;
        uint32_t frames;
 
+       if (gif->data_complete) {
+               return NSGIF_ERR_DATA_COMPLETE;
+       }
+
        /* Initialize values */
        gif->buf_len = size;
        gif->buf = data;
@@ -1734,6 +1757,32 @@ nsgif_error nsgif_data_scan(
        return ret;
 }
 
+/* exported function documented in nsgif.h */
+void nsgif_data_complete(
+               nsgif_t *gif)
+{
+       if (gif->data_complete == false) {
+               uint32_t start = gif->info.frame_count;
+               uint32_t end = gif->frame_count_partial;
+
+               for (uint32_t f = start; f < end; f++) {
+                       nsgif_frame *frame = &gif->frames[f];
+
+                       if (frame->lzw_data_length > 0) {
+                               frame->info.display = true;
+                               gif->info.frame_count = f + 1;
+
+                               if (f == 0) {
+                                       frame->info.transparency = true;
+                               }
+                               break;
+                       }
+               }
+       }
+
+       gif->data_complete = true;
+}
+
 static void nsgif__redraw_rect_extend(
                const nsgif_rect_t *frame,
                nsgif_rect_t *redraw)
@@ -1757,7 +1806,7 @@ static void nsgif__redraw_rect_extend(
 }
 
 static uint32_t nsgif__frame_next(
-               nsgif_t *gif,
+               const nsgif_t *gif,
                bool partial,
                uint32_t frame)
 {
@@ -1774,7 +1823,7 @@ static uint32_t nsgif__frame_next(
 }
 
 static nsgif_error nsgif__next_displayable_frame(
-               nsgif_t *gif,
+               const nsgif_t *gif,
                uint32_t *frame,
                uint32_t *delay)
 {
@@ -1782,7 +1831,11 @@ static nsgif_error nsgif__next_displayable_frame(
 
        do {
                next = nsgif__frame_next(gif, false, next);
-               if (next == *frame || next == NSGIF_FRAME_INVALID) {
+               if (next <= *frame && *frame != NSGIF_FRAME_INVALID &&
+                               gif->data_complete == false) {
+                       return NSGIF_ERR_END_OF_DATA;
+
+               } else if (next == *frame || next == NSGIF_FRAME_INVALID) {
                        return NSGIF_ERR_FRAME_DISPLAY;
                }
 
@@ -1850,21 +1903,26 @@ nsgif_error nsgif_frame_prepare(
                gif->loop_count++;
        }
 
-       if (gif->info.frame_count == 1) {
-               delay = NSGIF_INFINITE;
+       if (gif->data_complete) {
+               /* Check for last frame, which has infinite delay. */
 
-       } else if (gif->info.loop_max != 0) {
-               uint32_t frame_next = frame;
-               ret = nsgif__next_displayable_frame(gif, &frame_next, NULL);
-               if (ret != NSGIF_OK) {
-                       return ret;
-               }
+               if (gif->info.frame_count == 1) {
+                       delay = NSGIF_INFINITE;
+               } else if (gif->info.loop_max != 0) {
+                       uint32_t frame_next = frame;
 
-               if (frame_next < frame) {
-                       if (nsgif__animation_complete(
-                                       gif->loop_count + 1,
-                                       gif->info.loop_max)) {
-                               delay = NSGIF_INFINITE;
+                       ret = nsgif__next_displayable_frame(gif,
+                                       &frame_next, NULL);
+                       if (ret != NSGIF_OK) {
+                               return ret;
+                       }
+
+                       if (gif->data_complete && frame_next < frame) {
+                               if (nsgif__animation_complete(
+                                               gif->loop_count + 1,
+                                               gif->info.loop_max)) {
+                                       delay = NSGIF_INFINITE;
+                               }
                        }
                }
        }
@@ -1986,6 +2044,7 @@ const char *nsgif_strerror(nsgif_error err)
                [NSGIF_ERR_DATA_FRAME]    = "Invalid frame data",
                [NSGIF_ERR_FRAME_COUNT]   = "Excessive number of frames",
                [NSGIF_ERR_END_OF_DATA]   = "Unexpected end of GIF source data",
+               [NSGIF_ERR_DATA_COMPLETE] = "Can't add data to completed GIF",
                [NSGIF_ERR_FRAME_DISPLAY] = "Frame can't be displayed",
                [NSGIF_ERR_ANIMATION_END] = "Animation complete",
        };
diff --git a/test/nsgif.c b/test/nsgif.c
index 4a9e31c..7d61504 100644
--- a/test/nsgif.c
+++ b/test/nsgif.c
@@ -137,8 +137,7 @@ static uint8_t *load_file(const char *path, size_t 
*data_size)
 
 static void warning(const char *context, nsgif_error err)
 {
-       fprintf(stderr, "%s failed: %s\n",
-                       context, nsgif_strerror(err));
+       fprintf(stderr, "%s: %s\n", context, nsgif_strerror(err));
 }
 
 static void print_gif_info(const nsgif_info_t *info)
@@ -385,6 +384,8 @@ int main(int argc, char *argv[])
                warning("nsgif_data_scan", err);
        }
 
+       nsgif_data_complete(gif);
+
        if (nsgif_options.loops == 0) {
                nsgif_options.loops = 1;
        }


-- 
NetSurf GIF Decoder
_______________________________________________
netsurf-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to