Update libnsgif from upstream (#2674)

* libnsgif: Remove patch artifact.

* libnsgif: Update from upstream.
This commit is contained in:
Michael Drake 2022-02-21 20:07:20 +00:00 committed by GitHub
parent 49cae56e1e
commit b05515b0c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 1389 deletions

View File

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

File diff suppressed because it is too large Load Diff