Update libnsgif from upstream (#2674)
* libnsgif: Remove patch artifact. * libnsgif: Update from upstream.
This commit is contained in:
parent
49cae56e1e
commit
b05515b0c5
@ -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
Loading…
Reference in New Issue
Block a user