\f
-#include <config.h>
+#include "config.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
unsigned int global_bit_pixel;
unsigned int global_color_resolution;
unsigned int background_index;
+ gboolean stop_after_first_frame;
gboolean frame_cmap_active;
CMap frame_color_map;
#endif
retval = (fread(buffer, len, 1, context->file) != 0);
- if (!retval && ferror (context->file))
+ if (!retval && ferror (context->file)) {
+ gint save_errno = errno;
g_set_error (context->error,
G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Failure reading GIF: %s"), strerror (errno));
+ g_file_error_from_errno (save_errno),
+ _("Failure reading GIF: %s"),
+ g_strerror (save_errno));
+ }
#ifdef IO_GIFDEBUG
if (len < 100) {
retval = get_data_block (context, (unsigned char *) context->block_buf, NULL);
if (retval != 0)
return retval;
- if (!strncmp (context->block_buf, "NETSCAPE2.0", 11) ||
- !strncmp (context->block_buf, "ANIMEXTS1.0", 11)) {
+ if (!strncmp ((gchar *)context->block_buf, "NETSCAPE2.0", 11) ||
+ !strncmp ((gchar *)context->block_buf, "ANIMEXTS1.0", 11)) {
context->in_loop_extension = TRUE;
}
context->block_count = 0;
if (context->code_done) {
if (context->code_curbit >= context->code_lastbit) {
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("GIF file was missing some data (perhaps it was truncated somehow?)"));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+ _("GIF file was missing some data (perhaps it was truncated somehow?)"));
return -2;
}
#define CHECK_LZW_SP() G_STMT_START { \
if ((guchar *)context->lzw_sp >= \
(guchar *)context->lzw_stack + sizeof (context->lzw_stack)) { \
- g_set_error (context->error, \
- GDK_PIXBUF_ERROR, \
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE, \
- _("Stack overflow")); \
+ g_set_error_literal (context->error, \
+ GDK_PIXBUF_ERROR, \
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE, \
+ _("Stack overflow")); \
return -2; \
} \
} G_STMT_END
unsigned char buf[260];
/* FIXME - we should handle this case */
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_FAILED,
- _("GIF image loader cannot understand this image."));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_FAILED,
+ _("GIF image loader cannot understand this image."));
return -2;
if (ZeroDataBlock) {
while (code >= context->lzw_clear_code) {
if (code >= (1 << MAX_LZW_BITS)) {
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("Bad code encountered"));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+ _("Bad code encountered"));
return -2;
}
CHECK_LZW_SP ();
*(context->lzw_sp)++ = context->lzw_table[1][code];
if (code == context->lzw_table[0][code]) {
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("Circular table entry in GIF file"));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+ _("Circular table entry in GIF file"));
return -2;
}
code = context->lzw_table[0][code];
context->frame_height);
if (!context->frame->pixbuf) {
g_free (context->frame);
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
- _("Not enough memory to load GIF file"));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ _("Not enough memory to load GIF file"));
return -2;
}
/* GIF delay is in hundredths, we want thousandths */
context->frame->delay_time = context->gif89.delay_time * 10;
- /* Some GIFs apparently have delay time of 0,
- * that crashes everything so set it to "fast".
- * Also, timeouts less than 20 or so just lock up
- * the app or make the animation choppy, so fix them.
+ /* GIFs with delay time 0 are mostly broken, but they
+ * just want a default, "not that fast" delay.
+ */
+ if (context->frame->delay_time == 0)
+ context->frame->delay_time = 100;
+
+ /* No GIFs gets to play faster than 50 fps. They just
+ * lock up poor gtk.
*/
if (context->frame->delay_time < 20)
context->frame->delay_time = 20; /* 20 = "fast" */
/* Only call prepare_func for the first frame */
if (context->animation->frames->next == NULL) {
+ if (context->animation->width == 0 )
+ context->animation->width = gdk_pixbuf_get_width(context->frame->pixbuf);
+ if (context->animation->height == 0)
+ context->animation->height = gdk_pixbuf_get_height (context->frame->pixbuf);
+
if (context->prepare_func)
(* context->prepare_func) (context->frame->pixbuf,
GDK_PIXBUF_ANIMATION (context->animation),
g_list_free (context->animation->frames);
context->animation->frames = NULL;
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
- _("Not enough memory to composite a frame in GIF file"));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ _("Not enough memory to composite a frame in GIF file"));
return -2;
}
*/
context->frame = NULL;
context->frame_cmap_active = FALSE;
+
+ if (context->stop_after_first_frame)
+ context->state = GIF_DONE;
}
return v;
}
if (context->lzw_set_code_size > MAX_LZW_BITS) {
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("GIF image is corrupt (incorrect LZW compression)"));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+ _("GIF image is corrupt (incorrect LZW compression)"));
return -2;
}
if (strncmp ((char *) buf, "GIF", 3) != 0) {
/* Not a GIF file */
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("File does not appear to be a GIF file"));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+ _("File does not appear to be a GIF file"));
return -2;
}
if (!context->has_global_cmap) {
context->state = GIF_DONE;
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("GIF image has no global colormap, and a frame inside it has no local colormap."));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+ _("GIF image has no global colormap, and a frame inside it has no local colormap."));
return -2;
}
}
-#define LOG(x) /* g_print ("%d: %s\n", __LINE__, x); */
+#define LOG(x) /* g_print ("%s: %s\n", G_STRLOC, x); */
static gint
gif_main_loop (GifContext *context)
memset (context, 0, sizeof (GifContext));
- context->animation = g_object_new (GDK_TYPE_PIXBUF_GIF_ANIM, NULL);
+ context->animation = g_object_new (GDK_TYPE_PIXBUF_GIF_ANIM, NULL);
context->frame = NULL;
context->file = NULL;
context->state = GIF_START;
context->gif89.disposal = -1;
context->animation->loop = 1;
context->in_loop_extension = FALSE;
+ context->stop_after_first_frame = FALSE;
return context;
}
context = new_context ();
if (context == NULL) {
- g_set_error (error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
- _("Not enough memory to load GIF file"));
+ g_set_error_literal (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ _("Not enough memory to load GIF file"));
return NULL;
}
context->file = file;
context->error = error;
-
+ context->stop_after_first_frame = TRUE;
+
if (gif_main_loop (context) == -1 || context->animation->frames == NULL) {
if (context->error && *(context->error) == NULL)
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("GIF file was missing some data (perhaps it was truncated somehow?)"));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+ _("GIF file was missing some data (perhaps it was truncated somehow?)"));
}
pixbuf = gdk_pixbuf_animation_get_static_image (GDK_PIXBUF_ANIMATION (context->animation));
context = new_context ();
if (context == NULL) {
- g_set_error (error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
- _("Not enough memory to load GIF file"));
+ g_set_error_literal (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ _("Not enough memory to load GIF file"));
return NULL;
}
GifContext *context = (GifContext *) data;
gboolean retval = TRUE;
- if (context->state != GIF_DONE) {
- g_set_error (error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("GIF image was truncated or incomplete."));
+ if (context->state != GIF_DONE || context->animation->frames == NULL) {
+ g_set_error_literal (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+ _("GIF image was truncated or incomplete."));
retval = FALSE;
}
context = new_context ();
if (context == NULL) {
- g_set_error (error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
- _("Not enough memory to load GIF file"));
+ g_set_error_literal (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ _("Not enough memory to load GIF file"));
return NULL;
}
if (gif_main_loop (context) == -1 || context->animation->frames == NULL) {
if (context->error && *(context->error) == NULL)
- g_set_error (context->error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("GIF file was missing some data (perhaps it was truncated somehow?)"));
+ g_set_error_literal (context->error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+ _("GIF file was missing some data (perhaps it was truncated somehow?)"));
g_object_unref (context->animation);
context->animation = NULL;
return animation;
}
-void
-MODULE_ENTRY (gif, fill_vtable) (GdkPixbufModule *module)
+#ifndef INCLUDE_gif
+#define MODULE_ENTRY(function) G_MODULE_EXPORT void function
+#else
+#define MODULE_ENTRY(function) void _gdk_pixbuf__gif_ ## function
+#endif
+
+MODULE_ENTRY (fill_vtable) (GdkPixbufModule *module)
{
module->load = gdk_pixbuf__gif_image_load;
module->begin_load = gdk_pixbuf__gif_image_begin_load;
module->load_animation = gdk_pixbuf__gif_image_load_animation;
}
-void
-MODULE_ENTRY (gif, fill_info) (GdkPixbufFormat *info)
+MODULE_ENTRY (fill_info) (GdkPixbufFormat *info)
{
static GdkPixbufModulePattern signature[] = {
{ "GIF8", NULL, 100 },