[gthumb] thumbnailer: save the original image size into the thumbnail



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]