[gthumb: 55/129] Added GthImage as a generic container of image data
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 55/129] Added GthImage as a generic container of image data
- Date: Wed, 27 Apr 2011 20:55:00 +0000 (UTC)
commit 30e7b30b87cd87138f3b76f803f5b198fdecc6dd
Author: Paolo Bacchilega <paobac src gnome org>
Date: Thu Apr 21 21:54:17 2011 +0200
Added GthImage as a generic container of image data
This change will allow to add loaders that create a cairo_surface structure directly
instead of loading the image in a GdkPixbuf and then converting it to a cairo_surface.
.../contact_sheet/gth-contact-sheet-creator.c | 16 +-
extensions/flicker/dlg-import-from-flickr.c | 15 +-
extensions/image_print/gth-load-image-info-task.c | 21 +-
extensions/image_viewer/gth-image-viewer-page.c | 24 +-
extensions/picasaweb/dlg-import-from-picasaweb.c | 15 +-
extensions/raw_files/main.c | 68 +++---
extensions/slideshow/gth-slideshow.c | 10 +-
extensions/webalbums/gth-web-exporter.c | 15 +-
gthumb/Makefile.am | 2 +
gthumb/gth-image-loader.c | 131 ++++------
gthumb/gth-image-loader.h | 18 +-
gthumb/gth-image-preloader.c | 43 ++--
gthumb/gth-image-preloader.h | 4 +-
gthumb/gth-image.c | 280 ++++++++++++++++++++
gthumb/gth-image.h | 86 ++++++
gthumb/gth-main-default-types.c | 5 +-
gthumb/gth-main.c | 59 +++--
gthumb/gth-main.h | 7 +-
gthumb/gth-overwrite-dialog.c | 16 +-
gthumb/gth-thumb-loader.c | 87 ++++---
gthumb/gth-thumb-loader.h | 2 +-
gthumb/pixbuf-io.c | 53 ++--
gthumb/pixbuf-io.h | 5 +-
23 files changed, 686 insertions(+), 296 deletions(-)
---
diff --git a/extensions/contact_sheet/gth-contact-sheet-creator.c b/extensions/contact_sheet/gth-contact-sheet-creator.c
index bbfd578..fec4fec 100644
--- a/extensions/contact_sheet/gth-contact-sheet-creator.c
+++ b/extensions/contact_sheet/gth-contact-sheet-creator.c
@@ -933,23 +933,26 @@ image_loader_ready_cb (GObject *source_object,
gpointer user_data)
{
GthContactSheetCreator *self = user_data;
+ GthImage *image;
GdkPixbuf *pixbuf;
int original_width;
int original_height;
GError *error = NULL;
ItemData *item_data;
- if (! gth_image_loader_load_image_finish (GTH_IMAGE_LOADER (source_object),
- result,
- &pixbuf,
- &original_width,
- &original_height,
- &error))
+ if (! gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
+ result,
+ &image,
+ &original_width,
+ &original_height,
+ &error))
{
gth_task_completed (GTH_TASK (self), error);
return;
}
+ pixbuf = gth_image_get_pixbuf (image);
+
item_data = self->priv->current_file->data;
if (self->priv->squared_thumbnails)
item_data->thumbnail = _gdk_pixbuf_scale_squared (pixbuf, MIN (self->priv->thumb_height, self->priv->thumb_width), GDK_INTERP_BILINEAR);
@@ -959,6 +962,7 @@ image_loader_ready_cb (GObject *source_object,
item_data->original_height = original_height;
g_object_unref (pixbuf);
+ g_object_unref (image);
self->priv->current_file = self->priv->current_file->next;
load_current_image (self);
diff --git a/extensions/flicker/dlg-import-from-flickr.c b/extensions/flicker/dlg-import-from-flickr.c
index 2b527ed..27954e4 100644
--- a/extensions/flicker/dlg-import-from-flickr.c
+++ b/extensions/flicker/dlg-import-from-flickr.c
@@ -425,7 +425,7 @@ photoset_combobox_changed_cb (GtkComboBox *widget,
}
-static GdkPixbufAnimation *
+static GthImage *
flickr_thumbnail_loader (GthFileData *file_data,
int requested_size,
int *original_width,
@@ -434,10 +434,10 @@ flickr_thumbnail_loader (GthFileData *file_data,
GCancellable *cancellable,
GError **error)
{
- GdkPixbufAnimation *animation = NULL;
- GthThumbLoader *thumb_loader = user_data;
- FlickrPhoto *photo;
- const char *uri = NULL;
+ GthImage *image = NULL;
+ GthThumbLoader *thumb_loader = user_data;
+ FlickrPhoto *photo;
+ const char *uri = NULL;
photo = (FlickrPhoto *) g_file_info_get_attribute_object (file_data->info, "flickr::object");
requested_size = gth_thumb_loader_get_requested_size (thumb_loader);
@@ -472,7 +472,8 @@ flickr_thumbnail_loader (GthFileData *file_data,
g_object_unref (pixbuf);
pixbuf = rotated;
- animation = gdk_pixbuf_non_anim_new (pixbuf);
+ image = gth_image_new ();
+ gth_image_set_pixbuf (image, pixbuf);
}
g_object_unref (pixbuf);
@@ -484,7 +485,7 @@ flickr_thumbnail_loader (GthFileData *file_data,
else
*error = g_error_new_literal (GTH_ERROR, 0, "cannot generate the thumbnail");
- return animation;
+ return image;
}
diff --git a/extensions/image_print/gth-load-image-info-task.c b/extensions/image_print/gth-load-image-info-task.c
index 459673d..8446287 100644
--- a/extensions/image_print/gth-load-image-info-task.c
+++ b/extensions/image_print/gth-load-image-info-task.c
@@ -111,33 +111,38 @@ image_loader_ready_cb (GObject *source_object,
{
GthLoadImageInfoTask *self = user_data;
GthImageInfo *image_info;
- GdkPixbuf *pixbuf;
+ GthImage *image;
GError *error = NULL;
- gth_image_loader_load_image_finish (GTH_IMAGE_LOADER (source_object),
- result,
- &pixbuf,
- NULL,
- NULL,
- &error);
+ gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
+ result,
+ &image,
+ NULL,
+ NULL,
+ &error);
if (error == NULL)
g_cancellable_set_error_if_cancelled (gth_task_get_cancellable (GTH_TASK (self)), &error);
if (error == NULL) {
+ GdkPixbuf *pixbuf;
+
image_info = self->priv->images[self->priv->current];
+ pixbuf = gth_image_get_pixbuf (image);
if (pixbuf != NULL) {
gth_image_info_set_pixbuf (image_info, pixbuf);
g_object_unref (pixbuf);
}
}
- else if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_object_unref (image);
gth_task_completed (GTH_TASK (self), error);
return;
}
else
g_clear_error (&error);
+ g_object_unref (image);
continue_loading_image (self);
}
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index c0abb10..d44d5a7 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -287,12 +287,14 @@ viewer_key_press_cb (GtkWidget *widget,
static void
image_preloader_requested_ready_cb (GthImagePreloader *preloader,
GthFileData *requested,
- GdkPixbufAnimation *animation,
+ GthImage *image,
int original_width,
int original_height,
GError *error,
GthImageViewerPage *self)
{
+ cairo_surface_t *surface;
+
if (! _g_file_equal (requested->file, self->priv->file_data->file))
return;
@@ -302,10 +304,14 @@ image_preloader_requested_ready_cb (GthImagePreloader *preloader,
}
gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
- gth_image_viewer_set_animation (GTH_IMAGE_VIEWER (self->priv->viewer),
- animation,
- original_width,
- original_height);
+
+ surface = gth_image_get_cairo_surface (image);
+ gth_image_viewer_set_image (GTH_IMAGE_VIEWER (self->priv->viewer),
+ surface,
+ original_width,
+ original_height);
+ cairo_surface_destroy (surface);
+
if (self->priv->shrink_wrap)
gth_image_viewer_page_shrink_wrap (self, TRUE);
gth_image_history_clear (self->priv->history);
@@ -784,8 +790,6 @@ gth_image_viewer_page_real_view (GthViewerPage *base,
GthFileData *next_file_data = NULL;
GthFileData *next2_file_data = NULL;
GthFileData *prev_file_data = NULL;
- int window_width;
- int window_height;
self = (GthImageViewerPage*) base;
g_return_if_fail (file_data != NULL);
@@ -825,13 +829,9 @@ gth_image_viewer_page_real_view (GthViewerPage *base,
prev_file_data = gth_file_store_get_file (file_store, &iter2);
}
- gtk_window_get_size (GTK_WINDOW (self->priv->browser),
- &window_width,
- &window_height);
-
gth_image_preloader_load (self->priv->preloader,
self->priv->file_data,
- (gth_image_prelaoder_get_load_policy (self->priv->preloader) == GTH_LOAD_POLICY_TWO_STEPS) ? MAX (window_width, window_height) : -1,
+ -1,
next_file_data,
next2_file_data,
prev_file_data,
diff --git a/extensions/picasaweb/dlg-import-from-picasaweb.c b/extensions/picasaweb/dlg-import-from-picasaweb.c
index feccd04..29be8fc 100644
--- a/extensions/picasaweb/dlg-import-from-picasaweb.c
+++ b/extensions/picasaweb/dlg-import-from-picasaweb.c
@@ -863,7 +863,7 @@ album_combobox_changed_cb (GtkComboBox *widget,
}
-GdkPixbufAnimation *
+GthImage *
picasa_web_thumbnail_loader (GthFileData *file_data,
int requested_size,
int *original_width,
@@ -872,10 +872,10 @@ picasa_web_thumbnail_loader (GthFileData *file_data,
GCancellable *cancellable,
GError **error)
{
- GdkPixbufAnimation *animation = NULL;
- GthThumbLoader *thumb_loader = user_data;
- PicasaWebPhoto *photo;
- const char *uri;
+ GthImage *image = NULL;
+ GthThumbLoader *thumb_loader = user_data;
+ PicasaWebPhoto *photo;
+ const char *uri;
photo = (PicasaWebPhoto *) g_file_info_get_attribute_object (file_data->info, "gphoto::object");
requested_size = gth_thumb_loader_get_requested_size (thumb_loader);
@@ -910,7 +910,8 @@ picasa_web_thumbnail_loader (GthFileData *file_data,
g_object_unref (pixbuf);
pixbuf = rotated;
- animation = gdk_pixbuf_non_anim_new (pixbuf);
+ image = gth_image_new ();
+ gth_image_set_pixbuf (image, pixbuf);
}
g_object_unref (pixbuf);
@@ -922,7 +923,7 @@ picasa_web_thumbnail_loader (GthFileData *file_data,
else
*error = g_error_new_literal (GTH_ERROR, 0, "cannot generate the thumbnail");
- return animation;
+ return image;
}
diff --git a/extensions/raw_files/main.c b/extensions/raw_files/main.c
index 74b3e0f..b060627 100644
--- a/extensions/raw_files/main.c
+++ b/extensions/raw_files/main.c
@@ -181,13 +181,13 @@ openraw_get_pixbuf_from_file (GthFileData *file_data,
}
-static GdkPixbufAnimation *
+static GthImage *
openraw_pixbuf_animation_new_from_file (GthFileData *file_data,
int requested_size,
GError **error)
{
- GdkPixbufAnimation *animation;
- GdkPixbuf *pixbuf;
+ GthImage *image = NULL;
+ GdkPixbuf *pixbuf;
if (requested_size == 0)
pixbuf = openraw_extract_thumbnail_from_file (file_data, requested_size, error);
@@ -195,13 +195,12 @@ openraw_pixbuf_animation_new_from_file (GthFileData *file_data,
pixbuf = openraw_get_pixbuf_from_file (file_data, error);
if (pixbuf != NULL) {
- animation = gdk_pixbuf_non_anim_new (pixbuf);
+ image = gth_image_new ();
+ gth_image_set_pixbuf (image, pixbuf);
g_object_unref (pixbuf);
}
- else
- animation = NULL;
- return animation;
+ return image;
}
@@ -268,7 +267,7 @@ get_file_mtime (const char *path)
}
-static GdkPixbufAnimation *
+static GthImage *
openraw_pixbuf_animation_new_from_file (GthFileData *file_data,
int requested_size,
int *original_width,
@@ -277,17 +276,17 @@ openraw_pixbuf_animation_new_from_file (GthFileData *file_data,
GCancellable *cancellable,
GError **error)
{
- GdkPixbufAnimation *animation;
- GdkPixbuf *pixbuf;
- gboolean is_thumbnail;
- gboolean is_raw;
- gboolean is_hdr;
- char *local_file;
- char *local_file_md5;
- char *cache_file;
- char *cache_file_esc;
- char *local_file_esc;
- char *command = NULL;
+ GthImage *image = NULL;
+ GdkPixbuf *pixbuf;
+ gboolean is_thumbnail;
+ gboolean is_raw;
+ gboolean is_hdr;
+ char *local_file;
+ char *local_file_md5;
+ char *cache_file;
+ char *cache_file_esc;
+ char *local_file_esc;
+ char *command = NULL;
is_thumbnail = requested_size > 0;
is_raw = _g_mime_type_is_raw (gth_file_data_get_mime_type (file_data));
@@ -424,19 +423,17 @@ openraw_pixbuf_animation_new_from_file (GthFileData *file_data,
}
if (pixbuf != NULL) {
- animation = gdk_pixbuf_non_anim_new (pixbuf);
+ image = gth_image_new ();
+ gth_image_set_pixbuf (image, pixbuf);
g_object_unref (pixbuf);
}
- else
- animation = NULL;
-
g_free (cache_file_esc);
g_free (local_file_esc);
g_free (cache_file);
g_free (local_file);
- return animation;
+ return image;
}
@@ -446,17 +443,18 @@ openraw_pixbuf_animation_new_from_file (GthFileData *file_data,
G_MODULE_EXPORT void
gthumb_extension_activate (void)
{
- gth_main_register_pixbuf_loader (openraw_pixbuf_animation_new_from_file,
- "image/x-adobe-dng",
- "image/x-canon-cr2",
- "image/x-canon-crw",
- "image/x-epson-erf",
- "image/x-minolta-mrw",
- "image/x-nikon-nef",
- "image/x-olympus-orf",
- "image/x-pentax-pef",
- "image/x-sony-arw",
- NULL);
+ gth_main_register_image_loader_func (openraw_pixbuf_animation_new_from_file,
+ GTH_IMAGE_FORMAT_GDK_PIXBUF,
+ "image/x-adobe-dng",
+ "image/x-canon-cr2",
+ "image/x-canon-crw",
+ "image/x-epson-erf",
+ "image/x-minolta-mrw",
+ "image/x-nikon-nef",
+ "image/x-olympus-orf",
+ "image/x-pentax-pef",
+ "image/x-sony-arw",
+ NULL);
}
diff --git a/extensions/slideshow/gth-slideshow.c b/extensions/slideshow/gth-slideshow.c
index aa1b55f..b875127 100644
--- a/extensions/slideshow/gth-slideshow.c
+++ b/extensions/slideshow/gth-slideshow.c
@@ -232,14 +232,13 @@ view_next_image_automatically (GthSlideshow *self)
static void
image_preloader_requested_ready_cb (GthImagePreloader *preloader,
GthFileData *requested,
- GdkPixbufAnimation *animation,
+ GthImage *image,
int original_width,
int original_height,
GError *error,
gpointer user_data)
{
GthSlideshow *self = user_data;
- GdkPixbuf *static_image;
if (error != NULL) {
g_clear_error (&error);
@@ -248,12 +247,7 @@ image_preloader_requested_ready_cb (GthImagePreloader *preloader,
}
_g_object_unref (self->priv->current_pixbuf);
-
- static_image = gdk_pixbuf_animation_get_static_image (animation);
- if (static_image != NULL)
- self->priv->current_pixbuf = gdk_pixbuf_copy (static_image);
- else
- self->priv->current_pixbuf = NULL;
+ self->priv->current_pixbuf = gth_image_get_pixbuf (image);
if (self->priv->current_pixbuf == NULL) {
_gth_slideshow_load_next_image (self);
diff --git a/extensions/webalbums/gth-web-exporter.c b/extensions/webalbums/gth-web-exporter.c
index 6f68417..b95ecb5 100644
--- a/extensions/webalbums/gth-web-exporter.c
+++ b/extensions/webalbums/gth-web-exporter.c
@@ -2552,14 +2552,15 @@ image_loader_ready_cb (GObject *source_object,
{
GthWebExporter *self = user_data;
ImageData *idata;
+ GthImage *image;
GdkPixbuf *pixbuf;
- if (! gth_image_loader_load_image_finish (GTH_IMAGE_LOADER (source_object),
- result,
- &pixbuf,
- NULL,
- NULL,
- NULL))
+ if (! gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
+ result,
+ &image,
+ NULL,
+ NULL,
+ NULL))
{
load_next_file (self);
return;
@@ -2569,6 +2570,7 @@ image_loader_ready_cb (GObject *source_object,
/* image */
+ pixbuf = gth_image_get_pixbuf (image);
idata->image = g_object_ref (pixbuf);
if (self->priv->copy_images && self->priv->resize_images) {
int w = gdk_pixbuf_get_width (pixbuf);
@@ -2665,6 +2667,7 @@ image_loader_ready_cb (GObject *source_object,
self->priv->saving_timeout = g_idle_add (save_image_preview, self);
g_object_unref (pixbuf);
+ g_object_unref (image);
}
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index b24c9c6..a1e44a0 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -64,6 +64,7 @@ PUBLIC_HEADER_FILES = \
gth-hook.h \
gth-icon-cache.h \
gth-icon-view.h \
+ gth-image.h \
gth-image-dragger.h \
gth-image-history.h \
gth-image-loader.h \
@@ -182,6 +183,7 @@ gthumb_SOURCES = \
gth-hook.c \
gth-icon-cache.c \
gth-icon-view.c \
+ gth-image.c \
gth-image-dragger.c \
gth-image-history.c \
gth-image-loader.c \
diff --git a/gthumb/gth-image-loader.c b/gthumb/gth-image-loader.c
index f650f45..2ef664a 100644
--- a/gthumb/gth-image-loader.c
+++ b/gthumb/gth-image-loader.c
@@ -34,10 +34,11 @@
struct _GthImageLoaderPrivate {
- gboolean as_animation; /* Whether to load the image in a
- * GdkPixbufAnimation structure. */
- PixbufLoader loader_func;
- gpointer loader_data;
+ gboolean as_animation; /* Whether to load the image in a
+ * GdkPixbufAnimation structure. */
+ GthImageFormat preferred_format;
+ GthImageLoaderFunc loader_func;
+ gpointer loader_data;
};
@@ -72,6 +73,7 @@ gth_image_loader_init (GthImageLoader *self)
self->priv->as_animation = FALSE;
self->priv->loader_func = NULL;
self->priv->loader_data = NULL;
+ self->priv->preferred_format = GTH_IMAGE_FORMAT_GDK_PIXBUF;
}
@@ -104,8 +106,8 @@ gth_image_loader_get_type (void)
GthImageLoader *
-gth_image_loader_new (PixbufLoader loader_func,
- gpointer loader_data)
+gth_image_loader_new (GthImageLoaderFunc loader_func,
+ gpointer loader_data)
{
GthImageLoader *self;
@@ -117,9 +119,9 @@ gth_image_loader_new (PixbufLoader loader_func,
void
-gth_image_loader_set_loader_func (GthImageLoader *self,
- PixbufLoader loader_func,
- gpointer loader_data)
+gth_image_loader_set_loader_func (GthImageLoader *self,
+ GthImageLoaderFunc loader_func,
+ gpointer loader_data)
{
g_return_if_fail (self != NULL);
@@ -128,6 +130,15 @@ gth_image_loader_set_loader_func (GthImageLoader *self,
}
+void
+gth_image_loader_set_preferred_format (GthImageLoader *self,
+ GthImageFormat preferred_format)
+{
+ g_return_if_fail (self != NULL);
+ self->priv->preferred_format = preferred_format;
+}
+
+
typedef struct {
GthFileData *file_data;
int requested_size;
@@ -161,17 +172,17 @@ load_data_unref (LoadData *load_data)
typedef struct {
- GdkPixbufAnimation *animation;
- int original_width;
- int original_height;
+ GthImage *image;
+ int original_width;
+ int original_height;
} LoadResult;
static void
load_result_unref (LoadResult *load_result)
{
- if (load_result->animation != NULL)
- g_object_unref (load_result->animation);
+ if (load_result->image != NULL)
+ g_object_unref (load_result->image);
g_free (load_result);
}
@@ -245,7 +256,7 @@ load_image_thread (gpointer user_data)
GSimpleAsyncResult *result = user_data;
LoadData *load_data;
GthImageLoader *self;
- GdkPixbufAnimation *animation;
+ GthImage *image;
int original_width;
int original_height;
GError *error = NULL;
@@ -265,37 +276,38 @@ load_image_thread (gpointer user_data)
}
self = (GthImageLoader *) g_async_result_get_source_object (G_ASYNC_RESULT (result));
- animation = NULL;
+ image = NULL;
original_width = -1;
original_height = -1;
if (self->priv->loader_func != NULL) {
- animation = (*self->priv->loader_func) (load_data->file_data,
- load_data->requested_size,
- &original_width,
- &original_height,
- self->priv->loader_data,
- load_data->cancellable,
- &error);
+ image = (*self->priv->loader_func) (load_data->file_data,
+ load_data->requested_size,
+ &original_width,
+ &original_height,
+ self->priv->loader_data,
+ load_data->cancellable,
+ &error);
}
else {
- PixbufLoader loader_func;
+ GthImageLoaderFunc loader_func;
- loader_func = gth_main_get_pixbuf_loader (gth_file_data_get_mime_type (load_data->file_data));
+ loader_func = gth_main_get_image_loader_func (gth_file_data_get_mime_type (load_data->file_data),
+ self->priv->preferred_format);
if (loader_func != NULL)
- animation = loader_func (load_data->file_data,
- load_data->requested_size,
- &original_width,
- &original_height,
- NULL,
- load_data->cancellable,
- &error);
+ image = loader_func (load_data->file_data,
+ load_data->requested_size,
+ &original_width,
+ &original_height,
+ NULL,
+ load_data->cancellable,
+ &error);
else
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("No suitable loader available for this file type"));
}
load_result = g_new0 (LoadResult, 1);
- load_result->animation = animation;
+ load_result->image = image;
load_result->original_width = original_width;
load_result->original_height = original_height;
@@ -390,12 +402,12 @@ gth_image_loader_load (GthImageLoader *loader,
gboolean
-gth_image_loader_load_animation_finish (GthImageLoader *loader,
- GAsyncResult *result,
- GdkPixbufAnimation **animation,
- int *original_width,
- int *original_height,
- GError **error)
+gth_image_loader_load_finish (GthImageLoader *loader,
+ GAsyncResult *result,
+ GthImage **image,
+ int *original_width,
+ int *original_height,
+ GError **error)
{
GSimpleAsyncResult *simple;
LoadResult *load_result;
@@ -408,8 +420,8 @@ gth_image_loader_load_animation_finish (GthImageLoader *loader,
return FALSE;
load_result = g_simple_async_result_get_op_res_gpointer (simple);
- if (animation != NULL)
- *animation = g_object_ref (load_result->animation);
+ if (image != NULL)
+ *image = g_object_ref (load_result->image);
if (original_width != NULL)
*original_width = load_result->original_width;
if (original_height != NULL)
@@ -417,40 +429,3 @@ gth_image_loader_load_animation_finish (GthImageLoader *loader,
return TRUE;
}
-
-
-gboolean
-gth_image_loader_load_image_finish (GthImageLoader *loader,
- GAsyncResult *res,
- GdkPixbuf **pixbuf,
- int *original_width,
- int *original_height,
- GError **error)
-{
- GdkPixbufAnimation *animation;
- GdkPixbuf *static_image;
-
- if (! gth_image_loader_load_animation_finish (loader,
- res,
- &animation,
- original_width,
- original_height,
- error))
- {
- return FALSE;
- }
-
- static_image = gdk_pixbuf_animation_get_static_image (animation);
- if (static_image != NULL) {
- *pixbuf = gdk_pixbuf_copy (static_image);
- }
- else {
- *pixbuf = NULL;
- if (error != NULL)
- *error = g_error_new_literal (GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED, "No image");
- }
-
- g_object_unref (animation);
-
- return TRUE;
-}
diff --git a/gthumb/gth-image-loader.h b/gthumb/gth-image-loader.h
index 25d65d0..57252b8 100644
--- a/gthumb/gth-image-loader.h
+++ b/gthumb/gth-image-loader.h
@@ -25,7 +25,7 @@
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "gth-file-data.h"
-#include "pixbuf-io.h"
+#include "gth-image.h"
G_BEGIN_DECLS
@@ -50,11 +50,13 @@ struct _GthImageLoaderClass {
};
GType gth_image_loader_get_type (void);
-GthImageLoader * gth_image_loader_new (PixbufLoader loader_func,
+GthImageLoader * gth_image_loader_new (GthImageLoaderFunc loader_func,
gpointer loader_data);
void gth_image_loader_set_loader_func (GthImageLoader *loader,
- PixbufLoader loader_func,
+ GthImageLoaderFunc loader_func,
gpointer loader_data);
+void gth_image_loader_set_preferred_format (GthImageLoader *loader,
+ GthImageFormat preferred_format);
void gth_image_loader_load (GthImageLoader *loader,
GthFileData *file_data,
int requested_size,
@@ -62,15 +64,9 @@ void gth_image_loader_load (GthImageLoader
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-gboolean gth_image_loader_load_animation_finish (GthImageLoader *loader,
+gboolean gth_image_loader_load_finish (GthImageLoader *loader,
GAsyncResult *res,
- GdkPixbufAnimation **animation,
- int *original_width,
- int *original_height,
- GError **error);
-gboolean gth_image_loader_load_image_finish (GthImageLoader *loader,
- GAsyncResult *res,
- GdkPixbuf **pixbuf,
+ GthImage **image,
int *original_width,
int *original_height,
GError **error);
diff --git a/gthumb/gth-image-preloader.c b/gthumb/gth-image-preloader.c
index 856f102..1f14ba1 100644
--- a/gthumb/gth-image-preloader.c
+++ b/gthumb/gth-image-preloader.c
@@ -49,7 +49,7 @@ typedef struct {
gboolean loaded;
gboolean error;
GthImageLoader *loader;
- GdkPixbufAnimation *animation;
+ GthImage *image;
int original_width;
int original_height;
guint token;
@@ -99,7 +99,8 @@ preloader_new (GthImagePreloader *self)
preloader->loaded = FALSE;
preloader->error = FALSE;
preloader->loader = gth_image_loader_new (NULL, NULL);
- preloader->animation = NULL;
+ gth_image_loader_set_preferred_format (preloader->loader, GTH_IMAGE_FORMAT_CAIRO_SURFACE);
+ preloader->image = NULL;
preloader->original_width = -1;
preloader->original_height = -1;
@@ -112,7 +113,7 @@ preloader_free (Preloader *preloader)
{
if (preloader == NULL)
return;
- _g_object_unref (preloader->animation);
+ _g_object_unref (preloader->image);
_g_object_unref (preloader->loader);
_g_object_unref (preloader->file_data);
g_free (preloader);
@@ -145,7 +146,7 @@ preloader_has_valid_content_for_file (Preloader *preloader,
return ((preloader->file_data != NULL)
&& preloader->loaded
&& ! preloader->error
- && (preloader->animation != NULL)
+ && (preloader->image != NULL)
&& g_file_equal (preloader->file_data->file, file_data->file)
&& (_g_time_val_cmp (gth_file_data_get_modification_time (file_data),
gth_file_data_get_modification_time (preloader->file_data)) == 0));
@@ -172,8 +173,8 @@ preloader_needs_second_step (Preloader *preloader)
&& ! preloader->error
&& (preloader->requested_size != -1)
&& ((preloader->original_width > preloader->requested_size) || (preloader->original_height > preloader->requested_size))
- && (preloader->animation != NULL)
- && gdk_pixbuf_animation_is_static_image (preloader->animation));
+ && (preloader->image != NULL)
+ && ! gth_image_is_animation (preloader->image));
}
@@ -396,25 +397,25 @@ image_loader_ready_cb (GObject *source_object,
LoadRequest *load_request = user_data;
Preloader *preloader = load_request->preloader;
GthImagePreloader *self = preloader->self;
- GdkPixbufAnimation *animation = NULL;
+ GthImage *image;
int original_width;
int original_height;
GError *error = NULL;
gboolean success;
int interval;
- success = gth_image_loader_load_animation_finish (GTH_IMAGE_LOADER (source_object),
- result,
- &animation,
- &original_width,
- &original_height,
- &error);
+ success = gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
+ result,
+ &image,
+ &original_width,
+ &original_height,
+ &error);
if (! g_file_equal (load_request->file_data->file, preloader->file_data->file)
|| (preloader->token != self->priv->token))
{
load_request_free (load_request);
- _g_object_unref (animation);
+ g_object_unref (image);
if (error != NULL)
g_error_free (error);
return;
@@ -422,8 +423,8 @@ image_loader_ready_cb (GObject *source_object,
interval = NOT_REQUESTED_INTERVAL;
- _g_object_unref (preloader->animation);
- preloader->animation = _g_object_ref (animation);
+ _g_object_unref (preloader->image);
+ preloader->image = g_object_ref (image);
preloader->original_width = original_width;
preloader->original_height = original_height;
preloader->loaded = success;
@@ -439,7 +440,7 @@ image_loader_ready_cb (GObject *source_object,
gth_image_preloader_signals[preloader_signal_to_emit (preloader)],
0,
preloader->file_data,
- preloader->animation,
+ preloader->image,
preloader->original_width,
preloader->original_height,
error);
@@ -461,7 +462,7 @@ image_loader_ready_cb (GObject *source_object,
self->priv->load_id = g_timeout_add (interval, load_next, self);
load_request_free (load_request);
- _g_object_unref (animation);
+ g_object_unref (image);
}
@@ -524,8 +525,8 @@ start_next_loader (GthImagePreloader *self)
}
#endif
- _g_object_unref (preloader->animation);
- preloader->animation = NULL;
+ _g_object_unref (preloader->image);
+ preloader->image = NULL;
load_request = g_new0 (LoadRequest, 1);
load_request->preloader = preloader;
@@ -622,7 +623,7 @@ assign_loaders (LoadData *load_data)
gth_image_preloader_signals[preloader_signal_to_emit (preloader)],
0,
preloader->file_data,
- preloader->animation,
+ preloader->image,
preloader->original_width,
preloader->original_height,
NULL);
diff --git a/gthumb/gth-image-preloader.h b/gthumb/gth-image-preloader.h
index da42106..0278654 100644
--- a/gthumb/gth-image-preloader.h
+++ b/gthumb/gth-image-preloader.h
@@ -56,13 +56,13 @@ struct _GthImagePreloaderClass {
void (* requested_ready) (GthImagePreloader *preloader,
GthFileData *requested,
- GdkPixbufAnimation *animation,
+ GthImage *image,
int original_width,
int original_height,
GError *error);
void (* original_size_ready) (GthImagePreloader *preloader,
GthFileData *requested,
- GdkPixbufAnimation *animation,
+ GthImage *image,
int original_width,
int original_height,
GError *error);
diff --git a/gthumb/gth-image.c b/gthumb/gth-image.c
new file mode 100644
index 0000000..717e9ad
--- /dev/null
+++ b/gthumb/gth-image.c
@@ -0,0 +1,280 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2011 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define GDK_PIXBUF_ENABLE_BACKEND 1
+
+#include <glib.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "cairo-utils.h"
+#include "glib-utils.h"
+#include "gth-image.h"
+#include "pixbuf-utils.h"
+
+
+struct _GthImagePrivate {
+ GthImageFormat format;
+ union {
+ cairo_surface_t *surface;
+ GdkPixbuf *pixbuf;
+ GdkPixbufAnimation *pixbuf_animation;
+ } data;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+_gth_image_free_data (GthImage *self)
+{
+ switch (self->priv->format) {
+ case GTH_IMAGE_FORMAT_CAIRO_SURFACE:
+ cairo_surface_destroy (self->priv->data.surface);
+ self->priv->data.surface = NULL;
+ break;
+
+ case GTH_IMAGE_FORMAT_GDK_PIXBUF:
+ _g_object_unref (self->priv->data.pixbuf);
+ self->priv->data.pixbuf = NULL;
+ break;
+
+ case GTH_IMAGE_FORMAT_GDK_PIXBUF_ANIMATION:
+ _g_object_unref (self->priv->data.pixbuf_animation);
+ self->priv->data.pixbuf_animation = NULL;
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+static void
+gth_image_finalize (GObject *object)
+{
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GTH_IS_IMAGE (object));
+
+ _gth_image_free_data (GTH_IMAGE (object));
+
+ /* Chain up */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gth_image_class_init (GthImageClass *class)
+{
+ GObjectClass *gobject_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (GthImagePrivate));
+
+ gobject_class = (GObjectClass*) class;
+ gobject_class->finalize = gth_image_finalize;
+}
+
+
+static void
+gth_image_instance_init (GthImage *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_IMAGE, GthImagePrivate);
+ self->priv->format = GTH_IMAGE_FORMAT_CAIRO_SURFACE;
+ self->priv->data.surface = NULL;
+}
+
+
+GType
+gth_image_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthImageClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_image_class_init,
+ NULL,
+ NULL,
+ sizeof (GthImage),
+ 0,
+ (GInstanceInitFunc) gth_image_instance_init
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "GthImage",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+GthImage *
+gth_image_new (void)
+{
+ return (GthImage *) g_object_new (GTH_TYPE_IMAGE, NULL);
+}
+
+
+void
+gth_image_set_cairo_surface (GthImage *image,
+ cairo_surface_t *value)
+{
+ _gth_image_free_data (image);
+ if (value == NULL)
+ return;
+
+ image->priv->format = GTH_IMAGE_FORMAT_CAIRO_SURFACE;
+ image->priv->data.surface = cairo_surface_reference (value);
+}
+
+
+cairo_surface_t *
+gth_image_get_cairo_surface (GthImage *image)
+{
+ cairo_surface_t *result = NULL;
+
+ switch (image->priv->format) {
+ case GTH_IMAGE_FORMAT_CAIRO_SURFACE:
+ result = cairo_surface_reference (image->priv->data.surface);
+ break;
+
+ case GTH_IMAGE_FORMAT_GDK_PIXBUF:
+ result = _cairo_image_surface_create_from_pixbuf (image->priv->data.pixbuf);
+ break;
+
+ case GTH_IMAGE_FORMAT_GDK_PIXBUF_ANIMATION:
+ if (image->priv->data.pixbuf_animation != NULL) {
+ GdkPixbuf *static_image;
+
+ static_image = gdk_pixbuf_animation_get_static_image (image->priv->data.pixbuf_animation);
+ result = _cairo_image_surface_create_from_pixbuf (static_image);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+
+void
+gth_image_set_pixbuf (GthImage *image,
+ GdkPixbuf *value)
+{
+ _gth_image_free_data (image);
+ if (value == NULL)
+ return;
+
+ image->priv->format = GTH_IMAGE_FORMAT_GDK_PIXBUF;
+ image->priv->data.pixbuf = g_object_ref (value);
+}
+
+
+GdkPixbuf *
+gth_image_get_pixbuf (GthImage *image)
+{
+ GdkPixbuf *result = NULL;
+
+ switch (image->priv->format) {
+ case GTH_IMAGE_FORMAT_CAIRO_SURFACE:
+ result = _gdk_pixbuf_new_from_cairo_surface (image->priv->data.surface);
+ break;
+
+ case GTH_IMAGE_FORMAT_GDK_PIXBUF:
+ result = g_object_ref (image->priv->data.pixbuf);
+ break;
+
+ case GTH_IMAGE_FORMAT_GDK_PIXBUF_ANIMATION:
+ if (image->priv->data.pixbuf_animation != NULL) {
+ GdkPixbuf *static_image;
+
+ static_image = gdk_pixbuf_animation_get_static_image (image->priv->data.pixbuf_animation);
+ if (static_image != NULL)
+ result = gdk_pixbuf_copy (static_image);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+
+void
+gth_image_set_pixbuf_animation (GthImage *image,
+ GdkPixbufAnimation *value)
+{
+ _gth_image_free_data (image);
+ if (value == NULL)
+ return;
+
+ image->priv->format = GTH_IMAGE_FORMAT_GDK_PIXBUF_ANIMATION;
+ image->priv->data.pixbuf_animation = g_object_ref (value);
+}
+
+
+GdkPixbufAnimation *
+gth_image_get_pixbuf_animation (GthImage *image)
+{
+ GdkPixbufAnimation *result = NULL;
+
+ switch (image->priv->format) {
+ case GTH_IMAGE_FORMAT_CAIRO_SURFACE:
+ if (image->priv->data.surface != NULL) {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = _gdk_pixbuf_new_from_cairo_surface (image->priv->data.surface);
+ result = gdk_pixbuf_non_anim_new (pixbuf);
+
+ g_object_unref (pixbuf);
+ }
+ break;
+
+ case GTH_IMAGE_FORMAT_GDK_PIXBUF:
+ result = gdk_pixbuf_non_anim_new (image->priv->data.pixbuf);
+ break;
+
+ case GTH_IMAGE_FORMAT_GDK_PIXBUF_ANIMATION:
+ result = _g_object_ref (image->priv->data.pixbuf);
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+
+gboolean
+gth_image_is_animation (GthImage *image)
+{
+ return ((image->priv->format == GTH_IMAGE_FORMAT_GDK_PIXBUF_ANIMATION)
+ && (! gdk_pixbuf_animation_is_static_image (image->priv->data.pixbuf_animation)));
+}
diff --git a/gthumb/gth-image.h b/gthumb/gth-image.h
new file mode 100644
index 0000000..9230a3d
--- /dev/null
+++ b/gthumb/gth-image.h
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2011 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTH_IMAGE_H
+#define GTH_IMAGE_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "gth-file-data.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+ GTH_IMAGE_FORMAT_CAIRO_SURFACE,
+ GTH_IMAGE_FORMAT_GDK_PIXBUF,
+ GTH_IMAGE_FORMAT_GDK_PIXBUF_ANIMATION,
+ GTH_IMAGE_N_FORMATS
+} GthImageFormat;
+
+#define GTH_TYPE_IMAGE (gth_image_get_type ())
+#define GTH_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_IMAGE, GthImage))
+#define GTH_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_IMAGE, GthImageClass))
+#define GTH_IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_IMAGE))
+#define GTH_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_IMAGE))
+#define GTH_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_IMAGE, GthImageClass))
+
+typedef struct _GthImage GthImage;
+typedef struct _GthImageClass GthImageClass;
+typedef struct _GthImagePrivate GthImagePrivate;
+
+struct _GthImage
+{
+ GObject __parent;
+ GthImagePrivate *priv;
+};
+
+struct _GthImageClass
+{
+ GObjectClass __parent_class;
+};
+
+
+typedef GthImage * (*GthImageLoaderFunc) (GthFileData *file_data,
+ int requested_size,
+ int *original_width,
+ int *original_height,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **error);
+
+
+GType gth_image_get_type (void);
+GthImage * gth_image_new (void);
+void gth_image_set_cairo_surface (GthImage *image,
+ cairo_surface_t *value);
+cairo_surface_t * gth_image_get_cairo_surface (GthImage *image);
+void gth_image_set_pixbuf (GthImage *image,
+ GdkPixbuf *value);
+GdkPixbuf * gth_image_get_pixbuf (GthImage *image);
+void gth_image_set_pixbuf_animation (GthImage *image,
+ GdkPixbufAnimation *value);
+GdkPixbufAnimation * gth_image_get_pixbuf_animation (GthImage *image);
+gboolean gth_image_is_animation (GthImage *image);
+
+G_END_DECLS
+
+#endif /* GTH_IMAGE_H */
diff --git a/gthumb/gth-main-default-types.c b/gthumb/gth-main-default-types.c
index 511df17..037b301 100644
--- a/gthumb/gth-main-default-types.c
+++ b/gthumb/gth-main-default-types.c
@@ -44,7 +44,10 @@ gth_main_register_default_file_loader (void)
mime_types = gdk_pixbuf_format_get_mime_types (format);
for (i = 0; mime_types[i] != NULL; i++)
- gth_main_register_pixbuf_loader (gth_pixbuf_animation_new_from_file, mime_types[i], NULL);
+ gth_main_register_image_loader_func (gth_pixbuf_animation_new_from_file,
+ (g_content_type_is_a (mime_types[i], "image/gif") ? GTH_IMAGE_FORMAT_GDK_PIXBUF_ANIMATION : GTH_IMAGE_FORMAT_GDK_PIXBUF),
+ mime_types[i],
+ NULL);
g_strfreev (mime_types);
}
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index 23db90e..28ea727 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -104,7 +104,7 @@ struct _GthMainPrivate
GHashTable *metadata_info_hash;
gboolean metadata_info_sorted;
GHashTable *sort_types;
- GHashTable *loaders;
+ GHashTable *image_loaders;
GHashTable *types;
GHashTable *classes;
GHashTable *objects_order;
@@ -135,8 +135,8 @@ gth_main_finalize (GObject *object)
if (gth_main->priv->sort_types != NULL)
g_hash_table_unref (gth_main->priv->sort_types);
- if (gth_main->priv->loaders != NULL)
- g_hash_table_unref (gth_main->priv->loaders);
+ if (gth_main->priv->image_loaders != NULL)
+ g_hash_table_unref (gth_main->priv->image_loaders);
if (gth_main->priv->types != NULL)
g_hash_table_unref (gth_main->priv->types);
if (gth_main->priv->classes != NULL)
@@ -175,11 +175,11 @@ static void
gth_main_init (GthMain *main)
{
main->priv = g_new0 (GthMainPrivate, 1);
- main->priv->sort_types = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- NULL,
- NULL);
- main->priv->loaders = g_hash_table_new (g_str_hash, (GEqualFunc) g_content_type_equals);
+ main->priv->sort_types = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+ main->priv->image_loaders = g_hash_table_new_full (g_str_hash,
+ (GEqualFunc) g_content_type_equals,
+ g_free,
+ NULL);
main->priv->metadata_category = g_ptr_array_new ();
main->priv->metadata_info = g_ptr_array_new ();
main->priv->metadata_info_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
@@ -743,9 +743,10 @@ _gth_main_create_type_spec (GType object_type,
void
-gth_main_register_pixbuf_loader (PixbufLoader loader,
- const char *first_mime_type,
- ...)
+gth_main_register_image_loader_func (GthImageLoaderFunc loader,
+ GthImageFormat native_format,
+ const char *first_mime_type,
+ ...)
{
va_list var_args;
const char *mime_type;
@@ -755,7 +756,11 @@ gth_main_register_pixbuf_loader (PixbufLoader loader,
va_start (var_args, first_mime_type);
mime_type = first_mime_type;
while (mime_type != NULL) {
- g_hash_table_insert (Main->priv->loaders, (gpointer) get_static_string (g_content_type_from_mime_type (mime_type)), loader);
+ char *key;
+
+ key = g_strdup_printf ("%s-%d", mime_type, native_format);
+ g_hash_table_insert (Main->priv->image_loaders, (gpointer) key, loader);
+
mime_type = va_arg (var_args, const char *);
}
va_end (var_args);
@@ -764,13 +769,31 @@ gth_main_register_pixbuf_loader (PixbufLoader loader,
}
-PixbufLoader
-gth_main_get_pixbuf_loader (const char *mime_type)
+GthImageLoaderFunc
+gth_main_get_image_loader_func (const char *mime_type,
+ GthImageFormat preferred_format)
{
- if (mime_type != NULL)
- return (PixbufLoader) g_hash_table_lookup (Main->priv->loaders, mime_type);
- else
- return NULL;
+ GthImageLoaderFunc loader;
+ char *key;
+ int format;
+
+ /* give priority to the preferred format */
+
+ key = g_strdup_printf ("%s-%d", mime_type, preferred_format);
+ loader = g_hash_table_lookup (Main->priv->image_loaders, key);
+
+ /* if the preferred format is not available, search another
+ * format. */
+
+ for (format = 0; (loader == NULL) && (format < GTH_IMAGE_N_FORMATS); format++) {
+ g_free (key);
+ key = g_strdup_printf ("%s-%d", mime_type, format);
+ loader = g_hash_table_lookup (Main->priv->image_loaders, key);
+ }
+
+ g_free (key);
+
+ return loader;
}
diff --git a/gthumb/gth-main.h b/gthumb/gth-main.h
index df7458c..00d6a01 100644
--- a/gthumb/gth-main.h
+++ b/gthumb/gth-main.h
@@ -30,6 +30,7 @@
#include "gth-file-source.h"
#include "gth-filter-file.h"
#include "gth-hook.h"
+#include "gth-image.h"
#include "gth-metadata-provider.h"
#include "gth-monitor.h"
#include "gth-pixbuf-saver.h"
@@ -85,10 +86,12 @@ GList * gth_main_get_all_metadata_info (void);
void gth_main_register_sort_type (GthFileDataSort *sort_type);
GthFileDataSort * gth_main_get_sort_type (const char *name);
GList * gth_main_get_all_sort_types (void);
-void gth_main_register_pixbuf_loader (PixbufLoader loader,
+void gth_main_register_image_loader_func (GthImageLoaderFunc loader,
+ GthImageFormat native_format,
const char *first_mime_type,
...);
-PixbufLoader gth_main_get_pixbuf_loader (const char *mime_type);
+GthImageLoaderFunc gth_main_get_image_loader_func (const char *mime_type,
+ GthImageFormat preferred_format);
GthPixbufSaver * gth_main_get_pixbuf_saver (const char *mime_type);
GthTest * gth_main_get_general_filter (void);
GthTest * gth_main_add_general_filter (GthTest *filter);
diff --git a/gthumb/gth-overwrite-dialog.c b/gthumb/gth-overwrite-dialog.c
index 607a2ac..e34ed37 100644
--- a/gthumb/gth-overwrite-dialog.c
+++ b/gthumb/gth-overwrite-dialog.c
@@ -124,19 +124,22 @@ image_loader_ready_cb (GObject *source_object,
{
GthOverwriteDialog *self = user_data;
GError *error = NULL;
+ GthImage *image;
GdkPixbuf *pixbuf;
GtkWidget *viewer;
- if (! gth_image_loader_load_image_finish (GTH_IMAGE_LOADER (source_object),
- result,
- &pixbuf,
- NULL,
- NULL,
- &error))
+ if (! gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
+ result,
+ &image,
+ NULL,
+ NULL,
+ &error))
{
return;
}
+ pixbuf = gth_image_get_pixbuf (image);
+
if (GTH_IMAGE_LOADER (source_object) == self->priv->old_image_loader)
viewer = self->priv->old_image_viewer;
else
@@ -144,6 +147,7 @@ image_loader_ready_cb (GObject *source_object,
gth_image_viewer_set_pixbuf (GTH_IMAGE_VIEWER (viewer), pixbuf, -1, -1);
g_object_unref (pixbuf);
+ g_object_unref (image);
}
diff --git a/gthumb/gth-thumb-loader.c b/gthumb/gth-thumb-loader.c
index 350724f..17e2c60 100644
--- a/gthumb/gth-thumb-loader.c
+++ b/gthumb/gth-thumb-loader.c
@@ -139,7 +139,7 @@ gth_thumb_loader_get_type (void)
}
-static GdkPixbufAnimation *
+static GthImage *
generate_thumbnail (GthFileData *file_data,
int requested_size,
int *original_width,
@@ -148,10 +148,10 @@ generate_thumbnail (GthFileData *file_data,
GCancellable *cancellable,
GError **error)
{
- GthThumbLoader *self = user_data;
- GdkPixbuf *pixbuf = NULL;
- GdkPixbufAnimation *animation;
- char *uri;
+ GthThumbLoader *self = user_data;
+ GdkPixbuf *pixbuf = NULL;
+ GthImage *image;
+ char *uri;
if (original_width != NULL)
*original_width = -1;
@@ -159,7 +159,7 @@ generate_thumbnail (GthFileData *file_data,
if (original_height != NULL)
*original_height = -1;
- animation = NULL;
+ image = NULL;
uri = g_file_get_uri (file_data->file);
pixbuf = gnome_desktop_thumbnail_factory_generate_no_script (self->priv->thumb_factory,
uri,
@@ -174,17 +174,17 @@ generate_thumbnail (GthFileData *file_data,
}
if (pixbuf == NULL) {
- PixbufLoader thumbnailer;
+ GthImageLoaderFunc thumbnailer;
- thumbnailer = gth_main_get_pixbuf_loader (gth_file_data_get_mime_type (file_data));
+ thumbnailer = gth_main_get_image_loader_func (gth_file_data_get_mime_type (file_data), GTH_IMAGE_FORMAT_GDK_PIXBUF);
if (thumbnailer != NULL)
- animation = thumbnailer (file_data,
- self->priv->cache_max_size,
- original_width,
- original_height,
- NULL,
- cancellable,
- error);
+ image = thumbnailer (file_data,
+ self->priv->cache_max_size,
+ original_width,
+ original_height,
+ NULL,
+ cancellable,
+ error);
}
if (pixbuf != NULL) {
@@ -195,21 +195,24 @@ generate_thumbnail (GthFileData *file_data,
if (error != NULL)
g_clear_error (error);
- animation = gdk_pixbuf_non_anim_new (pixbuf);
+
+ image = gth_image_new ();
+ gth_image_set_pixbuf (image, pixbuf);
+
g_object_unref (pixbuf);
}
- if (animation == NULL)
+ if (image == NULL)
if (error != NULL)
*error = g_error_new_literal (GTH_ERROR, 0, "Cannot generate the thumbnail");
g_free (uri);
- return animation;
+ return image;
}
-static GdkPixbufAnimation *
+static GthImage *
load_cached_thumbnail (GthFileData *file_data,
int requested_size,
int *original_width,
@@ -218,20 +221,21 @@ load_cached_thumbnail (GthFileData *file_data,
GCancellable *cancellable,
GError **error)
{
- GdkPixbufAnimation *animation = NULL;
- char *filename;
- GdkPixbuf *pixbuf;
+ GthImage *image = NULL;
+ char *filename;
+ GdkPixbuf *pixbuf;
filename = g_file_get_path (file_data->file);
pixbuf = gdk_pixbuf_new_from_file (filename, error);
if (pixbuf != NULL) {
- animation = gdk_pixbuf_non_anim_new (pixbuf);
+ image = gth_image_new ();
+ gth_image_set_pixbuf (image, pixbuf);
g_object_unref (pixbuf);
}
g_free (filename);
- return animation;
+ return image;
}
@@ -258,8 +262,8 @@ gth_thumb_loader_new (int requested_size)
void
-gth_thumb_loader_set_loader_func (GthThumbLoader *self,
- PixbufLoader loader_func)
+gth_thumb_loader_set_loader_func (GthThumbLoader *self,
+ GthImageLoaderFunc loader_func)
{
gth_image_loader_set_loader_func (self->priv->tloader,
(loader_func != NULL) ? loader_func : generate_thumbnail,
@@ -426,18 +430,19 @@ cache_image_ready_cb (GObject *source_object,
{
LoadData *load_data = user_data;
GthThumbLoader *self = load_data->thumb_loader;
+ GthImage *image;
GdkPixbuf *pixbuf;
int width;
int height;
gboolean modified;
LoadResult *load_result;
- if (! gth_image_loader_load_image_finish (GTH_IMAGE_LOADER (source_object),
- res,
- &pixbuf,
- NULL,
- NULL,
- NULL))
+ if (! gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
+ res,
+ &image,
+ NULL,
+ NULL,
+ NULL))
{
/* error loading the thumbnail from the cache, try to generate
* the thumbnail loading the original image. */
@@ -456,6 +461,8 @@ cache_image_ready_cb (GObject *source_object,
/* Thumbnail correctly loaded from the cache. Scale if the user wants
* a different size. */
+ pixbuf = gth_image_get_pixbuf (image);
+
g_return_if_fail (pixbuf != NULL);
width = gdk_pixbuf_get_width (pixbuf);
@@ -477,6 +484,7 @@ cache_image_ready_cb (GObject *source_object,
g_simple_async_result_complete_in_idle (load_data->simple);
load_data_unref (load_data);
+ g_object_unref (image);
}
@@ -729,15 +737,16 @@ original_image_ready_cb (GObject *source_object,
{
LoadData *load_data = user_data;
GthThumbLoader *self = load_data->thumb_loader;
+ GthImage *image;
GdkPixbuf *pixbuf = NULL;
GError *error = NULL;
- if (! gth_image_loader_load_image_finish (GTH_IMAGE_LOADER (source_object),
- res,
- &pixbuf,
- NULL,
- NULL,
- &error))
+ if (! gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
+ res,
+ &image,
+ NULL,
+ NULL,
+ &error))
{
/* error loading the original image, try with the system
* thumbnailer */
@@ -781,9 +790,11 @@ original_image_ready_cb (GObject *source_object,
return;
}
+ pixbuf = gth_image_get_pixbuf (image);
original_image_loaded_correctly (self, load_data, pixbuf);
g_object_unref (pixbuf);
+ g_object_unref (image);
load_data_unref (load_data);
}
diff --git a/gthumb/gth-thumb-loader.h b/gthumb/gth-thumb-loader.h
index ef40bc7..56f8c21 100644
--- a/gthumb/gth-thumb-loader.h
+++ b/gthumb/gth-thumb-loader.h
@@ -55,7 +55,7 @@ struct _GthThumbLoaderClass
GType gth_thumb_loader_get_type (void);
GthThumbLoader * gth_thumb_loader_new (int requested_size);
void gth_thumb_loader_set_loader_func (GthThumbLoader *self,
- PixbufLoader loader_func);
+ GthImageLoaderFunc loader_func);
void gth_thumb_loader_set_requested_size (GthThumbLoader *self,
int size);
int gth_thumb_loader_get_requested_size (GthThumbLoader *self);
diff --git a/gthumb/pixbuf-io.c b/gthumb/pixbuf-io.c
index 5567dae..9610ad0 100644
--- a/gthumb/pixbuf-io.c
+++ b/gthumb/pixbuf-io.c
@@ -334,7 +334,7 @@ pixbuf_loader_size_prepared_cb (GdkPixbufLoader *loader,
#endif
-GdkPixbuf *
+GthImage *
gth_pixbuf_new_from_file (GthFileData *file_data,
int requested_size,
int *original_width,
@@ -344,6 +344,7 @@ gth_pixbuf_new_from_file (GthFileData *file_data,
GError **error)
{
#ifndef USE_PIXBUF_LOADER
+ GthImage *image;
GdkPixbuf *pixbuf = NULL;
char *path;
gboolean scale_pixbuf;
@@ -402,7 +403,12 @@ gth_pixbuf_new_from_file (GthFileData *file_data,
g_free (path);
- return pixbuf;
+ image = gth_image_new ();
+ gth_image_set_pixbuf (image, pixbuf);
+
+ g_object_unref (pixbuf);
+
+ return image;
#else
@@ -471,7 +477,7 @@ gth_pixbuf_new_from_file (GthFileData *file_data,
}
-GdkPixbufAnimation *
+GthImage *
gth_pixbuf_animation_new_from_file (GthFileData *file_data,
int requested_size,
int *original_width,
@@ -480,40 +486,35 @@ gth_pixbuf_animation_new_from_file (GthFileData *file_data,
GCancellable *cancellable,
GError **error)
{
- GdkPixbufAnimation *animation = NULL;
- const char *mime_type;
+ GthImage *image = NULL;
+ const char *mime_type;
mime_type = gth_file_data_get_mime_type (file_data);
if (mime_type == NULL)
return NULL;
if (g_content_type_equals (mime_type, "image/gif")) {
- char *path;
+ GdkPixbufAnimation *animation;
+ char *path;
path = g_file_get_path (file_data->file);
if (path != NULL)
animation = gdk_pixbuf_animation_new_from_file (path, error);
- g_free (path);
+ image = gth_image_new ();
+ gth_image_set_pixbuf_animation (image, animation);
- return animation;
- }
- else {
- GdkPixbuf *pixbuf;
-
- pixbuf = gth_pixbuf_new_from_file (file_data,
- requested_size,
- original_width,
- original_height,
- FALSE,
- cancellable,
- error);
-
- if (pixbuf != NULL) {
- animation = gdk_pixbuf_non_anim_new (pixbuf);
- g_object_unref (pixbuf);
- }
+ g_object_unref (animation);
+ g_free (path);
}
-
- return animation;
+ else
+ image = gth_pixbuf_new_from_file (file_data,
+ requested_size,
+ original_width,
+ original_height,
+ FALSE,
+ cancellable,
+ error);
+
+ return image;
}
diff --git a/gthumb/pixbuf-io.h b/gthumb/pixbuf-io.h
index 8ff6af0..d4bacc6 100644
--- a/gthumb/pixbuf-io.h
+++ b/gthumb/pixbuf-io.h
@@ -63,15 +63,14 @@ void _gdk_pixbuf_save_async (GdkPixbuf *pixbuf,
gboolean replace,
GthFileDataFunc ready_func,
gpointer data);
-GdkPixbuf * gth_pixbuf_new_from_file (GthFileData *file,
+GthImage * gth_pixbuf_new_from_file (GthFileData *file,
int requested_size,
int *original_width,
int *original_height,
gboolean scale_to_original,
GCancellable *cancellable,
GError **error);
-GdkPixbufAnimation *
- gth_pixbuf_animation_new_from_file (GthFileData *file_data,
+GthImage * gth_pixbuf_animation_new_from_file (GthFileData *file_data,
int requested_size,
int *original_width,
int *original_height,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]