* Christian Heckendorf <heckendo...@gmail.com> [10.09.2015. @13:02:44 -0400]:
> * Klaus Ethgen <klaus+gee...@ethgen.de> [10.09.2015. @16:56:30 +0100]:
> > Am Do den 10. Sep 2015 um 16:27 schrieb John Stoffel:
> > > When will geeqie (if ever) support animated gifs?  I've been forced to
> > > use ristretto lately, and I don't like it nearly as much.
> >
> > I would like to see that too from time to time. The only problem is that
> > there is not enough man power currently doing it. There are several
> > problems that would be more important.
> >
> > I currently do not know any image viewer that support animated GIFs. I
> > always use firefox or gimp for this purpose. On the other hand, I do not
> > have that need too often.
> >
> > But if you have a working patch, I would be grateful uploading it. :-)
> >
> 
> I wrote a patch for this over 5 years ago and never got around to
> cleaning it up and sharing it. I'll dig around my backups when I get
> home in a few hours to see if I still have it.
> 

I found the patch and updated it against the current master. Happy to
see it still works without any modifications needed. I implemented it as
a pop-up/right-click option called "Animate" because it's pretty slow to
start animating. Feel free to switch to some other concept, but this
might be a useful starting point.

In case the patch attachment gets stripped from the list, you can
also find it on my server:
http://ulmus.me/other/patch/geeqie-gif.patch
http://ulmus.me/other/patch/geeqie-gif.patch.asc

Thanks,
Christian
diff --git a/src/layout_image.c b/src/layout_image.c
index b59eaa6..4e2e6b3 100644
--- a/src/layout_image.c
+++ b/src/layout_image.c
@@ -256,6 +256,106 @@ static gboolean layout_image_slideshow_continue_check(LayoutWindow *lw)
 
 /*
  *----------------------------------------------------------------------------
+ * Animation
+ *----------------------------------------------------------------------------
+ */
+
+struct image_animation_data
+{
+	ImageWindow *iw;
+	GdkPixbufAnimation *gpa;
+	GdkPixbufAnimationIter *iter;
+	GdkPixbuf *gpb;
+	FileData *data_adr;
+	volatile FileData **cur_data_adr;
+	guint delay;
+};
+
+static void image_animation_data_free(struct image_animation_data *fd)
+{
+	g_object_unref(fd->iter);
+	g_object_unref(fd->gpa);
+	free(fd);
+}
+
+static gboolean animation_should_continue(struct image_animation_data *fd)
+{
+	/* Check if a new image has been loaded. */
+	if (fd->data_adr != *fd->cur_data_adr)
+		return FALSE;
+
+	return TRUE;
+}
+
+static gboolean show_next_frame(gpointer data)
+{
+	struct image_animation_data *fd = (struct image_animation_data*)data;
+	int delay;
+	PixbufRenderer *pr = (PixbufRenderer*)fd->iw->pr;
+
+	if (animation_should_continue(fd)==FALSE)
+		{
+		image_animation_data_free(fd);
+		return FALSE;
+		}
+
+	if (gdk_pixbuf_animation_iter_advance(fd->iter,NULL)==FALSE)
+		{
+		/* This indicates the animation is complete.
+		   Return FALSE here to disable looping. */
+		}
+
+	fd->gpb = gdk_pixbuf_animation_iter_get_pixbuf(fd->iter);
+	image_change_pixbuf(fd->iw,fd->gpb,pr->zoom,FALSE);
+
+	if (fd->iw->func_update)
+		fd->iw->func_update(fd->iw, fd->iw->data_update);
+
+	delay = gdk_pixbuf_animation_iter_get_delay_time(fd->iter);
+	if (delay!=fd->delay)
+		{
+		if (delay>0) /* Current frame not static. */
+			{
+			fd->delay=delay;
+			g_timeout_add(delay,show_next_frame,fd);
+			}
+		else
+			{
+			image_animation_data_free(fd);
+			}
+		return FALSE;
+		}
+
+	return TRUE;
+}
+
+void layout_image_animate_toggle(LayoutWindow *lw)
+{
+	GError *err=NULL;
+	GdkPixbufAnimation *gpa;
+	GdkPixbufAnimationIter *iter;
+	ImageWindow *iw;
+	struct image_animation_data *fd;
+
+	if (!lw || !(iw=lw->image) ||
+		!(gpa = gdk_pixbuf_animation_new_from_file(iw->image_fd->path,&err)) || err ||
+		gdk_pixbuf_animation_is_static_image(gpa) ||
+		!(iter = gdk_pixbuf_animation_get_iter(gpa,NULL)))
+		return;
+	
+	fd=malloc(sizeof(struct image_animation_data));
+	fd->iw = iw;
+	fd->gpa = gpa;
+	fd->iter = iter;
+	fd->data_adr = iw->image_fd;
+	fd->cur_data_adr = (volatile FileData**) &iw->image_fd;
+	fd->delay =gdk_pixbuf_animation_iter_get_delay_time(iter);
+
+	g_timeout_add(fd->delay, show_next_frame, fd);
+}
+
+/*
+ *----------------------------------------------------------------------------
  * pop-up menus
  *----------------------------------------------------------------------------
  */
@@ -411,6 +511,13 @@ static void li_pop_menu_full_screen_cb(GtkWidget *widget, gpointer data)
 	layout_image_full_screen_toggle(lw);
 }
 
+static void li_pop_menu_animate_cb(GtkWidget *widget, gpointer data)
+{
+	LayoutWindow *lw = data;
+
+	layout_image_animate_toggle(lw);
+}
+
 static void li_pop_menu_hide_cb(GtkWidget *widget, gpointer data)
 {
 	LayoutWindow *lw = data;
@@ -548,6 +655,8 @@ static GtkWidget *layout_image_pop_menu(LayoutWindow *lw)
 		menu_item_add(menu, _("Exit _full screen"), G_CALLBACK(li_pop_menu_full_screen_cb), lw);
 		}
 
+	menu_item_add(menu, _("_Animate"), G_CALLBACK(li_pop_menu_animate_cb), lw);
+
 	menu_item_add_divider(menu);
 
 	item = menu_item_add_check(menu, _("Hide file _list"), lw->options.tools_hidden,

Attachment: pgp_bMn6rjm7M.pgp
Description: PGP signature

------------------------------------------------------------------------------
_______________________________________________
Geeqie-devel mailing list
Geeqie-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geeqie-devel

Reply via email to