summaryrefslogtreecommitdiff
path: root/src/libnsgif.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnsgif.c')
-rw-r--r--src/libnsgif.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/src/libnsgif.c b/src/libnsgif.c
index ed394a2..3b070b3 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -637,17 +637,19 @@ gif__decode(gif_animation *gif,
{
const uint8_t *stack_base;
const uint8_t *stack_pos;
+ uint32_t written = 0;
gif_result ret = GIF_OK;
lzw_result res;
/* Initialise the LZW decoding */
res = lzw_decode_init(gif->lzw_ctx, gif->gif_data,
gif->buffer_size, gif->buffer_position,
- minimum_code_size, &stack_base, &stack_pos);
+ minimum_code_size, &stack_base);
if (res != LZW_OK) {
return gif_error_from_lzw(res);
}
+ stack_pos = stack_base;
for (unsigned int y = 0; y < height; y++) {
unsigned int x;
unsigned int decode_y;
@@ -660,21 +662,18 @@ gif__decode(gif_animation *gif,
}
frame_scanline = frame_data + offset_x + (decode_y * gif->width);
- /* Rather than decoding pixel by pixel, we try to burst
- * out streams of data to remove the need for end-of
- * data checks every pixel.
- */
x = width;
while (x > 0) {
- unsigned int burst_bytes = (stack_pos - stack_base);
- if (burst_bytes > 0) {
+ if (written > 0) {
+ unsigned burst_bytes = written;
if (burst_bytes > x) {
burst_bytes = x;
}
x -= burst_bytes;
+ written -= burst_bytes;
while (burst_bytes-- > 0) {
register unsigned char colour;
- colour = *--stack_pos;
+ colour = *stack_pos++;
if (((gif->frames[frame].transparency) &&
(colour != gif->frames[frame].transparency_index)) ||
(!gif->frames[frame].transparency)) {
@@ -683,7 +682,7 @@ gif__decode(gif_animation *gif,
frame_scanline++;
}
} else {
- res = lzw_decode(gif->lzw_ctx, &stack_pos);
+ res = lzw_decode(gif->lzw_ctx, &written);
if (res != LZW_OK) {
/* Unexpected end of frame, try to recover */
if (res == LZW_OK_EOD) {
@@ -693,10 +692,10 @@ gif__decode(gif_animation *gif,
}
break;
}
+ stack_pos = stack_base;
}
}
}
-
return ret;
}