Gitweb links:

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

The branch, master has been updated
       via  6d39a8f70009c43032d96da8ceb8934e6e67a159 (commit)
       via  696b29ffeb71d77f9ede7dd19408cf713923684a (commit)
       via  152c4a7429d9364ab163997dd6304665f5baa2e5 (commit)
      from  3832f7edc4cd117642ad7890eb1476d1f9d8e918 (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=6d39a8f70009c43032d96da8ceb8934e6e67a159
commit 6d39a8f70009c43032d96da8ceb8934e6e67a159
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    gif: Frame parse: Only grow image to accommodate first frame.
    
    This matches the behaviour of other browsers.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 2b53492..25f98c6 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -877,9 +877,15 @@ static gif_result gif__parse_image_descriptor(
                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;
+               /* Allow first frame to grow image dimensions. */
+               if (gif->frame_count == 0) {
+                       if (x + w > gif->width) {
+                               gif->width = x + w;
+                       }
+                       if (y + h > gif->height) {
+                               gif->height = y + h;
+                       }
+               }
        }
 
        *pos += GIF_IMAGE_DESCRIPTOR_LEN;


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

    gif: Background restoration: Add support for clipped frames.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index 2a5ff8d..2b53492 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -549,7 +549,10 @@ static void gif__restore_bg(
                uint32_t width = frame->redraw_width;
                uint32_t height = frame->redraw_height;
 
-               if (frame->display == false) {
+               width -= gif__clip(offset_x, width, gif->width);
+               height -= gif__clip(offset_y, height, gif->height);
+
+               if (frame->display == false || width == 0) {
                        return;
                }
 


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

    gif: decode: Add support for clipped frames.

diff --git a/src/libnsgif.c b/src/libnsgif.c
index ecddf78..2a5ff8d 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -300,6 +300,48 @@ static inline bool gif__next_row(uint32_t interlace,
        }
 }
 
+/**
+ * Get any frame clip adjustment for the image extent.
+ *
+ * \param[in]  frame_off  Frame's X or Y offset.
+ * \param[in]  frame_dim  Frame width or height.
+ * \param[in]  image_ext  Image width or height constraint.
+ * \return the amount the frame needs to be clipped to fit the image in given
+ *         dimension.
+ */
+static inline uint32_t gif__clip(
+               uint32_t frame_off,
+               uint32_t frame_dim,
+               uint32_t image_ext)
+{
+       uint32_t frame_ext = frame_off + frame_dim;
+
+       if (frame_ext <= image_ext) {
+               return 0;
+       }
+
+       return frame_ext - image_ext;
+}
+
+/**
+ * Perform any jump over decoded data, to accommodate clipped portion of frame.
+ *
+ * \param[in,out] skip       Number of pixels of data to jump.
+ * \param[in,out] available  Number of pixels of data currently available.
+ * \param[in,out] pos        Position in decoded pixel value data.
+ */
+static inline void gif__jump_data(
+               uint32_t *skip,
+               uint32_t *available,
+               const uint8_t **pos)
+{
+       uint32_t jump = (*skip < *available) ? *skip : *available;
+
+       *skip -= jump;
+       *available -= jump;
+       *pos += jump;
+}
+
 static gif_result gif__decode_complex(
                struct gif_animation *gif,
                uint32_t width,
@@ -313,12 +355,24 @@ static gif_result gif__decode_complex(
                uint32_t *restrict colour_table)
 {
        lzw_result res;
+       uint32_t clip_x = gif__clip(offset_x, width, gif->width);
+       uint32_t clip_y = gif__clip(offset_y, height, gif->height);
+       const uint8_t *uncompressed;
        gif_result ret = GIF_OK;
        uint32_t available = 0;
        uint8_t step = 24;
+       uint32_t skip = 0;
        uint32_t y = 0;
 
-       if (height == 0) {
+       if (offset_x >= gif->width ||
+           offset_y >= gif->height) {
+               return GIF_OK;
+       }
+
+       width -= clip_x;
+       height -= clip_y;
+
+       if (width == 0 || height == 0) {
                return GIF_OK;
        }
 
@@ -339,9 +393,8 @@ static gif_result gif__decode_complex(
 
                x = width;
                while (x > 0) {
-                       const uint8_t *uncompressed;
                        unsigned row_available;
-                       if (available == 0) {
+                       while (available == 0) {
                                if (res != LZW_OK) {
                                        /* Unexpected end of frame, try to 
recover */
                                        if (res == LZW_OK_EOD) {
@@ -349,10 +402,15 @@ static gif_result gif__decode_complex(
                                        } else {
                                                ret = gif__error_from_lzw(res);
                                        }
-                                       break;
+                                       return ret;
                                }
                                res = lzw_decode(gif->lzw_ctx,
                                                &uncompressed, &available);
+
+                               if (available == 0) {
+                                       return GIF_OK;
+                               }
+                               gif__jump_data(&skip, &available, 
&uncompressed);
                        }
 
                        row_available = x < available ? x : available;
@@ -375,6 +433,9 @@ static gif_result gif__decode_complex(
                                }
                        }
                }
+
+               skip = clip_x;
+               gif__jump_data(&skip, &available, &uncompressed);
        } while (gif__next_row(interlace, height, &y, &step));
 
        return ret;
@@ -394,6 +455,16 @@ static gif_result gif__decode_simple(
        gif_result ret = GIF_OK;
        lzw_result res;
 
+       if (offset_y >= gif->height) {
+               return GIF_OK;
+       }
+
+       height -= gif__clip(offset_y, height, gif->height);
+
+       if (height == 0) {
+               return GIF_OK;
+       }
+
        /* Initialise the LZW decoding */
        res = lzw_decode_init_map(gif->lzw_ctx, data[0],
                        transparency_index, colour_table,


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

Summary of changes:
 src/libnsgif.c |   96 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 88 insertions(+), 8 deletions(-)

diff --git a/src/libnsgif.c b/src/libnsgif.c
index ecddf78..25f98c6 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -300,6 +300,48 @@ static inline bool gif__next_row(uint32_t interlace,
        }
 }
 
+/**
+ * Get any frame clip adjustment for the image extent.
+ *
+ * \param[in]  frame_off  Frame's X or Y offset.
+ * \param[in]  frame_dim  Frame width or height.
+ * \param[in]  image_ext  Image width or height constraint.
+ * \return the amount the frame needs to be clipped to fit the image in given
+ *         dimension.
+ */
+static inline uint32_t gif__clip(
+               uint32_t frame_off,
+               uint32_t frame_dim,
+               uint32_t image_ext)
+{
+       uint32_t frame_ext = frame_off + frame_dim;
+
+       if (frame_ext <= image_ext) {
+               return 0;
+       }
+
+       return frame_ext - image_ext;
+}
+
+/**
+ * Perform any jump over decoded data, to accommodate clipped portion of frame.
+ *
+ * \param[in,out] skip       Number of pixels of data to jump.
+ * \param[in,out] available  Number of pixels of data currently available.
+ * \param[in,out] pos        Position in decoded pixel value data.
+ */
+static inline void gif__jump_data(
+               uint32_t *skip,
+               uint32_t *available,
+               const uint8_t **pos)
+{
+       uint32_t jump = (*skip < *available) ? *skip : *available;
+
+       *skip -= jump;
+       *available -= jump;
+       *pos += jump;
+}
+
 static gif_result gif__decode_complex(
                struct gif_animation *gif,
                uint32_t width,
@@ -313,12 +355,24 @@ static gif_result gif__decode_complex(
                uint32_t *restrict colour_table)
 {
        lzw_result res;
+       uint32_t clip_x = gif__clip(offset_x, width, gif->width);
+       uint32_t clip_y = gif__clip(offset_y, height, gif->height);
+       const uint8_t *uncompressed;
        gif_result ret = GIF_OK;
        uint32_t available = 0;
        uint8_t step = 24;
+       uint32_t skip = 0;
        uint32_t y = 0;
 
-       if (height == 0) {
+       if (offset_x >= gif->width ||
+           offset_y >= gif->height) {
+               return GIF_OK;
+       }
+
+       width -= clip_x;
+       height -= clip_y;
+
+       if (width == 0 || height == 0) {
                return GIF_OK;
        }
 
@@ -339,9 +393,8 @@ static gif_result gif__decode_complex(
 
                x = width;
                while (x > 0) {
-                       const uint8_t *uncompressed;
                        unsigned row_available;
-                       if (available == 0) {
+                       while (available == 0) {
                                if (res != LZW_OK) {
                                        /* Unexpected end of frame, try to 
recover */
                                        if (res == LZW_OK_EOD) {
@@ -349,10 +402,15 @@ static gif_result gif__decode_complex(
                                        } else {
                                                ret = gif__error_from_lzw(res);
                                        }
-                                       break;
+                                       return ret;
                                }
                                res = lzw_decode(gif->lzw_ctx,
                                                &uncompressed, &available);
+
+                               if (available == 0) {
+                                       return GIF_OK;
+                               }
+                               gif__jump_data(&skip, &available, 
&uncompressed);
                        }
 
                        row_available = x < available ? x : available;
@@ -375,6 +433,9 @@ static gif_result gif__decode_complex(
                                }
                        }
                }
+
+               skip = clip_x;
+               gif__jump_data(&skip, &available, &uncompressed);
        } while (gif__next_row(interlace, height, &y, &step));
 
        return ret;
@@ -394,6 +455,16 @@ static gif_result gif__decode_simple(
        gif_result ret = GIF_OK;
        lzw_result res;
 
+       if (offset_y >= gif->height) {
+               return GIF_OK;
+       }
+
+       height -= gif__clip(offset_y, height, gif->height);
+
+       if (height == 0) {
+               return GIF_OK;
+       }
+
        /* Initialise the LZW decoding */
        res = lzw_decode_init_map(gif->lzw_ctx, data[0],
                        transparency_index, colour_table,
@@ -478,7 +549,10 @@ static void gif__restore_bg(
                uint32_t width = frame->redraw_width;
                uint32_t height = frame->redraw_height;
 
-               if (frame->display == false) {
+               width -= gif__clip(offset_x, width, gif->width);
+               height -= gif__clip(offset_y, height, gif->height);
+
+               if (frame->display == false || width == 0) {
                        return;
                }
 
@@ -803,9 +877,15 @@ static gif_result gif__parse_image_descriptor(
                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;
+               /* Allow first frame to grow image dimensions. */
+               if (gif->frame_count == 0) {
+                       if (x + w > gif->width) {
+                               gif->width = x + w;
+                       }
+                       if (y + h > gif->height) {
+                               gif->height = y + h;
+                       }
+               }
        }
 
        *pos += GIF_IMAGE_DESCRIPTOR_LEN;


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