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