[gnome-photos/wip/rishi/edit-preview: 4/6] base-item: Add photos_base_item_create_preview



commit fa59109b875b536ff15379d2b987546ea4f92648
Author: Debarshi Ray <debarshir gnome org>
Date:   Mon Nov 23 20:57:51 2015 +0100

    base-item: Add photos_base_item_create_preview

 src/photos-base-item.c |  121 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/photos-base-item.h |    7 +++
 2 files changed, 128 insertions(+), 0 deletions(-)
---
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index 7ee60ad..6b175a1 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -30,6 +30,7 @@
 #include <string.h>
 
 #include <gdk/gdk.h>
+#include <gegl-plugin.h>
 #include <gio/gio.h>
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -1380,6 +1381,126 @@ photos_base_item_can_trash (PhotosBaseItem *self)
 }
 
 
+cairo_surface_t *
+photos_base_item_create_preview (PhotosBaseItem *self,
+                                 gint size,
+                                 gint scale,
+                                 const gchar *operation,
+                                 const gchar *first_property_name,
+                                 ...)
+{
+  PhotosBaseItemPrivate *priv = self->priv;
+  GeglBuffer *buffer = NULL;
+  GeglNode *buffer_source;
+  GeglNode *crop;
+  GeglNode *graph = NULL;
+  GeglNode *operation_node;
+  GeglOperation *op;
+  GeglProcessor *processor = NULL;
+  GeglRectangle bbox;
+  GeglRectangle roi;
+  cairo_surface_t *surface;
+  const Babl *format;
+  const gchar *name;
+  gdouble x;
+  gdouble y;
+  gdouble zoom;
+  gint level;
+  gint min_dimension;
+  gint size_scaled;
+  gint stride;
+  gint64 end;
+  gint64 start;
+  guchar *buf = NULL;
+  va_list ap;
+
+  g_return_val_if_fail (operation != NULL && operation[0] != '\0', NULL);
+  g_return_val_if_fail (priv->buffer_source != NULL, NULL);
+  g_return_val_if_fail (priv->edit_graph != NULL, NULL);
+  g_return_val_if_fail (priv->load_graph != NULL, NULL);
+
+  op = gegl_node_get_gegl_operation (priv->buffer_source);
+  g_return_val_if_fail (op != NULL, NULL);
+
+  name = gegl_operation_get_name (op);
+  g_return_val_if_fail (g_strcmp0 (name, "gegl:buffer-source") == 0, NULL);
+
+  bbox = gegl_node_get_bounding_box (priv->buffer_source);
+  min_dimension = bbox.height < bbox.width ? bbox.height : bbox.width;
+  size_scaled = size * scale;
+  zoom = (gdouble) size_scaled / (gdouble) min_dimension;
+  level = photos_utils_get_level_from_zoom (zoom);
+  g_message ("%d, %d, %lf", bbox.width, bbox.height, zoom);
+
+  format = gegl_operation_get_format (op, "output");
+  buffer = gegl_buffer_new (&bbox, format);
+
+  start = g_get_monotonic_time ();
+
+  gegl_node_blit_buffer (priv->buffer_source, buffer, &bbox, level, GEGL_ABYSS_NONE);
+
+  end = g_get_monotonic_time ();
+  photos_debug (PHOTOS_DEBUG_GEGL, "Create Preview: Node Blit: %" G_GINT64_FORMAT, end - start);
+
+  bbox = *gegl_buffer_get_extent (buffer);
+  min_dimension = bbox.height < bbox.width ? bbox.height : bbox.width;
+  x = (gdouble) (bbox.width - min_dimension) / 2.0;
+  y = (gdouble) (bbox.height - min_dimension) / 2.0;
+  zoom = (gdouble) size_scaled / (gdouble) min_dimension;
+  g_message ("%d, %d, %d, %lf", bbox.width, bbox.height, level, zoom);
+
+  graph = gegl_node_new ();
+  buffer_source = gegl_node_new_child (graph, "operation", "gegl:buffer-source", "buffer", buffer, NULL);
+  crop = gegl_node_new_child (graph,
+                              "operation", "gegl:crop",
+                              "height", (gdouble) min_dimension,
+                              "width", (gdouble) min_dimension,
+                              "x", x,
+                              "y", y,
+                              NULL);
+  operation_node = gegl_node_new_child (graph, "operation", operation, NULL);
+
+  va_start (ap, first_property_name);
+  gegl_node_set_valist (operation_node, first_property_name, ap);
+  va_end (ap);
+
+  gegl_node_link_many (buffer_source, crop, operation_node, NULL);
+
+  processor = gegl_node_new_processor (operation_node, NULL);
+  gegl_processor_set_level (processor, level);
+
+  start = g_get_monotonic_time ();
+
+  while (gegl_processor_work (processor, NULL));
+
+  end = g_get_monotonic_time ();
+  photos_debug (PHOTOS_DEBUG_GEGL, "Create Preview: Process: %" G_GINT64_FORMAT, end - start);
+
+  bbox = gegl_node_get_bounding_box (operation_node);
+  g_message ("%d, %d, %lf", bbox.width, bbox.height, zoom);
+
+  roi.height = size_scaled;
+  roi.width = size_scaled;
+  roi.x = (gint) (x * zoom + 0.5);
+  roi.y = (gint) (y * zoom + 0.5);
+
+  stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, roi.width);
+  buf = g_malloc0 (stride * roi.height);
+
+  format = babl_format ("cairo-ARGB32");
+  gegl_node_blit (operation_node, zoom, &roi, format, buf, GEGL_AUTO_ROWSTRIDE, GEGL_BLIT_CACHE);
+
+  surface = cairo_image_surface_create_for_data (buf, CAIRO_FORMAT_ARGB32, roi.width, roi.height, stride);
+  cairo_surface_set_device_scale (surface, (gdouble) scale, (gdouble) scale);
+
+  g_object_unref (buffer);
+  g_object_unref (graph);
+  g_object_unref (processor);
+
+  return surface;
+}
+
+
 void
 photos_base_item_destroy (PhotosBaseItem *self)
 {
diff --git a/src/photos-base-item.h b/src/photos-base-item.h
index 884e925..7cf2ba8 100644
--- a/src/photos-base-item.h
+++ b/src/photos-base-item.h
@@ -91,6 +91,13 @@ GType               photos_base_item_get_type                (void) G_GNUC_CONST
 
 gboolean            photos_base_item_can_trash               (PhotosBaseItem *self);
 
+cairo_surface_t    *photos_base_item_create_preview          (PhotosBaseItem *self,
+                                                              gint size,
+                                                              gint scale,
+                                                              const gchar *operation,
+                                                              const gchar *first_property_name,
+                                                              ...) G_GNUC_NULL_TERMINATED 
G_GNUC_WARN_UNUSED_RESULT;
+
 void                photos_base_item_destroy                 (PhotosBaseItem *self);
 
 gchar              *photos_base_item_download                (PhotosBaseItem *self,


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