[gthumb] image history: save a GthImage to preserve the icc profile
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] image history: save a GthImage to preserve the icc profile
- Date: Fri, 6 Feb 2015 09:58:42 +0000 (UTC)
commit fa3eb2ea4b5b13410d34981169a86a435bae96e7
Author: Paolo Bacchilega <paobac src gnome org>
Date: Thu Feb 5 18:16:26 2015 +0100
image history: save a GthImage to preserve the icc profile
extensions/file_tools/gth-file-tool-resize.c | 8 +-
extensions/image_viewer/gth-image-viewer-page.c | 57 ++++++---
gthumb/gth-image-history.c | 34 ++++--
gthumb/gth-image-history.h | 53 +++++----
gthumb/gth-image-preloader.c | 4 +-
gthumb/gth-image-preloader.h | 2 +-
gthumb/gth-image.c | 153 +++++++++++++++++++++--
gthumb/gth-image.h | 3 +
8 files changed, 248 insertions(+), 66 deletions(-)
---
diff --git a/extensions/file_tools/gth-file-tool-resize.c b/extensions/file_tools/gth-file-tool-resize.c
index 5136840..7319f94 100644
--- a/extensions/file_tools/gth-file-tool-resize.c
+++ b/extensions/file_tools/gth-file-tool-resize.c
@@ -117,10 +117,10 @@ resize_task_completed_cb (GthTask *task,
gth_image_viewer_page_set_image (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->new_image, FALSE);
if (self->priv->apply_to_original) {
- gth_image_history_add_image (gth_image_viewer_page_get_history (GTH_IMAGE_VIEWER_PAGE
(viewer_page)),
- self->priv->new_image,
- -1,
- TRUE);
+ gth_image_history_add_surface (gth_image_viewer_page_get_history (GTH_IMAGE_VIEWER_PAGE
(viewer_page)),
+ self->priv->new_image,
+ -1,
+ TRUE);
gth_viewer_page_focus (GTH_VIEWER_PAGE (viewer_page));
gth_file_tool_hide_options (GTH_FILE_TOOL (self));
}
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index 7ad6a5c..baf2ab1 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -1063,7 +1063,7 @@ preloader_load_ready_cb (GObject *source_object,
gth_image_history_clear (self->priv->history);
gth_image_history_add_image (self->priv->history,
- gth_image_viewer_get_current_image (GTH_IMAGE_VIEWER
(self->priv->viewer)),
+ image,
requested_size,
FALSE);
@@ -1504,21 +1504,20 @@ gth_image_viewer_page_real_save_as (GthViewerPage *base,
static void
_gth_image_viewer_page_set_image (GthImageViewerPage *self,
- cairo_surface_t *image,
+ GthImage *image,
int requested_size,
gboolean modified)
{
GthFileData *file_data;
int width;
int height;
- char *size;
if (image == NULL)
return;
if (modified)
gth_image_preloader_set_modified_image (self->priv->preloader, image);
- gth_image_viewer_set_surface (GTH_IMAGE_VIEWER (self->priv->viewer), image, -1, -1);
+ gth_image_viewer_set_image (GTH_IMAGE_VIEWER (self->priv->viewer), image, -1, -1);
gth_image_viewer_set_requested_size (GTH_IMAGE_VIEWER (self->priv->viewer), requested_size);
file_data = gth_browser_get_current_file (GTH_BROWSER (self->priv->browser));
@@ -1526,16 +1525,16 @@ _gth_image_viewer_page_set_image (GthImageViewerPage *self,
self->priv->image_changed = modified;
g_file_info_set_attribute_boolean (file_data->info, "gth::file::is-modified", modified);
- if (! _cairo_image_surface_get_original_size (image, &width, &height)) {
- width = cairo_image_surface_get_width (image);
- height = cairo_image_surface_get_height (image);
- }
- g_file_info_set_attribute_int32 (file_data->info, "image::width", width);
- g_file_info_set_attribute_int32 (file_data->info, "image::height", height);
+ if (gth_image_get_original_size (image, &width, &height)) {
+ char *size;
+
+ g_file_info_set_attribute_int32 (file_data->info, "image::width", width);
+ g_file_info_set_attribute_int32 (file_data->info, "image::height", height);
- size = g_strdup_printf (_("%d × %d"), width, height);
- g_file_info_set_attribute_string (file_data->info, "general::dimensions", size);
- g_free (size);
+ size = g_strdup_printf (_("%d × %d"), width, height);
+ g_file_info_set_attribute_string (file_data->info, "general::dimensions", size);
+ g_free (size);
+ }
gth_monitor_metadata_changed (gth_main_get_default_monitor (), file_data);
@@ -1544,6 +1543,21 @@ _gth_image_viewer_page_set_image (GthImageViewerPage *self,
static void
+_gth_image_viewer_page_set_surface (GthImageViewerPage *self,
+ cairo_surface_t *surface,
+ int requested_size,
+ gboolean modified)
+{
+ GthImage *image;
+
+ image = gth_image_new_for_surface (surface);
+ _gth_image_viewer_page_set_image (self, image, requested_size, modified);
+
+ g_object_unref (image);
+}
+
+
+static void
gth_image_viewer_page_real_revert (GthViewerPage *base)
{
GthImageViewerPage *self = GTH_IMAGE_VIEWER_PAGE (base);
@@ -1729,9 +1743,9 @@ gth_image_viewer_page_set_image (GthImageViewerPage *self,
return;
if (add_to_history)
- gth_image_history_add_image (self->priv->history, image, -1, TRUE);
+ gth_image_history_add_surface (self->priv->history, image, -1, TRUE);
- _gth_image_viewer_page_set_image (self, image, -1, TRUE);
+ _gth_image_viewer_page_set_surface (self, image, -1, TRUE);
if (add_to_history)
gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
@@ -2095,6 +2109,15 @@ gth_image_viewer_page_apply_icc_profile (GthImageViewerPage *self,
gth_image_preloader_clear_cache (self->priv->preloader);
file_data = gth_browser_get_current_file (self->priv->browser);
- if (file_data != NULL)
- _gth_image_viewer_page_load (self, file_data);
+ if (file_data == NULL)
+ return;
+
+ /* force a complete reload */
+ _g_object_unref (self->priv->last_loaded);
+ self->priv->last_loaded = NULL;
+
+ g_object_ref (file_data);
+ _gth_image_viewer_page_load (self, file_data);
+
+ g_object_unref (file_data);
}
diff --git a/gthumb/gth-image-history.c b/gthumb/gth-image-history.c
index d58c66d..35ed066 100644
--- a/gthumb/gth-image-history.c
+++ b/gthumb/gth-image-history.c
@@ -20,6 +20,7 @@
*/
#include <config.h>
+#include "glib-utils.h"
#include "gth-image-history.h"
@@ -33,9 +34,9 @@ G_DEFINE_TYPE (GthImageHistory, gth_image_history, G_TYPE_OBJECT)
GthImageData *
-gth_image_data_new (cairo_surface_t *image,
- int requested_size,
- gboolean unsaved)
+gth_image_data_new (GthImage *image,
+ int requested_size,
+ gboolean unsaved)
{
GthImageData *idata;
@@ -44,7 +45,7 @@ gth_image_data_new (cairo_surface_t *image,
idata = g_new0 (GthImageData, 1);
idata->ref = 1;
- idata->image = cairo_surface_reference (image);
+ idata->image = _g_object_ref (image);
idata->requested_size = requested_size;
idata->unsaved = unsaved;
@@ -68,7 +69,7 @@ gth_image_data_unref (GthImageData *idata)
idata->ref--;
if (idata->ref == 0) {
- cairo_surface_destroy (idata->image);
+ _g_object_unref (idata->image);
g_free (idata);
}
}
@@ -173,7 +174,7 @@ remove_first_image (GList **list)
static GList*
add_image_to_list (GList *list,
- cairo_surface_t *image,
+ GthImage *image,
int requested_size,
gboolean unsaved)
{
@@ -196,7 +197,7 @@ add_image_to_list (GList *list,
static void
add_image_to_undo_history (GthImageHistory *history,
- cairo_surface_t *image,
+ GthImage *image,
int requested_size,
gboolean unsaved)
{
@@ -209,7 +210,7 @@ add_image_to_undo_history (GthImageHistory *history,
static void
add_image_to_redo_history (GthImageHistory *history,
- cairo_surface_t *image,
+ GthImage *image,
int requested_size,
gboolean unsaved)
{
@@ -222,7 +223,7 @@ add_image_to_redo_history (GthImageHistory *history,
void
gth_image_history_add_image (GthImageHistory *history,
- cairo_surface_t *image,
+ GthImage *image,
int requested_size,
gboolean unsaved)
{
@@ -236,6 +237,21 @@ gth_image_history_add_image (GthImageHistory *history,
}
+void
+gth_image_history_add_surface (GthImageHistory *history,
+ cairo_surface_t *surface,
+ int requested_size,
+ gboolean unsaved)
+{
+ GthImage *image;
+
+ image = gth_image_new_for_surface (surface);
+ gth_image_history_add_image (history, image, requested_size, unsaved);
+
+ g_object_unref (image);
+}
+
+
GthImageData *
gth_image_history_undo (GthImageHistory *history)
{
diff --git a/gthumb/gth-image-history.h b/gthumb/gth-image-history.h
index ffd686d..9b1d605 100644
--- a/gthumb/gth-image-history.h
+++ b/gthumb/gth-image-history.h
@@ -25,6 +25,7 @@
#include <glib.h>
#include <glib-object.h>
#include <cairo.h>
+#include "gth-image.h"
G_BEGIN_DECLS
@@ -40,10 +41,10 @@ typedef struct _GthImageHistoryPrivate GthImageHistoryPrivate;
typedef struct _GthImageHistoryClass GthImageHistoryClass;
typedef struct {
- int ref;
- cairo_surface_t *image;
- int requested_size;
- gboolean unsaved;
+ int ref;
+ GthImage *image;
+ int requested_size;
+ gboolean unsaved;
} GthImageData;
struct _GthImageHistory {
@@ -59,26 +60,30 @@ struct _GthImageHistoryClass {
void (*changed) (GthImageHistory *image_history);
};
-GthImageData * gth_image_data_new (cairo_surface_t *image,
- int requested_size,
- gboolean unsaved);
-GthImageData * gth_image_data_ref (GthImageData *idata);
-void gth_image_data_unref (GthImageData *idata);
-void gth_image_data_list_free (GList *list);
-
-GType gth_image_history_get_type (void);
-GthImageHistory * gth_image_history_new (void);
-void gth_image_history_add_image (GthImageHistory *history,
- cairo_surface_t *image,
- int requested_size,
- gboolean unsaved);
-GthImageData * gth_image_history_undo (GthImageHistory *history);
-GthImageData * gth_image_history_redo (GthImageHistory *history);
-void gth_image_history_clear (GthImageHistory *history);
-gboolean gth_image_history_can_undo (GthImageHistory *history);
-gboolean gth_image_history_can_redo (GthImageHistory *history);
-GthImageData * gth_image_history_revert (GthImageHistory *history);
-GthImageData * gth_image_history_get_last (GthImageHistory *history);
+GthImageData * gth_image_data_new (GthImage *image,
+ int requested_size,
+ gboolean unsaved);
+GthImageData * gth_image_data_ref (GthImageData *idata);
+void gth_image_data_unref (GthImageData *idata);
+void gth_image_data_list_free (GList *list);
+
+GType gth_image_history_get_type (void);
+GthImageHistory * gth_image_history_new (void);
+void gth_image_history_add_image (GthImageHistory *history,
+ GthImage *image,
+ int requested_size,
+ gboolean unsaved);
+void gth_image_history_add_surface (GthImageHistory *history,
+ cairo_surface_t *image,
+ int requested_size,
+ gboolean unsaved);
+GthImageData * gth_image_history_undo (GthImageHistory *history);
+GthImageData * gth_image_history_redo (GthImageHistory *history);
+void gth_image_history_clear (GthImageHistory *history);
+gboolean gth_image_history_can_undo (GthImageHistory *history);
+gboolean gth_image_history_can_redo (GthImageHistory *history);
+GthImageData * gth_image_history_revert (GthImageHistory *history);
+GthImageData * gth_image_history_get_last (GthImageHistory *history);
G_END_DECLS
diff --git a/gthumb/gth-image-preloader.c b/gthumb/gth-image-preloader.c
index 537d10f..8768e21 100644
--- a/gthumb/gth-image-preloader.c
+++ b/gthumb/gth-image-preloader.c
@@ -866,7 +866,7 @@ gth_image_preloader_load_finish (GthImagePreloader *self,
void
gth_image_preloader_set_modified_image (GthImagePreloader *self,
- cairo_surface_t *image)
+ GthImage *image)
{
GList *scan;
CacheData *cache_data;
@@ -889,7 +889,7 @@ gth_image_preloader_set_modified_image (GthImagePreloader *self,
cache_data = cache_data_new ();
cache_data->file_data = GTH_MODIFIED_IMAGE;
- cache_data->image = gth_image_new_for_surface (image);
+ cache_data->image = g_object_ref (image);
cache_data->original_width = -1;
cache_data->original_height = -1;
cache_data->requested_size = -1;
diff --git a/gthumb/gth-image-preloader.h b/gthumb/gth-image-preloader.h
index 94e9e1f..d5de045 100644
--- a/gthumb/gth-image-preloader.h
+++ b/gthumb/gth-image-preloader.h
@@ -70,7 +70,7 @@ gboolean gth_image_preloader_load_finish (GthImagePreloader
*
int
*original_height,
GError **error);
void gth_image_preloader_set_modified_image (GthImagePreloader *self,
- cairo_surface_t *image);
+ GthImage *image);
cairo_surface_t * gth_image_preloader_get_modified_image (GthImagePreloader *self);
void gth_image_preloader_clear_cache (GthImagePreloader *self);
diff --git a/gthumb/gth-image.c b/gthumb/gth-image.c
index 1cee383..4b5fffb 100644
--- a/gthumb/gth-image.c
+++ b/gthumb/gth-image.c
@@ -33,6 +33,91 @@
#include "pixbuf-utils.h"
+/* -- GthICCData -- */
+
+
+#define GTH_TYPE_ICC_DATA (gth_icc_data_get_type ())
+#define GTH_ICC_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_ICC_DATA, GthICCData))
+#define GTH_ICC_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_ICC_DATA, GthICCDataClass))
+#define GTH_IS_ICC_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_ICC_DATA))
+#define GTH_IS_ICC_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_ICC_DATA))
+#define GTH_ICC_DATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_ICC_DATA, GthICCDataClass))
+
+typedef struct _GthICCData GthICCData;
+typedef struct _GthICCDataClass GthICCDataClass;
+
+struct _GthICCData {
+ GObject __parent;
+ GthICCProfile icc_profile;
+};
+
+struct _GthICCDataClass {
+ GObjectClass __parent_class;
+};
+
+
+static GType gth_icc_data_get_type (void);
+
+
+G_DEFINE_TYPE (GthICCData, gth_icc_data, G_TYPE_OBJECT)
+
+
+static void
+gth_icc_data_finalize (GObject *object)
+{
+ GthICCData *icc_data;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GTH_IS_ICC_DATA (object));
+
+ icc_data = GTH_ICC_DATA (object);
+ gth_icc_profile_free (icc_data->icc_profile);
+
+ /* Chain up */
+ G_OBJECT_CLASS (gth_icc_data_parent_class)->finalize (object);
+}
+
+
+static void
+gth_icc_data_class_init (GthICCDataClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = (GObjectClass*) klass;
+ gobject_class->finalize = gth_icc_data_finalize;
+}
+
+
+static void
+gth_icc_data_init (GthICCData *self)
+{
+ self->icc_profile = NULL;
+}
+
+
+static GthICCData *
+gth_icc_data_new (GthICCProfile profile)
+{
+ GthICCData *icc_data;
+
+ icc_data = g_object_new (GTH_TYPE_ICC_DATA, NULL);
+ icc_data->icc_profile = profile;
+
+ return icc_data;
+}
+
+
+static GthICCProfile
+gth_icc_data_get_profile (GthICCData *self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+ return self->icc_profile;
+}
+
+
+/* -- GthImage -- */
+
+
struct _GthImagePrivate {
GthImageFormat format;
union {
@@ -40,7 +125,7 @@ struct _GthImagePrivate {
GdkPixbuf *pixbuf;
GdkPixbufAnimation *pixbuf_animation;
} data;
- GthICCProfile icc_profile;
+ GthICCData *icc_data;
};
@@ -75,8 +160,8 @@ _gth_image_free_data (GthImage *self)
static void
_gth_image_free_icc_profile (GthImage *self)
{
- gth_icc_profile_free (self->priv->icc_profile);
- self->priv->icc_profile = NULL;
+ _g_object_unref (self->priv->icc_data);
+ self->priv->icc_data = NULL;
}
@@ -132,7 +217,7 @@ gth_image_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;
- self->priv->icc_profile = NULL;
+ self->priv->icc_data = NULL;
}
@@ -173,6 +258,7 @@ gth_image_copy (GthImage *image)
GthImage *new_image;
new_image = gth_image_new ();
+ gth_image_set_icc_profile (new_image, gth_image_get_icc_profile (image));
switch (image->priv->format) {
case GTH_IMAGE_FORMAT_CAIRO_SURFACE:
@@ -243,6 +329,45 @@ gth_image_get_cairo_surface (GthImage *image)
gboolean
+gth_image_get_original_size (GthImage *image,
+ int *width,
+ int *height)
+{
+ cairo_surface_t *surface;
+ int local_width;
+ int local_height;
+ gboolean value_set = FALSE;
+
+ switch (image->priv->format) {
+ case GTH_IMAGE_FORMAT_CAIRO_SURFACE:
+ surface = gth_image_get_cairo_surface (image);
+ if (! _cairo_image_surface_get_original_size (surface, &local_width, &local_height)) {
+ local_width = cairo_image_surface_get_width (surface);
+ local_height = cairo_image_surface_get_height (surface);
+ }
+ value_set = TRUE;
+ break;
+
+ case GTH_IMAGE_FORMAT_GDK_PIXBUF:
+ local_width = gdk_pixbuf_get_width (image->priv->data.pixbuf);
+ local_height = gdk_pixbuf_get_height (image->priv->data.pixbuf);
+ value_set = TRUE;
+ break;
+
+ case GTH_IMAGE_FORMAT_GDK_PIXBUF_ANIMATION:
+ if (image->priv->data.pixbuf_animation != NULL) {
+ local_width = gdk_pixbuf_animation_get_width (image->priv->data.pixbuf_animation);
+ local_height = gdk_pixbuf_animation_get_width (image->priv->data.pixbuf_animation);
+ value_set = TRUE;
+ }
+ break;
+ }
+
+ return value_set;
+}
+
+
+gboolean
gth_image_get_is_zoomable (GthImage *self)
{
if (self == NULL)
@@ -373,7 +498,8 @@ gth_image_set_icc_profile (GthImage *image,
GthICCProfile profile)
{
_gth_image_free_icc_profile (image);
- image->priv->icc_profile = profile;
+ if (profile != NULL)
+ image->priv->icc_data = gth_icc_data_new (profile);
}
@@ -381,7 +507,7 @@ GthICCProfile
gth_image_get_icc_profile (GthImage *image)
{
g_return_val_if_fail (image != NULL, NULL);
- return image->priv->icc_profile;
+ return (image->priv->icc_data != NULL) ? gth_icc_data_get_profile (image->priv->icc_data) : NULL;
}
@@ -406,6 +532,7 @@ gth_image_apply_icc_profile (GthImage *image,
{
#if HAVE_LCMS2
+ GthICCProfile image_profile;
cmsHTRANSFORM hTransform;
cairo_surface_t *surface;
unsigned char *surface_row;
@@ -414,10 +541,19 @@ gth_image_apply_icc_profile (GthImage *image,
int row_stride;
int row;
+ g_return_if_fail (image != NULL);
+
+ if (out_profile == NULL)
+ return;
+
+ image_profile = gth_image_get_icc_profile (image);
+ if (image_profile == NULL)
+ return;
+
if (image->priv->format != GTH_IMAGE_FORMAT_CAIRO_SURFACE)
return;
- hTransform = cmsCreateTransform ((cmsHPROFILE) image->priv->icc_profile,
+ hTransform = cmsCreateTransform ((cmsHPROFILE) image_profile,
_LCMS2_CAIRO_FORMAT,
(cmsHPROFILE) out_profile,
_LCMS2_CAIRO_FORMAT,
@@ -474,8 +610,7 @@ _gth_image_apply_icc_profile_thread (GSimpleAsyncResult *result,
GError *error = NULL;
apd = g_simple_async_result_get_op_res_gpointer (result);
- if ((apd->image->priv->icc_profile != NULL) && (apd->out_profile != NULL))
- gth_image_apply_icc_profile (apd->image, apd->out_profile, cancellable);
+ gth_image_apply_icc_profile (apd->image, apd->out_profile, cancellable);
if ((cancellable != NULL) && g_cancellable_is_cancelled (cancellable))
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "");
diff --git a/gthumb/gth-image.h b/gthumb/gth-image.h
index 9528b13..c55f9d8 100644
--- a/gthumb/gth-image.h
+++ b/gthumb/gth-image.h
@@ -88,6 +88,9 @@ GthImage * gth_image_copy (GthImage
void gth_image_set_cairo_surface (GthImage *image,
cairo_surface_t *value);
cairo_surface_t * gth_image_get_cairo_surface (GthImage *image);
+gboolean gth_image_get_original_size (GthImage *image,
+ int *width,
+ int *height);
gboolean gth_image_get_is_zoomable (GthImage *image);
gboolean gth_image_set_zoom (GthImage *image,
double zoom,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]