[gthumb] thumbnailer: save the original image size into the thumbnail
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] thumbnailer: save the original image size into the thumbnail
- Date: Sat, 9 Nov 2013 19:55:45 +0000 (UTC)
commit 1d2ffdaa055d4c52d842885d3c940a588082979c
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Sep 14 18:03:40 2013 +0200
thumbnailer: save the original image size into the thumbnail
extensions/cairo_io/cairo-image-surface-jpeg.c | 41 ++++++---------
extensions/cairo_io/cairo-image-surface-png.c | 24 ++++++++
gthumb/cairo-utils.c | 24 ++++++++
gthumb/cairo-utils.h | 12 ++++-
gthumb/gth-thumb-loader.c | 69 ++++++++++++++---------
gthumb/pixbuf-utils.c | 21 +++++++
6 files changed, 138 insertions(+), 53 deletions(-)
---
diff --git a/extensions/cairo_io/cairo-image-surface-jpeg.c b/extensions/cairo_io/cairo-image-surface-jpeg.c
index 90e5f2a..0fe2a4d 100644
--- a/extensions/cairo_io/cairo-image-surface-jpeg.c
+++ b/extensions/cairo_io/cairo-image-surface-jpeg.c
@@ -147,8 +147,8 @@ GthImage *
_cairo_image_surface_create_from_jpeg (GInputStream *istream,
GthFileData *file_data,
int requested_size,
- int *original_width,
- int *original_height,
+ int *original_width_p,
+ int *original_height_p,
gpointer user_data,
GCancellable *cancellable,
GError **error)
@@ -511,6 +511,8 @@ _cairo_image_surface_create_from_jpeg (GInputStream *istream,
cairo_surface_mark_dirty (surface);
if (! g_cancellable_is_cancelled (cancellable)) {
+ int original_width;
+ int original_height;
/* Set the original dimensions */
@@ -519,35 +521,24 @@ _cairo_image_surface_create_from_jpeg (GInputStream *istream,
|| (orientation == GTH_TRANSFORM_TRANSPOSE)
|| (orientation == GTH_TRANSFORM_TRANSVERSE))
{
- if (original_width != NULL)
- *original_width = srcinfo.image_height;
- if (original_height != NULL)
- *original_height = srcinfo.image_width;
+ original_width = srcinfo.image_height;
+ original_height = srcinfo.image_width;
}
else {
- if (original_width != NULL)
- *original_width = srcinfo.image_width;
- if (original_height != NULL)
- *original_height = srcinfo.image_height;
+ original_width = srcinfo.image_width;
+ original_height = srcinfo.image_height;
}
- jpeg_finish_decompress (&srcinfo);
- jpeg_destroy_decompress (&srcinfo);
-
- /* Scale to the requested size */
- if (load_scaled) {
- cairo_surface_t *scaled;
- int width;
- int height;
+ metadata->original_width = original_width;
+ metadata->original_height = original_height;
- width = destination_width;
- height = destination_height;
- scale_keeping_ratio (&width, &height, requested_size, requested_size, TRUE);
- scaled = _cairo_image_surface_scale (surface, width, height, SCALE_FILTER_GOOD, NULL);
+ if (original_width_p != NULL)
+ *original_width_p = original_width;
+ if (original_height_p != NULL)
+ *original_height_p = original_height;
- cairo_surface_destroy (surface);
- surface = scaled;
- }
+ jpeg_finish_decompress (&srcinfo);
+ jpeg_destroy_decompress (&srcinfo);
/*_cairo_image_surface_set_attribute_int (surface, "Image::Rotation", rotation); FIXME*/
/* FIXME _cairo_image_surface_set_attribute (surface, "Jpeg::ColorSpace",
jpeg_color_space_name (srcinfo.jpeg_color_space)); */
diff --git a/extensions/cairo_io/cairo-image-surface-png.c b/extensions/cairo_io/cairo-image-surface-png.c
index b1283f1..4e4c126 100644
--- a/extensions/cairo_io/cairo-image-surface-png.c
+++ b/extensions/cairo_io/cairo-image-surface-png.c
@@ -149,6 +149,8 @@ _cairo_image_surface_create_from_png (GInputStream *istream,
int rowstride;
png_bytep *row_pointers;
int row;
+ png_textp text_ptr;
+ int num_texts;
image = gth_image_new ();
@@ -202,6 +204,8 @@ _cairo_image_surface_create_from_png (GInputStream *istream,
metadata = _cairo_image_surface_get_metadata (cairo_png_data->surface);
metadata->has_alpha = (color_type & PNG_COLOR_MASK_ALPHA);
+ metadata->original_width = width;
+ metadata->original_height = height;
/* Set the data transformations */
@@ -245,6 +249,26 @@ _cairo_image_surface_create_from_png (GInputStream *istream,
if (cairo_surface_status (cairo_png_data->surface) == CAIRO_STATUS_SUCCESS)
gth_image_set_cairo_surface (image, cairo_png_data->surface);
+ if (original_width != NULL)
+ *original_width = png_get_image_width (cairo_png_data->png_ptr, cairo_png_data->png_info_ptr);
+ if (original_height != NULL)
+ *original_height = png_get_image_height (cairo_png_data->png_ptr,
cairo_png_data->png_info_ptr);
+
+ if (png_get_text (cairo_png_data->png_ptr,
+ cairo_png_data->png_info_ptr,
+ &text_ptr,
+ &num_texts))
+ {
+ int i;
+
+ for (i = 0; i < num_texts; i++) {
+ if (strcmp (text_ptr[i].key, "Thumb::Image::Width") == 0)
+ metadata->thumbnail.image_width = atoi (text_ptr[i].text);
+ else if (strcmp (text_ptr[i].key, "Thumb::Image::Height") == 0)
+ metadata->thumbnail.image_height = atoi (text_ptr[i].text);
+ }
+ }
+
g_free (row_pointers);
_cairo_png_data_destroy (cairo_png_data);
diff --git a/gthumb/cairo-utils.c b/gthumb/cairo-utils.c
index 44f480d..b183faa 100644
--- a/gthumb/cairo-utils.c
+++ b/gthumb/cairo-utils.c
@@ -128,6 +128,11 @@ _cairo_image_surface_get_metadata (cairo_surface_t *surface)
metadata = cairo_surface_get_user_data (surface, &surface_metadata_key);
if (metadata == NULL) {
metadata = g_new0 (cairo_surface_metadata_t, 1);
+ metadata->has_alpha = FALSE;
+ metadata->original_width = 0;
+ metadata->original_height = 0;
+ metadata->thumbnail.image_width = 0;
+ metadata->thumbnail.image_height = 0;
cairo_surface_set_user_data (surface, &surface_metadata_key, metadata, surface_metadata_free);
}
@@ -135,6 +140,25 @@ _cairo_image_surface_get_metadata (cairo_surface_t *surface)
}
+void
+_cairo_image_surface_copy_metadata (cairo_surface_t *src,
+ cairo_surface_t *dest)
+{
+ cairo_surface_metadata_t *src_metadata;
+ cairo_surface_metadata_t *dest_metadata;
+
+ src_metadata = _cairo_image_surface_get_metadata (src);
+ dest_metadata = _cairo_image_surface_get_metadata (dest);
+
+ dest_metadata->has_alpha = src_metadata->has_alpha;
+ dest_metadata->original_width = src_metadata->original_width;
+ dest_metadata->original_height = src_metadata->original_height;
+ dest_metadata->thumbnail.image_width = src_metadata->thumbnail.image_width;
+ dest_metadata->thumbnail.image_height = src_metadata->thumbnail.image_height;
+
+}
+
+
gboolean
_cairo_image_surface_get_has_alpha (cairo_surface_t *surface)
{
diff --git a/gthumb/cairo-utils.h b/gthumb/cairo-utils.h
index 05e10e5..4f2d03d 100644
--- a/gthumb/cairo-utils.h
+++ b/gthumb/cairo-utils.h
@@ -131,7 +131,15 @@ typedef struct {
} cairo_color_255_t;
typedef struct {
- gboolean has_alpha;
+ int image_width;
+ int image_height;
+} thumbnail_metadata_t;
+
+typedef struct {
+ gboolean has_alpha;
+ int original_width;
+ int original_height;
+ thumbnail_metadata_t thumbnail;
} cairo_surface_metadata_t;
extern const unsigned char cairo_channel[4];
@@ -159,6 +167,8 @@ void _cairo_clear_surface (cairo_surface_t
unsigned char * _cairo_image_surface_flush_and_get_data (cairo_surface_t *surface);
cairo_surface_metadata_t *
_cairo_image_surface_get_metadata (cairo_surface_t *surface);
+void _cairo_image_surface_copy_metadata (cairo_surface_t *src,
+ cairo_surface_t *dest);
gboolean _cairo_image_surface_get_has_alpha (cairo_surface_t *surface);
cairo_surface_t * _cairo_image_surface_create (cairo_format_t format,
int width,
diff --git a/gthumb/gth-thumb-loader.c b/gthumb/gth-thumb-loader.c
index 7efe3cd..a1c688c 100644
--- a/gthumb/gth-thumb-loader.c
+++ b/gthumb/gth-thumb-loader.c
@@ -210,27 +210,17 @@ load_cached_thumbnail (GInputStream *istream,
GCancellable *cancellable,
GError **error)
{
- GthImage *image = NULL;
- char *filename;
- cairo_surface_t *surface;
-
if (file_data == NULL) {
- if (error != NULL)
- *error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, "Could not
load file");
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, "Could not load file");
return NULL;
}
- filename = g_file_get_path (file_data->file);
- surface = cairo_image_surface_create_from_png (filename);
- if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
- image = gth_image_new_for_surface (surface);
- else
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, cairo_status_to_string
(cairo_surface_status (surface)));
-
- cairo_surface_destroy (surface);
- g_free (filename);
-
- return image;
+ return gth_image_new_from_stream (istream,
+ requested_size,
+ original_width,
+ original_height,
+ cancellable,
+ error);
}
@@ -425,7 +415,12 @@ _cairo_image_surface_scale_for_thumbnail (cairo_surface_t *image,
int new_width,
int new_height)
{
- return _cairo_image_surface_scale (image, new_width, new_height, SCALE_FILTER_GOOD, NULL);
+ cairo_surface_t *scaled;
+
+ scaled = _cairo_image_surface_scale (image, new_width, new_height, SCALE_FILTER_GOOD, NULL);
+ _cairo_image_surface_copy_metadata (image, scaled);
+
+ return scaled;
}
@@ -520,10 +515,13 @@ is_a_cache_file (const char *uri)
static gboolean
_gth_thumb_loader_save_to_cache (GthThumbLoader *self,
GthFileData *file_data,
- cairo_surface_t *image)
+ cairo_surface_t *image,
+ int original_width,
+ int original_height)
{
- char *uri;
- GdkPixbuf *pixbuf;
+ char *uri;
+ cairo_surface_metadata_t *metadata;
+ GdkPixbuf *pixbuf;
if ((self == NULL) || (image == NULL))
return FALSE;
@@ -538,6 +536,11 @@ _gth_thumb_loader_save_to_cache (GthThumbLoader *self,
return FALSE;
}
+ if ((original_width > 0) && (original_height > 0)) {
+ metadata = _cairo_image_surface_get_metadata (image);
+ metadata->thumbnail.image_width = original_width;
+ metadata->thumbnail.image_height = original_height;
+ }
pixbuf = _gdk_pixbuf_new_from_cairo_surface (image);
if (pixbuf == NULL)
return FALSE;
@@ -556,7 +559,9 @@ _gth_thumb_loader_save_to_cache (GthThumbLoader *self,
static void
original_image_loaded_correctly (GthThumbLoader *self,
LoadData *load_data,
- cairo_surface_t *image)
+ cairo_surface_t *image,
+ int original_width,
+ int original_height)
{
cairo_surface_t *local_image;
int width;
@@ -587,7 +592,11 @@ original_image_loaded_correctly (GthThumbLoader *self,
cairo_surface_destroy (tmp);
}
- _gth_thumb_loader_save_to_cache (self, load_data->file_data, local_image);
+ _gth_thumb_loader_save_to_cache (self,
+ load_data->file_data,
+ local_image,
+ original_width,
+ original_height);
}
/* Scale if the user wants a different size. */
@@ -720,7 +729,7 @@ watch_thumbnailer_cb (GPid pid,
cairo_surface_t *surface;
surface = _cairo_image_surface_create_from_pixbuf (pixbuf);
- original_image_loaded_correctly (self, load_data, surface);
+ original_image_loaded_correctly (self, load_data, surface, 0, 0);
cairo_surface_destroy (surface);
g_object_unref (pixbuf);
@@ -738,14 +747,16 @@ original_image_ready_cb (GObject *source_object,
LoadData *load_data = user_data;
GthThumbLoader *self = load_data->thumb_loader;
GthImage *image = NULL;
+ int original_width;
+ int original_height;
cairo_surface_t *surface = NULL;
GError *error = NULL;
if (! gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
res,
&image,
- NULL,
- NULL,
+ &original_width,
+ &original_height,
&error))
{
/* error loading the original image, try with the system
@@ -791,7 +802,11 @@ original_image_ready_cb (GObject *source_object,
}
surface = gth_image_get_cairo_surface (image);
- original_image_loaded_correctly (self, load_data, surface);
+ original_image_loaded_correctly (self,
+ load_data,
+ surface,
+ original_width,
+ original_height);
cairo_surface_destroy (surface);
g_object_unref (image);
diff --git a/gthumb/pixbuf-utils.c b/gthumb/pixbuf-utils.c
index 4e729f1..ba1e971 100644
--- a/gthumb/pixbuf-utils.c
+++ b/gthumb/pixbuf-utils.c
@@ -24,6 +24,8 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
+#define GDK_PIXBUF_ENABLE_BACKEND 1
+#include <gdk-pixbuf/gdk-pixbuf.h>
#include "cairo-utils.h"
#include "pixbuf-utils.h"
@@ -87,6 +89,25 @@ _gdk_pixbuf_new_from_cairo_surface (cairo_surface_t *surface)
p_pixels += p_stride;
}
+ /* copy the known metadata from the surface to the pixbuf */
+
+ {
+ cairo_surface_metadata_t *metadata;
+
+ metadata = _cairo_image_surface_get_metadata (surface);
+ if ((metadata->thumbnail.image_width > 0) && (metadata->thumbnail.image_height > 0)) {
+ char *value;
+
+ value = g_strdup_printf ("%d", metadata->thumbnail.image_width);
+ gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Width", value);
+ g_free (value);
+
+ value = g_strdup_printf ("%d", metadata->thumbnail.image_height);
+ gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Height", value);
+ g_free (value);
+ }
+ }
+
return pixbuf;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]