Commit 30e7b30b authored by Paolo Bacchilega's avatar Paolo Bacchilega
Browse files

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.
parent ba1b9f3b
......@@ -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);
......
......@@ -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;
}
......
......@@ -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);
}
......
......@@ -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,
......
......@@ -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;
}
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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 \
......
......@@ -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)