* Christian Heckendorf <[email protected]> [10.09.2015. @13:02:44 -0400]: > * Klaus Ethgen <[email protected]> [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,
pgp_bMn6rjm7M.pgp
Description: PGP signature
------------------------------------------------------------------------------
_______________________________________________ Geeqie-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/geeqie-devel
