summaryrefslogtreecommitdiff
path: root/gdk-pixbuf
diff options
context:
space:
mode:
authorRobert Ancell <robert.ancell@canonical.com>2018-12-04 16:51:36 +1300
committerRobert Ancell <robert.ancell@canonical.com>2019-01-16 15:47:09 +1300
commitb9b12bfd5c6f8394cc9a4a548bd6dc0f5fb2f70b (patch)
treedfd082ef8439c313cf44dacaa5d740f150534b61 /gdk-pixbuf
parent06afde5c45b58dd20a366d3dcb85d7e6fd702096 (diff)
downloadgdk-pixbuf-b9b12bfd5c6f8394cc9a4a548bd6dc0f5fb2f70b.tar.gz
gif: Fix multiple LZW clear codes breaking decoding
The following was occurring: 1. A clear code is detected in the LZW stream 2. The first code is detected as a clear. 3. The following code is returned as a color index, this breaks if it is a clear. There were two codepaths in use, one for handling the first clear in the LZW sequence and another for handling clears within the sequence. The former handled sequential clears correctly, the latter did not. The solution is to the correct codepath and remove the other one. This simplification should not affect other decoding (as confirmed by the test suite).
Diffstat (limited to 'gdk-pixbuf')
-rw-r--r--gdk-pixbuf/io-gif.c40
1 files changed, 1 insertions, 39 deletions
diff --git a/gdk-pixbuf/io-gif.c b/gdk-pixbuf/io-gif.c
index 3986635bc..244d8788f 100644
--- a/gdk-pixbuf/io-gif.c
+++ b/gdk-pixbuf/io-gif.c
@@ -86,7 +86,6 @@ enum {
GIF_GET_COLORMAP2,
GIF_PREPARE_LZW,
GIF_LZW_FILL_BUFFER,
- GIF_LZW_CLEAR_CODE,
GIF_GET_LZW,
GIF_DONE
};
@@ -162,7 +161,6 @@ struct _GifContext
int code_lastbit;
int code_done;
int code_last_byte;
- int lzw_code_pending;
/* lzw context */
gint lzw_fresh;
@@ -554,29 +552,6 @@ get_code (GifContext *context,
return ret;
}
-
-static void
-set_gif_lzw_clear_code (GifContext *context)
-{
- context->state = GIF_LZW_CLEAR_CODE;
- context->lzw_code_pending = -1;
-}
-
-static int
-gif_lzw_clear_code (GifContext *context)
-{
- gint code;
-
- code = get_code (context, context->lzw_code_size);
- if (code == -3)
- return -0;
-
- context->lzw_firstcode = context->lzw_oldcode = code;
- context->lzw_code_pending = code;
- context->state = GIF_GET_LZW;
- return 0;
-}
-
#define CHECK_LZW_SP() G_STMT_START { \
if ((guchar *)context->lzw_sp >= \
(guchar *)context->lzw_stack + sizeof (context->lzw_stack)) { \
@@ -596,12 +571,6 @@ lzw_read_byte (GifContext *context)
gint my_retval;
register int i;
- if (context->lzw_code_pending != -1) {
- retval = context->lzw_code_pending;
- context->lzw_code_pending = -1;
- return retval;
- }
-
if (context->lzw_fresh) {
context->lzw_fresh = FALSE;
do {
@@ -632,8 +601,7 @@ lzw_read_byte (GifContext *context)
context->lzw_max_code_size = 2 * context->lzw_clear_code;
context->lzw_max_code = context->lzw_clear_code + 2;
context->lzw_sp = context->lzw_stack;
-
- set_gif_lzw_clear_code (context);
+ context->lzw_fresh = TRUE;
return -3;
} else if (code == context->lzw_end_code) {
int count;
@@ -1136,7 +1104,6 @@ static void
gif_set_prepare_lzw (GifContext *context)
{
context->state = GIF_PREPARE_LZW;
- context->lzw_code_pending = -1;
}
static int
gif_prepare_lzw (GifContext *context)
@@ -1444,11 +1411,6 @@ gif_main_loop (GifContext *context)
retval = gif_lzw_fill_buffer (context);
break;
- case GIF_LZW_CLEAR_CODE:
- LOG("clear_code\n");
- retval = gif_lzw_clear_code (context);
- break;
-
case GIF_GET_LZW:
LOG("get_lzw\n");
retval = gif_get_lzw (context);