[gnome-photos] Add a zoom parameter to photos_base_item_save_async



commit 15bfbdf6e8c23acae5d5fd3af39f1b13605299c4
Author: Debarshi Ray <debarshir gnome org>
Date:   Tue Dec 29 11:19:29 2015 +0100

    Add a zoom parameter to photos_base_item_save_async
    
    The UX design expects the user to be able to optionally downscale the
    item when saving. This is a step in that direction.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=759363

 src/photos-application.c |    2 +-
 src/photos-base-item.c   |  140 +++++++++++++++++++++++++++++++++------------
 src/photos-base-item.h   |    1 +
 3 files changed, 104 insertions(+), 39 deletions(-)
---
diff --git a/src/photos-application.c b/src/photos-application.c
index 77121af..ffc1a0f 100644
--- a/src/photos-application.c
+++ b/src/photos-application.c
@@ -921,7 +921,7 @@ photos_application_save (PhotosApplication *self)
     }
 
   g_application_hold (G_APPLICATION (self));
-  photos_base_item_save_async (item, parent, NULL, photos_application_save_save, self);
+  photos_base_item_save_async (item, parent, 1.0, NULL, photos_application_save_save, self);
 
  out:
   g_free (parent_path);
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index b5657e7..0d454bd 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -126,6 +126,15 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (PhotosBaseItem, photos_base_item, G_TYPE_OBJEC
                                                          photos_base_item_filterable_iface_init));
 
 
+typedef struct _PhotosBaseItemSaveData PhotosBaseItemSaveData;
+
+struct _PhotosBaseItemSaveData
+{
+  GFile *dir;
+  GeglNode *buffer;
+  gchar *type;
+};
+
 static GdkPixbuf *failed_icon;
 static GdkPixbuf *thumbnailing_icon;
 static GThreadPool *create_thumbnail_pool;
@@ -134,6 +143,28 @@ static GThreadPool *create_thumbnail_pool;
 static void photos_base_item_populate_from_cursor (PhotosBaseItem *self, TrackerSparqlCursor *cursor);
 
 
+static PhotosBaseItemSaveData *
+photos_base_item_save_data_new (GFile *dir, const gchar *type)
+{
+  PhotosBaseItemSaveData *data;
+
+  data = g_slice_new0 (PhotosBaseItemSaveData);
+  data->dir = g_object_ref (dir);
+  data->type = g_strdup (type);
+  return data;
+}
+
+
+static void
+photos_base_item_save_data_free (PhotosBaseItemSaveData *data)
+{
+  g_object_unref (data->dir);
+  g_clear_object (&data->buffer);
+  g_free (data->type);
+  g_slice_free (PhotosBaseItemSaveData, data);
+}
+
+
 static GdkPixbuf *
 photos_base_item_create_placeholder_icon (const gchar *icon_name)
 {
@@ -1032,21 +1063,17 @@ static void
 photos_base_item_save_replace (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {
   GTask *task = G_TASK (user_data);
-  PhotosBaseItem *self;
-  PhotosBaseItemPrivate *priv;
   GCancellable *cancellable;
   GdkPixbuf *pixbuf = NULL;
   GError *error = NULL;
-  GeglNode *graph;
+  GeglNode *buffer_source;
+  GeglNode *graph = NULL;
   GFile *file = G_FILE (source_object);
   GFileOutputStream *stream = NULL;
-  const gchar *type;
-
-  self = PHOTOS_BASE_ITEM (g_task_get_source_object (task));
-  priv = self->priv;
+  PhotosBaseItemSaveData *data;
 
   cancellable = g_task_get_cancellable (task);
-  type = (const gchar *) g_task_get_task_data (task);
+  data = (PhotosBaseItemSaveData *) g_task_get_task_data (task);
 
   stream = g_file_replace_finish (file, res, &error);
   if (error != NULL)
@@ -1055,31 +1082,20 @@ photos_base_item_save_replace (GObject *source_object, GAsyncResult *res, gpoint
       goto out;
     }
 
-  if (priv->processor == NULL)
-    {
-      g_task_return_new_error (task, PHOTOS_ERROR, 0, "Failed to find a processor for the GEGL graph");
-      goto out;
-    }
-
-  if (gegl_processor_work (priv->processor, NULL))
-    {
-      g_task_return_new_error (task, PHOTOS_ERROR, 0, "Have not finished processing the GEGL graph");
-      goto out;
-    }
-
-  graph = photos_pipeline_get_graph (priv->pipeline);
-  pixbuf = photos_utils_create_pixbuf_from_node (graph);
+  graph = gegl_node_new ();
+  buffer_source = gegl_node_new_child (graph, "operation", "gegl:buffer-source", "buffer", data->buffer, 
NULL);
+  pixbuf = photos_utils_create_pixbuf_from_node (buffer_source);
   if (pixbuf == NULL)
     {
-      g_task_return_new_error (task, PHOTOS_ERROR, 0, "Failed to create a GdkPixbuf from the GEGL graph");
+      g_task_return_new_error (task, PHOTOS_ERROR, 0, "Failed to create a GdkPixbuf from the GeglBuffer");
       goto out;
     }
 
-  if (g_strcmp0 (type, "jpeg") == 0)
+  if (g_strcmp0 (data->type, "jpeg") == 0)
     {
       gdk_pixbuf_save_to_stream_async (pixbuf,
                                        G_OUTPUT_STREAM (stream),
-                                       type,
+                                       data->type,
                                        cancellable,
                                        photos_base_item_save_save_to_stream,
                                        g_object_ref (task),
@@ -1090,7 +1106,7 @@ photos_base_item_save_replace (GObject *source_object, GAsyncResult *res, gpoint
     {
       gdk_pixbuf_save_to_stream_async (pixbuf,
                                        G_OUTPUT_STREAM (stream),
-                                       type,
+                                       data->type,
                                        cancellable,
                                        photos_base_item_save_save_to_stream,
                                        g_object_ref (task),
@@ -1098,6 +1114,7 @@ photos_base_item_save_replace (GObject *source_object, GAsyncResult *res, gpoint
     }
 
  out:
+  g_clear_object (&graph);
   g_clear_object (&pixbuf);
   g_clear_object (&stream);
   g_object_unref (task);
@@ -1105,6 +1122,50 @@ photos_base_item_save_replace (GObject *source_object, GAsyncResult *res, gpoint
 
 
 static void
+photos_base_item_save_buffer_zoom (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+  GTask *task = G_TASK (user_data);
+  PhotosBaseItem *self;
+  GCancellable *cancellable;
+  GError *error;
+  GFile *file = NULL;
+  GeglBuffer *buffer = GEGL_BUFFER (source_object);
+  GeglBuffer *buffer_zoomed = NULL;
+  PhotosBaseItemSaveData *data;
+
+  self = PHOTOS_BASE_ITEM (g_task_get_source_object (task));
+  cancellable = g_task_get_cancellable (task);
+  data = (PhotosBaseItemSaveData *) g_task_get_task_data (task);
+
+  error = NULL;
+  buffer_zoomed = photos_utils_buffer_zoom_finish (buffer, res, &error);
+  if (error != NULL)
+    {
+      g_task_return_error (task, error);
+      goto out;
+    }
+
+  g_assert_null (data->buffer);
+  data->buffer = g_object_ref (buffer_zoomed);
+
+  file = g_file_get_child (data->dir, self->priv->filename);
+  g_file_replace_async (file,
+                        NULL,
+                        TRUE,
+                        G_FILE_CREATE_REPLACE_DESTINATION,
+                        G_PRIORITY_DEFAULT,
+                        cancellable,
+                        photos_base_item_save_replace,
+                        g_object_ref (task));
+
+ out:
+  g_clear_object (&buffer_zoomed);
+  g_clear_object (&file);
+  g_object_unref (task);
+}
+
+
+static void
 photos_base_item_set_thumbnailing_icon (PhotosBaseItem *self)
 {
   if (thumbnailing_icon == NULL)
@@ -2056,13 +2117,16 @@ photos_base_item_refresh (PhotosBaseItem *self)
 void
 photos_base_item_save_async (PhotosBaseItem *self,
                              GFile *dir,
+                             gdouble zoom,
                              GCancellable *cancellable,
                              GAsyncReadyCallback callback,
                              gpointer user_data)
 {
   PhotosBaseItemPrivate *priv;
-  GFile *file;
   GTask *task;
+  GeglBuffer *buffer;
+  GeglNode *graph;
+  PhotosBaseItemSaveData *data;
   gchar *type = NULL;
 
   g_return_if_fail (PHOTOS_IS_BASE_ITEM (self));
@@ -2077,22 +2141,22 @@ photos_base_item_save_async (PhotosBaseItem *self,
   type = photos_utils_get_pixbuf_type_from_mime_type (priv->mime_type);
   g_return_if_fail (type != NULL);
 
+  data = photos_base_item_save_data_new (dir, type);
+
   task = g_task_new (self, cancellable, callback, user_data);
   g_task_set_source_tag (task, photos_base_item_save_async);
-  g_task_set_task_data (task, g_strdup (type), g_free);
+  g_task_set_task_data (task, data, (GDestroyNotify) photos_base_item_save_data_free);
 
-  file = g_file_get_child (dir, priv->filename);
-  g_file_replace_async (file,
-                        NULL,
-                        TRUE,
-                        G_FILE_CREATE_REPLACE_DESTINATION,
-                        G_PRIORITY_DEFAULT,
-                        cancellable,
-                        photos_base_item_save_replace,
-                        g_object_ref (task));
+  graph = photos_pipeline_get_graph (priv->pipeline);
+  buffer = photos_utils_create_buffer_from_node (graph);
+  photos_utils_buffer_zoom_async (buffer,
+                                  zoom,
+                                  cancellable,
+                                  photos_base_item_save_buffer_zoom,
+                                  g_object_ref (task));
 
   g_free (type);
-  g_object_unref (file);
+  g_object_unref (buffer);
   g_object_unref (task);
 }
 
diff --git a/src/photos-base-item.h b/src/photos-base-item.h
index 8e1e418..54c8dae 100644
--- a/src/photos-base-item.h
+++ b/src/photos-base-item.h
@@ -219,6 +219,7 @@ void                photos_base_item_refresh                 (PhotosBaseItem *se
 
 void                photos_base_item_save_async              (PhotosBaseItem *self,
                                                               GFile *dir,
+                                                              gdouble zoom,
                                                               GCancellable *cancellable,
                                                               GAsyncReadyCallback callback,
                                                               gpointer user_data);


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