* 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,
pgp_bMn6rjm7M.pgp
Description: PGP signature
------------------------------------------------------------------------------
_______________________________________________ Geeqie-devel mailing list Geeqie-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/geeqie-devel