[gnome-photos] utils: Add photos_utils_file_copy_as_thumbnail



commit 15d079e878268482763944fef5012c58125a6433
Author: Debarshi Ray <debarshir gnome org>
Date:   Tue Feb 14 14:33:10 2017 +0100

    utils: Add photos_utils_file_copy_as_thumbnail
    
    This is meant to copy a pre-existing thumbnail image to its proper
    location with the necessary metadata and in the right format (ie. PNG).
    Remote items often have server-side thumbnails, but won't have the
    metadata that we need, or might not be in the format that we expect.
    A simple g_file_copy will copy a JPEG image to a thumbnail file with
    the '*.png' extension. That's not good. It can trigger strange corner
    cases in various MIME-type detection code. Now that we are changing
    the location of our thumbnail cache, it is a good time to address this
    and avoiding a whole class of bugs.

 src/photos-utils.c |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/photos-utils.h |    8 ++++++
 2 files changed, 77 insertions(+), 0 deletions(-)
---
diff --git a/src/photos-utils.c b/src/photos-utils.c
index f2b613c..691deb6 100644
--- a/src/photos-utils.c
+++ b/src/photos-utils.c
@@ -733,6 +733,75 @@ photos_utils_eval_radial_line (gdouble crop_center_x,
 }
 
 
+gboolean
+photos_utils_file_copy_as_thumbnail (GFile *source,
+                                     GFile *destination,
+                                     const gchar *original_uri,
+                                     gint64 original_height,
+                                     gint64 original_width,
+                                     GCancellable *cancellable,
+                                     GError **error)
+{
+  GFileInputStream *istream = NULL;
+  GFileOutputStream *ostream = NULL;
+  GdkPixbuf *pixbuf = NULL;
+  gboolean ret_val = FALSE;
+  const gchar *prgname;
+  gchar *original_height_str = NULL;
+  gchar *original_width_str = NULL;
+
+  g_return_val_if_fail (G_IS_FILE (source), FALSE);
+  g_return_val_if_fail (G_IS_FILE (destination), FALSE);
+  g_return_val_if_fail (original_uri != NULL && original_uri[0] != '\0', FALSE);
+  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  istream = g_file_read (source, cancellable, error);
+  if (istream == NULL)
+    goto out;
+
+  pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (istream), cancellable, error);
+  if (pixbuf == NULL)
+    goto out;
+
+  ostream = g_file_replace (destination,
+                            NULL,
+                            FALSE,
+                            G_FILE_CREATE_PRIVATE | G_FILE_CREATE_REPLACE_DESTINATION,
+                            cancellable,
+                            error);
+  if (ostream == NULL)
+    goto out;
+
+  original_height_str = g_strdup_printf ("%" G_GINT64_FORMAT, original_height);
+  original_width_str = g_strdup_printf ("%" G_GINT64_FORMAT, original_width);
+  prgname = g_get_prgname ();
+  if (!gdk_pixbuf_save_to_stream (pixbuf,
+                                  G_OUTPUT_STREAM (ostream),
+                                  "png",
+                                  cancellable,
+                                  error,
+                                  "tEXt::Software", prgname,
+                                  "tEXt::Thumb::URI", original_uri,
+                                  "tEXt::Thumb::Image::Height", original_height_str,
+                                  "tEXt::Thumb::Image::Width", original_width_str,
+                                  NULL))
+    {
+      goto out;
+    }
+
+  ret_val = TRUE;
+
+ out:
+  g_free (original_height_str);
+  g_free (original_width_str);
+  g_clear_object (&istream);
+  g_clear_object (&ostream);
+  g_clear_object (&pixbuf);
+  return ret_val;
+}
+
+
 static void
 photos_utils_file_query_info_data_free (PhotosUtilsFileQueryInfoData *data)
 {
diff --git a/src/photos-utils.h b/src/photos-utils.h
index 5ab3fc6..466fffe 100644
--- a/src/photos-utils.h
+++ b/src/photos-utils.h
@@ -101,6 +101,14 @@ gdouble          photos_utils_eval_radial_line            (gdouble crop_center_x
                                                            gdouble corner_y,
                                                            gdouble event_x);
 
+gboolean         photos_utils_file_copy_as_thumbnail      (GFile *source,
+                                                           GFile *destination,
+                                                           const gchar *original_uri,
+                                                           gint64 original_height,
+                                                           gint64 original_width,
+                                                           GCancellable *cancellable,
+                                                           GError **error);
+
 void             photos_utils_file_query_info_async       (GFile *file,
                                                            const gchar *attributes,
                                                            GFileQueryInfoFlags flags,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]