[gnome-photos/wip/rishi/edit-preview: 4/6] base-item: Add photos_base_item_create_preview
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-photos/wip/rishi/edit-preview: 4/6] base-item: Add photos_base_item_create_preview
- Date: Tue, 24 Nov 2015 02:19:16 +0000 (UTC)
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]