This patch adds support for GtkImageView in EOG. The EogScrollView widget is replaced with a GtkAnimView. This way, EOG becomes capable of showing GIF animations. Patch applies cleanly against EOG r3989. Copyright (C) 2007 Björn Lindqvist Index: src/eog-image.h =================================================================== --- src/eog-image.h (revision 3989) +++ src/eog-image.h (arbetskopia) @@ -148,6 +148,8 @@ GdkPixbuf* eog_image_get_pixbuf (EogImage *img); +GdkPixbufAnimation *eog_image_get_anim (EogImage *img); + GdkPixbuf* eog_image_get_thumbnail (EogImage *img); void eog_image_get_size (EogImage *img, Index: src/eog-image-private.h =================================================================== --- src/eog-image-private.h (revision 3989) +++ src/eog-image-private.h (arbetskopia) @@ -1,5 +1,7 @@ -/* Eye Of Gnome - Image Private Data +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- * + * Eye Of Gnome - Image Private Data + * * Copyright (C) 2007 The Free Software Foundation * * Author: Lucas Rocha @@ -31,7 +33,8 @@ EogImageStatus status; - GdkPixbuf *image; + GdkPixbufAnimation *anim; + GdkPixbuf *thumbnail; gint width; Index: src/eog-image-jpeg.c =================================================================== --- src/eog-image-jpeg.c (revision 3989) +++ src/eog-image-jpeg.c (arbetskopia) @@ -329,10 +329,10 @@ struct error_handler_data jerr; g_return_val_if_fail (EOG_IS_IMAGE (image), FALSE); - g_return_val_if_fail (EOG_IMAGE (image)->priv->image != NULL, FALSE); + g_return_val_if_fail (EOG_IMAGE (image)->priv->anim != NULL, FALSE); priv = image->priv; - pixbuf = priv->image; + pixbuf = gdk_pixbuf_animation_get_static_image (priv->anim); outfile = fopen (file, "wb"); if (outfile == NULL) { Index: src/eog-window.c =================================================================== --- src/eog-window.c (revision 3989) +++ src/eog-window.c (arbetskopia) @@ -1,5 +1,7 @@ -/* Eye Of Gnome - Main Window +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- * + * Eye Of Gnome - Main Window + * * Copyright (C) 2000-2006 The Free Software Foundation * * Author: Lucas Rocha @@ -32,7 +34,6 @@ #include #include "eog-window.h" -#include "eog-scroll-view.h" #include "eog-debug.h" #include "eog-file-chooser.h" #include "eog-thumb-view.h" @@ -62,6 +63,10 @@ #include #include #include +#include +#include +#include +#include #ifdef GDK_WINDOWING_X11 #include #endif @@ -135,6 +140,7 @@ GtkWidget *box; GtkWidget *layout; GtkWidget *cbox; + GtkWidget *scroll_win; GtkWidget *view; GtkWidget *sidebar; GtkWidget *thumbview; @@ -220,17 +226,21 @@ eog_debug (DEBUG_PREFERENCES); g_return_if_fail (EOG_IS_WINDOW (user_data)); - + priv = EOG_WINDOW (user_data)->priv; - g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view)); + g_return_if_fail (GTK_IMAGE_VIEW (priv->view)); if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL) { interpolate = gconf_value_get_bool (entry->value); } - eog_scroll_view_set_antialiasing (EOG_SCROLL_VIEW (priv->view), - interpolate); + GdkInterpType interp = GDK_INTERP_NEAREST; + if (interpolate) { + interp = GDK_INTERP_BILINEAR; + } + gtk_image_view_set_interpolation (GTK_IMAGE_VIEW (priv->view), + interp); } static void @@ -239,23 +249,7 @@ GConfEntry *entry, gpointer user_data) { - EogWindowPrivate *priv; - gboolean scroll_wheel_zoom = FALSE; - - eog_debug (DEBUG_PREFERENCES); - - g_return_if_fail (EOG_IS_WINDOW (user_data)); - - priv = EOG_WINDOW (user_data)->priv; - - g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view)); - - if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL) { - scroll_wheel_zoom = gconf_value_get_bool (entry->value); - } - - eog_scroll_view_set_scroll_wheel_zoom (EOG_SCROLL_VIEW (priv->view), - scroll_wheel_zoom); + printf ("THIS SETTING IS NOT SUPPORTED AT ALL!\n"); } static void @@ -264,23 +258,7 @@ GConfEntry *entry, gpointer user_data) { - EogWindowPrivate *priv; - gdouble multiplier = 0.05; - - eog_debug (DEBUG_PREFERENCES); - - g_return_if_fail (EOG_IS_WINDOW (user_data)); - - priv = EOG_WINDOW (user_data)->priv; - - g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view)); - - if (entry->value != NULL && entry->value->type == GCONF_VALUE_FLOAT) { - multiplier = gconf_value_get_float (entry->value); - } - - eog_scroll_view_set_zoom_multiplier (EOG_SCROLL_VIEW (priv->view), - multiplier); + printf ("THIS SETTING IS NOT SUPPORTED AT ALL!\n"); } static void @@ -298,7 +276,7 @@ priv = EOG_WINDOW (user_data)->priv; - g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view)); + g_return_if_fail (GTK_IMAGE_VIEW (priv->view)); if (entry->value != NULL && entry->value->type == GCONF_VALUE_STRING) { value = gconf_value_get_string (entry->value); @@ -313,16 +291,21 @@ color_str = gconf_client_get_string (priv->client, EOG_CONF_VIEW_TRANS_COLOR, NULL); if (gdk_color_parse (color_str, &color)) { - eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view), - EOG_TRANSP_COLOR, &color); + printf ("FIXME: Color conversion needed.\n"); + gtk_image_view_set_transp (GTK_IMAGE_VIEW (priv->view), + GTK_IMAGE_TRANSP_COLOR, + (0xff000000 + | ((color.red >> 8) << 16) + | ((color.green >> 8) << 8) + | (color.blue >> 8))); } g_free (color_str); } else if (g_ascii_strcasecmp (value, "CHECK_PATTERN") == 0) { - eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view), - EOG_TRANSP_CHECKED, 0); + gtk_image_view_set_transp (GTK_IMAGE_VIEW (priv->view), + GTK_IMAGE_TRANSP_GRID, 0); } else { - eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view), - EOG_TRANSP_BACKGROUND, 0); + gtk_image_view_set_transp (GTK_IMAGE_VIEW (priv->view), + GTK_IMAGE_TRANSP_BACKGROUND, 0); } } @@ -343,7 +326,7 @@ priv = EOG_WINDOW (user_data)->priv; - g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view)); + g_return_if_fail (GTK_IS_IMAGE_VIEW (priv->view)); value = gconf_client_get_string (priv->client, EOG_CONF_VIEW_TRANSPARENCY, @@ -358,8 +341,13 @@ color_str = gconf_value_get_string (entry->value); if (gdk_color_parse (color_str, &color)) { - eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view), - EOG_TRANSP_COLOR, &color); + printf ("FIXME: Not sure about this\n"); + gtk_image_view_set_transp (GTK_IMAGE_VIEW (priv->view), + GTK_IMAGE_TRANSP_COLOR, + (0xff000000 + | ((color.red >> 8) << 16) + | ((color.green >> 8) << 8) + | (color.blue >> 8))); } } g_free (value); @@ -380,7 +368,7 @@ priv = EOG_WINDOW (user_data)->priv; - g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view)); + g_return_if_fail (GTK_IS_IMAGE_VIEW (priv->view)); if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL) { show_buttons = gconf_value_get_bool (entry->value); @@ -586,6 +574,8 @@ EogWindowPrivate *priv; char *str = NULL; + printf ("update_status_bar\n"); + g_return_if_fail (EOG_IS_WINDOW (window)); eog_debug (DEBUG_WINDOW); @@ -597,7 +587,7 @@ int zoom, width, height; GnomeVFSFileSize bytes = 0; - zoom = floor (100 * eog_scroll_view_get_zoom (EOG_SCROLL_VIEW (priv->view)) + 0.5); + zoom = floor (100 * gtk_image_view_get_zoom (GTK_IMAGE_VIEW (priv->view)) + 0.5); eog_image_get_size (priv->image, &width, &height); @@ -605,7 +595,7 @@ if ((width > 0) && (height > 0)) { char *size_string; - + size_string = gnome_vfs_format_file_size_for_display (bytes); /* [image width] x [image height] pixels [bytes] [zoom in percent] */ @@ -629,6 +619,7 @@ priv->image_info_message_cid, str ? str : ""); g_free (str); + printf ("update_status_bar:done\n"); } static void @@ -759,7 +750,7 @@ priv->mode != EOG_WINDOW_MODE_SLIDESHOW; gtk_widget_show (priv->layout); - gtk_widget_show_all (priv->view->parent); + gtk_widget_show_all (priv->scroll_win->parent); if (show_image_collection) gtk_widget_show (priv->nav); @@ -917,6 +908,8 @@ EogWindowPrivate *priv; GnomeVFSURI *uri; + printf ("eog_window_display_image\n"); + g_return_if_fail (EOG_IS_WINDOW (window)); g_return_if_fail (EOG_IS_IMAGE (image)); @@ -935,7 +928,8 @@ image_thumb_changed_cb (image, window); } - eog_scroll_view_set_image (EOG_SCROLL_VIEW (priv->view), image); + gtk_anim_view_set_anim (GTK_ANIM_VIEW (priv->view), + eog_image_get_anim (image)); gtk_window_set_title (GTK_WINDOW (window), eog_image_get_caption (image)); @@ -1247,6 +1241,8 @@ EogWindow *window; EogWindowPrivate *priv; + printf ("eog_job_load_cb:start\n"); + g_return_if_fail (EOG_IS_WINDOW (data)); eog_debug (DEBUG_WINDOW); @@ -1303,7 +1299,7 @@ update_status_bar (window); - eog_scroll_view_set_image (EOG_SCROLL_VIEW (priv->view), NULL); + gtk_anim_view_set_anim (GTK_ANIM_VIEW (priv->view), NULL); if (window->priv->status == EOG_WINDOW_STATUS_INIT) { update_action_groups_state (window); @@ -1326,6 +1322,7 @@ } g_object_unref (job->image); + printf ("eog_job_load_cb:end\n"); } static void @@ -1349,12 +1346,17 @@ eog_job_transform_cb (EogJobTransform *job, gpointer data) { EogWindow *window; + + printf ("eog_job_transform_cb\n"); g_return_if_fail (EOG_IS_WINDOW (data)); window = EOG_WINDOW (data); eog_window_clear_transform_job (window); + + gtk_anim_view_set_anim (GTK_ANIM_VIEW (window->priv->view), + eog_image_get_anim (window->priv->image)); } static void @@ -1449,14 +1451,15 @@ } static void -view_zoom_changed_cb (GtkWidget *widget, double zoom, gpointer user_data) +view_zoom_changed_cb (GtkWidget *widget, gpointer user_data) { EogWindow *window; GtkAction *action_zoom_in; GtkAction *action_zoom_out; + gdouble zoom; g_return_if_fail (EOG_IS_WINDOW (user_data)); - + window = EOG_WINDOW (user_data); update_status_bar (window); @@ -1469,10 +1472,11 @@ gtk_action_group_get_action (window->priv->actions_image, "ViewZoomOut"); + zoom = gtk_image_view_get_zoom (GTK_IMAGE_VIEW (window->priv->view)); gtk_action_set_sensitive (action_zoom_in, - !eog_scroll_view_get_zoom_is_max (EOG_SCROLL_VIEW (window->priv->view))); + zoom < gtk_zooms_get_max_zoom ()); gtk_action_set_sensitive (action_zoom_out, - !eog_scroll_view_get_zoom_is_min (EOG_SCROLL_VIEW (window->priv->view))); + zoom > gtk_zooms_get_min_zoom ()); } static void @@ -1604,7 +1608,8 @@ gtk_widget_hide_all (window->priv->fullscreen_popup); - eog_scroll_view_hide_cursor (EOG_SCROLL_VIEW (window->priv->view)); + gtk_image_view_set_show_cursor (GTK_IMAGE_VIEW (window->priv->view), + FALSE); fullscreen_clear_timeout (window); @@ -1673,7 +1678,8 @@ window->priv->fullscreen_timeout_source = source; - eog_scroll_view_show_cursor (EOG_SCROLL_VIEW (window->priv->view)); + gtk_image_view_set_show_cursor (GTK_IMAGE_VIEW (window->priv->view), + TRUE); } static void @@ -1900,7 +1906,6 @@ { EogWindowPrivate *priv; GtkWidget *menubar; - gboolean upscale; eog_debug (DEBUG_WINDOW); @@ -1922,7 +1927,7 @@ g_assert (GTK_IS_WIDGET (menubar)); gtk_widget_hide (menubar); - g_object_set (G_OBJECT (gtk_widget_get_parent (priv->view)), + g_object_set (G_OBJECT (gtk_widget_get_parent (priv->scroll_win)), "shadow-type", GTK_SHADOW_NONE, NULL); @@ -1962,28 +1967,27 @@ slideshow_set_timeout (window); } - upscale = gconf_client_get_bool (priv->client, - EOG_CONF_FULLSCREEN_UPSCALE, - NULL); + gtk_widget_grab_focus (priv->view); - eog_scroll_view_set_zoom_upscale (EOG_SCROLL_VIEW (priv->view), - upscale); + - gtk_widget_grab_focus (priv->view); - - gtk_widget_modify_bg (window->priv->view, GTK_STATE_NORMAL, + gtk_widget_modify_bg (window->priv->view, GTK_STATE_NORMAL, &(GTK_WIDGET (window)->style->black)); + gtk_image_view_set_show_frame (GTK_IMAGE_VIEW (priv->view), FALSE); { + /* Make the border of the frame the scroll_win is + added to invisible. */ GtkStyle *style; + GtkWidget *frame; - style = gtk_style_copy (gtk_widget_get_style (priv->view->parent)); + frame = priv->scroll_win->parent; + style = gtk_style_copy (gtk_widget_get_style (frame)); style->xthickness = 0; style->ythickness = 0; - gtk_widget_set_style (priv->view->parent, style); - + gtk_widget_set_style (frame, style); g_object_unref (style); } @@ -2019,10 +2023,10 @@ if (slideshow) { slideshow_clear_timeout (window); } - - g_object_set (G_OBJECT (gtk_widget_get_parent (priv->view)), + + g_object_set (G_OBJECT (gtk_widget_get_parent (priv->scroll_win)), "shadow-type", GTK_SHADOW_IN, - NULL); + NULL); g_signal_handlers_disconnect_by_func (priv->view, (gpointer) fullscreen_motion_notify_cb, @@ -2045,21 +2049,18 @@ menubar = gtk_ui_manager_get_widget (priv->ui_mgr, "/MainMenu"); g_assert (GTK_IS_WIDGET (menubar)); gtk_widget_show (menubar); - - eog_scroll_view_set_zoom_upscale (EOG_SCROLL_VIEW (priv->view), FALSE); - gtk_widget_modify_bg (window->priv->view, GTK_STATE_NORMAL, NULL); - gtk_widget_set_style (window->priv->view->parent, NULL); gtk_window_unfullscreen (GTK_WINDOW (window)); + gtk_widget_modify_bg (window->priv->view, GTK_STATE_NORMAL, NULL); + gtk_image_view_set_show_frame (GTK_IMAGE_VIEW (priv->view), TRUE); + gtk_image_view_set_show_cursor (GTK_IMAGE_VIEW (priv->view), TRUE); + if (slideshow) { eog_window_update_slideshow_action (window); } else { eog_window_update_fullscreen_action (window); } - - eog_scroll_view_show_cursor (EOG_SCROLL_VIEW (priv->view)); - eog_application_screensaver_enable (EOG_APP); } @@ -3072,7 +3073,7 @@ priv = EOG_WINDOW (user_data)->priv; if (priv->view) { - eog_scroll_view_zoom_in (EOG_SCROLL_VIEW (priv->view), FALSE); + gtk_image_view_zoom_in (GTK_IMAGE_VIEW (priv->view)); } } @@ -3088,7 +3089,7 @@ priv = EOG_WINDOW (user_data)->priv; if (priv->view) { - eog_scroll_view_zoom_out (EOG_SCROLL_VIEW (priv->view), FALSE); + gtk_image_view_zoom_out (GTK_IMAGE_VIEW (priv->view)); } } @@ -3104,7 +3105,7 @@ priv = EOG_WINDOW (user_data)->priv; if (priv->view) { - eog_scroll_view_set_zoom (EOG_SCROLL_VIEW (priv->view), 1.0); + gtk_image_view_set_zoom (GTK_IMAGE_VIEW (priv->view), 1.0); } } @@ -3120,7 +3121,7 @@ priv = EOG_WINDOW (user_data)->priv; if (priv->view) { - eog_scroll_view_zoom_fit (EOG_SCROLL_VIEW (priv->view)); + gtk_image_view_set_fitting (GTK_IMAGE_VIEW (priv->view), TRUE); } } @@ -3807,8 +3808,10 @@ G_CALLBACK (eog_window_sidebar_page_removed), window); - priv->view = eog_scroll_view_new (); - gtk_widget_set_size_request (GTK_WIDGET (priv->view), 100, 100); + priv->view = gtk_anim_view_new (); + priv->scroll_win = + gtk_image_scroll_win_new (GTK_IMAGE_VIEW (priv->view)); + gtk_widget_set_size_request (priv->view, 100, 100); g_signal_connect (G_OBJECT (priv->view), "zoom_changed", G_CALLBACK (view_zoom_changed_cb), @@ -3818,7 +3821,7 @@ "shadow-type", GTK_SHADOW_IN, NULL); - gtk_container_add (GTK_CONTAINER (frame), priv->view); + gtk_container_add (GTK_CONTAINER (frame), priv->scroll_win); gtk_paned_pack1 (GTK_PANED (hpaned), priv->sidebar, @@ -4195,15 +4198,16 @@ if (tbcontainer->focus_child != NULL) break; case GDK_Page_Up: - if (!eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) { - eog_thumb_view_select_single (EOG_THUMB_VIEW (EOG_WINDOW (widget)->priv->thumbview), - EOG_THUMB_VIEW_SELECT_LEFT); - result = TRUE; - } + printf ("FIXME: Not sure about this\n"); +/* if (!eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) { */ +/* eog_thumb_view_select_single (EOG_THUMB_VIEW (EOG_WINDOW (widget)->priv->thumbview), */ +/* EOG_THUMB_VIEW_SELECT_LEFT); */ +/* result = TRUE; */ +/* } */ - if (EOG_WINDOW (widget)->priv->mode == EOG_WINDOW_MODE_SLIDESHOW) { - slideshow_set_timeout (EOG_WINDOW (widget)); - } +/* if (EOG_WINDOW (widget)->priv->mode == EOG_WINDOW_MODE_SLIDESHOW) { */ +/* slideshow_set_timeout (EOG_WINDOW (widget)); */ +/* } */ break; case GDK_Down: @@ -4211,15 +4215,16 @@ if (tbcontainer->focus_child != NULL) break; case GDK_Page_Down: - if (!eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) { - eog_thumb_view_select_single (EOG_THUMB_VIEW (EOG_WINDOW (widget)->priv->thumbview), - EOG_THUMB_VIEW_SELECT_RIGHT); - result = TRUE; - } + printf ("FIXME: Not sure about this\n"); +/* if (!eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) { */ +/* eog_thumb_view_select_single (EOG_THUMB_VIEW (EOG_WINDOW (widget)->priv->thumbview), */ +/* EOG_THUMB_VIEW_SELECT_RIGHT); */ +/* result = TRUE; */ +/* } */ - if (EOG_WINDOW (widget)->priv->mode == EOG_WINDOW_MODE_SLIDESHOW) { - slideshow_set_timeout (EOG_WINDOW (widget)); - } +/* if (EOG_WINDOW (widget)->priv->mode == EOG_WINDOW_MODE_SLIDESHOW) { */ +/* slideshow_set_timeout (EOG_WINDOW (widget)); */ +/* } */ break; } Index: src/eog-image.c =================================================================== --- src/eog-image.c (revision 3989) +++ src/eog-image.c (arbetskopia) @@ -1,5 +1,7 @@ -/* Eye Of Gnome - Image +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- * + * Eye Of Gnome - Image + * * Copyright (C) 2006 The Free Software Foundation * * Author: Lucas Rocha @@ -23,6 +25,9 @@ #include "config.h" #endif +/* Define needed to get the gdk_pixbuf_non_anim_new() function. */ +#define GDK_PIXBUF_ENABLE_BACKEND + #include "eog-image.h" #include "eog-image-private.h" #include "eog-debug.h" @@ -41,11 +46,14 @@ #include + + #include #include #include #include #include +#include #include #include @@ -91,9 +99,9 @@ if (priv->status == EOG_IMAGE_STATUS_LOADING) { eog_image_cancel_load (image); } else { - if (priv->image != NULL) { - g_object_unref (priv->image); - priv->image = NULL; + if (priv->anim != NULL) { + g_object_unref (priv->anim); + priv->anim = NULL; } #ifdef HAVE_EXIF @@ -231,7 +239,7 @@ img->priv = EOG_IMAGE_GET_PRIVATE (img); img->priv->uri = NULL; - img->priv->image = NULL; + img->priv->anim = NULL; img->priv->thumbnail = NULL; img->priv->width = -1; img->priv->height = -1; @@ -342,20 +350,30 @@ GdkPixbuf *transformed; gboolean modified = FALSE; + printf ("eog_image_real_transform\n"); + g_return_if_fail (EOG_IS_IMAGE (img)); g_return_if_fail (EOG_IS_TRANSFORM (trans)); priv = img->priv; - if (priv->image != NULL) { - transformed = eog_transform_apply (trans, priv->image, job); + /* Transformations cannot be applied to animations. */ + if (priv->anim != NULL && + gdk_pixbuf_animation_is_static_image (priv->anim) == TRUE) { + + printf ("Making transform!\n"); - g_object_unref (priv->image); - priv->image = transformed; + /* Take the static frame, transform it, and then + repackage it in the animation. */ + GdkPixbuf *pixbuf; + pixbuf = gdk_pixbuf_animation_get_static_image (priv->anim); + transformed = eog_transform_apply (trans, pixbuf, job); + g_object_unref (priv->anim); + + priv->anim = gdk_pixbuf_non_anim_new (transformed); priv->width = gdk_pixbuf_get_width (transformed); priv->height = gdk_pixbuf_get_height (transformed); - modified = TRUE; } @@ -459,7 +477,7 @@ return TRUE; } - if (priv->image == NULL) { + if (priv->anim == NULL) { g_set_error (error, EOG_IMAGE_ERROR, EOG_IMAGE_ERROR_NOT_LOADED, @@ -468,17 +486,24 @@ return FALSE; } - if (priv->trans != NULL) { - transformed = eog_transform_apply (priv->trans, priv->image, NULL); + /* Transformations can only be applied to images, not + animations. */ + if (gdk_pixbuf_animation_is_static_image (priv->anim) && + priv->trans != NULL) { + /* Take the static frame, transform it, and then + repackage it in the animation. */ + GdkPixbuf *pixbuf; + + pixbuf = gdk_pixbuf_animation_get_static_image (priv->anim); + transformed = eog_transform_apply (priv->trans, pixbuf, NULL); + g_object_unref (priv->anim); + + priv->anim = gdk_pixbuf_non_anim_new (transformed); + priv->width = gdk_pixbuf_get_width (transformed); + priv->height = gdk_pixbuf_get_height (transformed); } - g_object_unref (priv->image); - priv->image = transformed; - - if (transformed != NULL) { - priv->width = gdk_pixbuf_get_width (priv->image); - priv->height = gdk_pixbuf_get_height (priv->image); - } else { + if (transformed == NULL) { g_set_error (error, EOG_IMAGE_ERROR, EOG_IMAGE_ERROR_GENERIC, @@ -529,12 +554,16 @@ cmsHTRANSFORM transform; gint row, width, rows, stride; guchar *p; + GdkPixbuf *pixbuf; g_return_if_fail (img != NULL); priv = img->priv; - if (screen == NULL || priv->profile == NULL) return; + if (screen == NULL || + priv->profile == NULL || + gdk_pixbuf_animation_is_static_image (priv->anim) == FALSE) + return; transform = cmsCreateTransform (priv->profile, TYPE_RGB_8, @@ -542,11 +571,13 @@ TYPE_RGB_8, INTENT_PERCEPTUAL, 0); + + pixbuf = gdk_pixbuf_animation_get_static_image (priv->anim); - rows = gdk_pixbuf_get_height(priv->image); - width = gdk_pixbuf_get_width (priv->image); - stride = gdk_pixbuf_get_rowstride (priv->image); - p = gdk_pixbuf_get_pixels (priv->image); + rows = gdk_pixbuf_get_height(pixbuf); + width = gdk_pixbuf_get_width (pixbuf); + stride = gdk_pixbuf_get_rowstride (pixbuf); + p = gdk_pixbuf_get_pixels (pixbuf); for (row = 0; row < rows; ++row) { cmsDoTransform(transform, p, p, width); @@ -870,7 +901,7 @@ priv = img->priv; - g_assert (!read_image_data || priv->image == NULL); + g_assert (!read_image_data || priv->anim == NULL); if (read_image_data && priv->file_type != NULL) { g_free (priv->file_type); @@ -1031,18 +1062,20 @@ } } else { if (read_image_data) { - if (priv->image != NULL) { - g_object_unref (priv->image); + if (priv->anim != NULL) { + g_object_unref (priv->anim); } - priv->image = gdk_pixbuf_loader_get_pixbuf (loader); + priv->anim = gdk_pixbuf_loader_get_animation (loader); - g_assert (priv->image != NULL); + g_assert (priv->anim != NULL); - g_object_ref (priv->image); + g_object_ref (priv->anim); - priv->width = gdk_pixbuf_get_width (priv->image); - priv->height = gdk_pixbuf_get_height (priv->image); + priv->width = + gdk_pixbuf_animation_get_width (priv->anim); + priv->height = + gdk_pixbuf_animation_get_height (priv->anim); format = gdk_pixbuf_loader_get_format (loader); @@ -1084,7 +1117,7 @@ if ((req_data & EOG_IMAGE_DATA_IMAGE) > 0) { req_data = (req_data & !EOG_IMAGE_DATA_IMAGE); - has_data = has_data && (priv->image != NULL); + has_data = has_data && (priv->anim != NULL); } if ((req_data & EOG_IMAGE_DATA_DIMENSION) > 0 ) { @@ -1198,7 +1231,7 @@ g_return_val_if_fail (EOG_IS_IMAGE (img), NULL); g_mutex_lock (img->priv->status_mutex); - image = img->priv->image; + image = gdk_pixbuf_animation_get_static_image (img->priv->anim); g_mutex_unlock (img->priv->status_mutex); if (image != NULL) { @@ -1208,6 +1241,24 @@ return image; } +GdkPixbufAnimation * +eog_image_get_anim (EogImage *img) +{ + GdkPixbufAnimation *anim; + + g_return_val_if_fail (EOG_IS_IMAGE (img), NULL); + + g_mutex_lock (img->priv->status_mutex); + anim = img->priv->anim; + g_mutex_unlock (img->priv->status_mutex); + + if (anim != NULL) { + g_object_ref (anim); + } + + return anim; +} + #ifdef HAVE_LCMS cmsHPROFILE eog_image_get_profile (EogImage *img) @@ -1481,7 +1532,7 @@ } /* fail if there is no image to save */ - if (priv->image == NULL) { + if (priv->anim == NULL) { g_set_error (error, EOG_IMAGE_ERROR, EOG_IMAGE_ERROR_NOT_LOADED, _("No image loaded.")); @@ -1507,7 +1558,12 @@ #endif if (!success && (*error == NULL)) { - success = gdk_pixbuf_save (priv->image, tmpfile, source->format, error, NULL); + success = gdk_pixbuf_save + (gdk_pixbuf_animation_get_static_image (priv->anim), + tmpfile, + source->format, + error, + NULL); } if (success) { @@ -1609,7 +1665,7 @@ priv = img->priv; /* fail if there is no image to save */ - if (priv->image == NULL) { + if (priv->anim == NULL) { g_set_error (error, EOG_IMAGE_ERROR, EOG_IMAGE_ERROR_NOT_LOADED, @@ -1645,7 +1701,12 @@ #endif if (!success && (*error == NULL)) { - success = gdk_pixbuf_save (priv->image, tmpfile, target->format, error, NULL); + success = gdk_pixbuf_save + (gdk_pixbuf_animation_get_static_image (priv->anim), + tmpfile, + target->format, + error, + NULL); } if (success && !direct_copy) { /* not required if we alredy copied the file directly */ Index: configure.ac =================================================================== --- configure.ac (revision 3989) +++ configure.ac (arbetskopia) @@ -76,6 +76,7 @@ GNOME_ICON_THEME_REQUIRED=2.19.1 SHARED_MIME_INFO_REQUIRED=0.20 EXEMPI_REQUIRED=1.99.2 +GTKIMAGEVIEW_REQUIRED=1.4.0 EOG_MODULES="gtk+-2.0 >= $GTK_REQUIRED \ @@ -89,7 +90,8 @@ gnome-desktop-2.0 >= $GNOME_DESKTOP_REQUIRED \ gtk+-unix-print-2.0 >= $GTK_PRINT_REQUIRED \ gnome-icon-theme >= $GNOME_ICON_THEME_REQUIRED \ - shared-mime-info >= $SHARED_MIME_INFO_REQUIRED" + shared-mime-info >= $SHARED_MIME_INFO_REQUIRED \ + gtkimageview >= $GTKIMAGEVIEW_REQUIRED" # *************** # EXIF (optional)