new state. Fixes un-compressed gifs.

1999-11-03  Jonathan Blandford  <jrb@redhat.com>

	* src/io-gif.c (set_gif_lzw_clear_code): new state.  Fixes
	un-compressed gifs.

	* src/gnome-canvas-pixbuf.c (recompute_bounding_box): remove
	unneeded x,y,h,w vars.
This commit is contained in:
Jonathan Blandford 1999-11-03 21:22:38 +00:00 committed by Jonathan Blandford
parent d0e4efb401
commit 87a9022b72
3 changed files with 81 additions and 82 deletions

View File

@ -1,3 +1,11 @@
1999-11-03 Jonathan Blandford <jrb@redhat.com>
* src/io-gif.c (set_gif_lzw_clear_code): new state. Fixes
un-compressed gifs.
* src/gnome-canvas-pixbuf.c (recompute_bounding_box): remove
unneeded x,y,h,w vars.
1999-11-03 Larry Ewing <lewing@gimp.org> 1999-11-03 Larry Ewing <lewing@gimp.org>
* src/gnome-canvas-pixbuf.c (compute_render_affine): adjust * src/gnome-canvas-pixbuf.c (compute_render_affine): adjust

View File

@ -558,8 +558,6 @@ recompute_bounding_box (GnomeCanvasPixbuf *gcp)
GnomeCanvasItem *item; GnomeCanvasItem *item;
PixbufPrivate *priv; PixbufPrivate *priv;
double i2c[6], render_affine[6]; double i2c[6], render_affine[6];
double w, h;
double x, y;
ArtDRect rect; ArtDRect rect;

View File

@ -54,7 +54,7 @@ typedef unsigned char CMap[3][MAXCOLORMAPSIZE];
/* Possible states we can be in. */ /* Possible states we can be in. */
enum { enum {
GIF_START = 1, GIF_START,
GIF_GET_COLORMAP, GIF_GET_COLORMAP,
GIF_GET_NEXT_STEP, GIF_GET_NEXT_STEP,
GIF_GET_FRAME_INFO, GIF_GET_FRAME_INFO,
@ -62,6 +62,7 @@ enum {
GIF_GET_COLORMAP2, GIF_GET_COLORMAP2,
GIF_PREPARE_LZW, GIF_PREPARE_LZW,
GIF_LZW_FILL_BUFFER, GIF_LZW_FILL_BUFFER,
GIF_LZW_CLEAR_CODE,
GIF_GET_LZW, GIF_GET_LZW,
GIF_DONE, GIF_DONE,
}; };
@ -121,12 +122,14 @@ struct _GifContext
guchar block_buf[280]; guchar block_buf[280];
gint block_ptr; gint block_ptr;
int old_state; /* used by lzw_fill buffer */
/* get_code context */ /* get_code context */
int code_curbit; int code_curbit;
int code_lastbit; int code_lastbit;
int code_done; int code_done;
int code_last_byte; int code_last_byte;
int lzw_code_pending;
/* lzw context */ /* lzw context */
gint lzw_fresh; gint lzw_fresh;
gint lzw_code_size; gint lzw_code_size;
@ -149,9 +152,7 @@ struct _GifContext
}; };
static int GetDataBlock (GifContext *, unsigned char *); static int GetDataBlock (GifContext *, unsigned char *);
static int GetCode (GifContext *, int);
#define IO_GIFDEBUG
static int count = 0; static int count = 0;
/* Returns TRUE if Read is OK, /* Returns TRUE if Read is OK,
@ -333,7 +334,7 @@ gif_get_extension (GifContext *context)
else else
context->gif89.transparent = -1; context->gif89.transparent = -1;
} }
/* Now we've successfully loaded this one, we continue on our way */ /* Now we've successfully loaded this one, we continue on our way */
context->block_count = 0; context->block_count = 0;
context->extension_flag = FALSE; context->extension_flag = FALSE;
@ -376,51 +377,12 @@ GetDataBlock (GifContext *context,
return context->block_count; return context->block_count;
} }
#if 0
static int
GetCode (GifContext *context,
int code_size)
{
int i, j, ret;
unsigned char count;
if ((context->code_curbit + code_size) >= context->code_lastbit){
if (context->code_done) {
if (context->code_curbit >= context->code_lastbit) {
/*g_message (_("GIF: ran off the end of by bits\n"));*/
return -2;
}
return -2;
}
context->block_buf[0] = context->block_buf[context->code_last_byte - 2];
context->block_buf[1] = context->block_buf[context->code_last_byte - 1];
context->block_count = 0;
if ((count = GetDataBlock (context, &context->block_buf[2])) == 0)
context->code_done = TRUE;
context->code_last_byte = 2 + count;
context->code_curbit = (context->code_curbit - context->code_lastbit) + 16;
context->code_lastbit = (2 + count) * 8;
}
ret = 0;
for (i = context->code_curbit, j = 0; j < code_size; ++i, ++j)
ret |= ((context->block_buf[i / 8] & (1 << (i % 8))) != 0) << j;
context->code_curbit += code_size;
return ret;
}
#endif
static void static void
gif_set_lzw_fill_buffer (GifContext *context) gif_set_lzw_fill_buffer (GifContext *context)
{ {
context->block_count = 0; context->block_count = 0;
context->old_state = context->state;
context->state = GIF_LZW_FILL_BUFFER; context->state = GIF_LZW_FILL_BUFFER;
} }
@ -428,7 +390,7 @@ static int
gif_lzw_fill_buffer (GifContext *context) gif_lzw_fill_buffer (GifContext *context)
{ {
gint retval; gint retval;
if (context->code_done) { if (context->code_done) {
if (context->code_curbit >= context->code_lastbit) { if (context->code_curbit >= context->code_lastbit) {
g_message ("GIF: ran off the end of by bits\n"); g_message ("GIF: ran off the end of by bits\n");
@ -453,13 +415,13 @@ gif_lzw_fill_buffer (GifContext *context)
context->code_curbit = (context->code_curbit - context->code_lastbit) + 16; context->code_curbit = (context->code_curbit - context->code_lastbit) + 16;
context->code_lastbit = (2 + context->block_count) * 8; context->code_lastbit = (2 + context->block_count) * 8;
context->state = GIF_GET_LZW; context->state = context->old_state;
return 0; return 0;
} }
static int static int
GetCode (GifContext *context, get_code (GifContext *context,
int code_size) int code_size)
{ {
int i, j, ret; int i, j, ret;
@ -477,39 +439,62 @@ GetCode (GifContext *context,
return ret; return ret;
} }
/*
* For various reasons, this one is a little different from the others: static void
* set_gif_lzw_clear_code (GifContext *context)
* returns -1 if it needs more bytes. {
* returns -2 if there's an error. context->state = GIF_LZW_CLEAR_CODE;
* returns -3 if there is no error, but needs to go back to the main loop. context->lzw_code_pending = -1;
* returns the byte otherwise. }
*/
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;
}
static int static int
lzw_read_byte (GifContext *context) lzw_read_byte (GifContext *context)
{ {
int code, incode; int code, incode;
gint retval; gint retval;
gint my_retval;
register int i; 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) { if (context->lzw_fresh) {
context->lzw_fresh = FALSE; context->lzw_fresh = FALSE;
do { do {
retval = GetCode (context, context->lzw_code_size); retval = get_code (context, context->lzw_code_size);
if (retval < 0) { if (retval < 0) {
return retval; return retval;
} }
context->lzw_firstcode = context->lzw_oldcode = retval; context->lzw_firstcode = context->lzw_oldcode = retval;
} while (context->lzw_firstcode == context->lzw_clear_code); } while (context->lzw_firstcode == context->lzw_clear_code);
return context->lzw_firstcode; return context->lzw_firstcode;
} }
if (context->lzw_sp > context->lzw_stack) if (context->lzw_sp > context->lzw_stack) {
return *--(context->lzw_sp); my_retval = *--(context->lzw_sp);
return my_retval;
}
while ((code = GetCode (context, context->lzw_code_size)) >= 0) { while ((code = get_code (context, context->lzw_code_size)) >= 0) {
if (code == context->lzw_clear_code) { if (code == context->lzw_clear_code) {
for (i = 0; i < context->lzw_clear_code; ++i) { for (i = 0; i < context->lzw_clear_code; ++i) {
context->lzw_table[0][i] = 0; context->lzw_table[0][i] = 0;
@ -521,25 +506,27 @@ lzw_read_byte (GifContext *context)
context->lzw_max_code_size = 2 * context->lzw_clear_code; context->lzw_max_code_size = 2 * context->lzw_clear_code;
context->lzw_max_code = context->lzw_clear_code + 2; context->lzw_max_code = context->lzw_clear_code + 2;
context->lzw_sp = context->lzw_stack; context->lzw_sp = context->lzw_stack;
context->lzw_firstcode = context->lzw_oldcode =
GetCode (context, context->lzw_code_size); set_gif_lzw_clear_code (context);
return context->lzw_firstcode; return -3;
} else if (code == context->lzw_end_code) { } else if (code == context->lzw_end_code) {
int count; int count;
unsigned char buf[260]; unsigned char buf[260];
/*g_error (" DID WE EVER EVER GET HERE\n");*/ /*g_error (" DID WE EVER EVER GET HERE\n");*/
g_warning ("unhandled case. This won't load correctly\n"); g_error ("Unhandled Case. If you have an image that causes this, let me <jrb@redhat.com> know.\n");
if (ZeroDataBlock) if (ZeroDataBlock) {
return -2; return -2;
}
while ((count = GetDataBlock (context, buf)) > 0) while ((count = GetDataBlock (context, buf)) > 0)
; ;
if (count != 0) if (count != 0) {
/*g_print (_("GIF: missing EOD in data stream (common occurence)"));*/ /*g_print (_("GIF: missing EOD in data stream (common occurence)"));*/
return -2; return -2;
}
} }
incode = code; incode = code;
@ -551,6 +538,7 @@ lzw_read_byte (GifContext *context)
while (code >= context->lzw_clear_code) { while (code >= context->lzw_clear_code) {
*(context->lzw_sp)++ = context->lzw_table[1][code]; *(context->lzw_sp)++ = context->lzw_table[1][code];
if (code == context->lzw_table[0][code]) { if (code == context->lzw_table[0][code]) {
/*g_message (_("GIF: circular table entry BIG ERROR\n"));*/ /*g_message (_("GIF: circular table entry BIG ERROR\n"));*/
/*gimp_quit ();*/ /*gimp_quit ();*/
@ -574,13 +562,14 @@ lzw_read_byte (GifContext *context)
context->lzw_oldcode = incode; context->lzw_oldcode = incode;
if (context->lzw_sp > context->lzw_stack) if (context->lzw_sp > context->lzw_stack) {
return *--(context->lzw_sp); my_retval = *--(context->lzw_sp);
return my_retval;
}
} }
return code; return code;
} }
static void static void
gif_set_get_lzw (GifContext *context) gif_set_get_lzw (GifContext *context)
{ {
@ -646,7 +635,7 @@ gif_get_lzw (GifContext *context)
guchar *dest, *temp; guchar *dest, *temp;
gint v; gint v;
if (context->pixbuf == NULL) { if (context->pixbuf == NULL) {
context->pixbuf = gdk_pixbuf_new (ART_PIX_RGB, context->pixbuf = gdk_pixbuf_new (ART_PIX_RGB,
context->gif89.transparent, context->gif89.transparent,
@ -664,7 +653,7 @@ gif_get_lzw (GifContext *context)
if (v < 0) { if (v < 0) {
return v; return v;
} }
if (context->gif89.transparent) { if (context->gif89.transparent) {
temp = dest + context->draw_ypos * gdk_pixbuf_get_rowstride (context->pixbuf) + context->draw_xpos * 4; temp = dest + context->draw_ypos * gdk_pixbuf_get_rowstride (context->pixbuf) + context->draw_xpos * 4;
@ -681,7 +670,7 @@ gif_get_lzw (GifContext *context)
if (context->func && context->frame_interlace) if (context->func && context->frame_interlace)
gif_fill_in_lines (context, dest, v); gif_fill_in_lines (context, dest, v);
context->draw_xpos++; context->draw_xpos++;
if (context->draw_xpos == context->frame_len) { if (context->draw_xpos == context->frame_len) {
context->draw_xpos = 0; context->draw_xpos = 0;
@ -732,6 +721,7 @@ static void
gif_set_prepare_lzw (GifContext *context) gif_set_prepare_lzw (GifContext *context)
{ {
context->state = GIF_PREPARE_LZW; context->state = GIF_PREPARE_LZW;
context->lzw_code_pending = -1;
} }
static int static int
gif_prepare_lzw (GifContext *context) gif_prepare_lzw (GifContext *context)
@ -848,9 +838,8 @@ gif_get_frame_info (GifContext *context)
} }
gif_set_prepare_lzw (context); gif_set_prepare_lzw (context);
return 0; return 0;
}
}
static gint static gint
gif_get_next_step (GifContext *context) gif_get_next_step (GifContext *context)
@ -879,7 +868,7 @@ gif_get_next_step (GifContext *context)
/* Not a valid start character */ /* Not a valid start character */
continue; continue;
} }
/* assume it's frame info */ /* load the frame */
gif_set_get_frame_info (context); gif_set_get_frame_info (context);
return 0; return 0;
} }
@ -930,7 +919,11 @@ gif_main_loop (GifContext *context)
case GIF_LZW_FILL_BUFFER: case GIF_LZW_FILL_BUFFER:
retval = gif_lzw_fill_buffer (context); retval = gif_lzw_fill_buffer (context);
break; break;
case GIF_LZW_CLEAR_CODE:
retval = gif_lzw_clear_code (context);
break;
case GIF_GET_LZW: case GIF_GET_LZW:
retval = gif_get_lzw (context); retval = gif_get_lzw (context);
break; break;