[gegl/soc-2011-seamless-clone: 15/49] Make the two-step seamless clone realtime!



commit 81afcdd4bef118b68a48fdd058578558ce302d86
Author: Barak Itkin <lightningismyname gmail com>
Date:   Fri Aug 19 22:03:43 2011 +0300

    Make the two-step seamless clone realtime!

 .../seamless-clone/poly2tri-c/render/mesh-render.c |   13 +++++++++++-
 .../seamless-clone/poly2tri-c/render/mesh-render.h |    8 +++++++
 .../common/seamless-clone/seamless-clone-prepare.c |   21 ++++++++++++++++++++
 .../common/seamless-clone/seamless-clone-render.c  |   16 +++++++++-----
 operations/common/seamless-clone/seamless-clone.h  |    4 +++
 5 files changed, 55 insertions(+), 7 deletions(-)
---
diff --git a/operations/common/seamless-clone/poly2tri-c/render/mesh-render.c b/operations/common/seamless-clone/poly2tri-c/render/mesh-render.c
index 656c9ec..6d8e3ca 100755
--- a/operations/common/seamless-clone/poly2tri-c/render/mesh-render.c
+++ b/operations/common/seamless-clone/poly2tri-c/render/mesh-render.c
@@ -200,7 +200,16 @@ p2tr_mesh_render_cache_uvt (P2tRTriangulation    *T,
                             P2tRuvt              *dest,
                             P2tRImageConfig      *config)
 {
-  gint x, y;
+  p2tr_mesh_render_cache_uvt_exact (T, dest, config->x_samples * config->y_samples, config);
+}
+
+void
+p2tr_mesh_render_cache_uvt_exact (P2tRTriangulation    *T,
+                                  P2tRuvt              *dest,
+                                  gint                  dest_len,
+                                  P2tRImageConfig      *config)
+{
+  gint x, y, n = dest_len;
   P2tRuvt *uvt = dest;
   P2tRTriangle *tr_prev = NULL;
 
@@ -210,6 +219,7 @@ p2tr_mesh_render_cache_uvt (P2tRTriangulation    *T,
   for (y = 0; y < config->y_samples; y++)
     for (x = 0; x < config->x_samples; x++)
     {
+      if (n-- == 0) return;
       gdouble Px = config->min_x + x * config->step_x;
       gdouble Py = config->min_y + y * config->step_y;
       uvt3_t(uvt) = p2tr_triangulation_locate_point2 (T, Px, Py, tr_prev, &uvt3_u(uvt), &uvt3_v(uvt));
@@ -218,6 +228,7 @@ p2tr_mesh_render_cache_uvt (P2tRTriangulation    *T,
     }
 }
 
+
 void
 p2tr_mesh_render_scanline (P2tRTriangulation    *T,
                            gfloat               *dest,
diff --git a/operations/common/seamless-clone/poly2tri-c/render/mesh-render.h b/operations/common/seamless-clone/poly2tri-c/render/mesh-render.h
index 3f99828..907d41f 100755
--- a/operations/common/seamless-clone/poly2tri-c/render/mesh-render.h
+++ b/operations/common/seamless-clone/poly2tri-c/render/mesh-render.h
@@ -40,6 +40,14 @@ p2tr_mesh_render_cache_uvt (P2tRTriangulation    *T,
                             P2tRuvt              *dest,
                             P2tRImageConfig      *config);
 
+/* Like the regular version, but cache only the specified amount of
+ * pixels */
+void
+p2tr_mesh_render_cache_uvt_exact (P2tRTriangulation    *T,
+                                  P2tRuvt              *dest,
+                                  gint                  dest_len,
+                                  P2tRImageConfig      *config);
+
 void
 p2tr_mesh_render_scanline (P2tRTriangulation    *T,
                            gfloat               *dest,
diff --git a/operations/common/seamless-clone/seamless-clone-prepare.c b/operations/common/seamless-clone/seamless-clone-prepare.c
index fb63654..a30783c 100644
--- a/operations/common/seamless-clone/seamless-clone-prepare.c
+++ b/operations/common/seamless-clone/seamless-clone-prepare.c
@@ -65,6 +65,10 @@ process (GeglOperation       *operation,
   ScPreprocessResult *result = sc_preprocess_new ();
   gpointer           *dest = GEGL_CHANT_PROPERTIES (operation) -> result;
 
+  GeglBuffer         *uvt;
+  GeglBufferIterator *iter;
+  P2tRImageConfig     config;
+
   if (dest == NULL)
     {
       return FALSE;
@@ -82,6 +86,22 @@ process (GeglOperation       *operation,
   /* If caching of UV is desired, it shold be done here, and possibly
    * by using a regular operation rather than a sink one, so that we can
    * output UV coords */
+  result->uvt = gegl_buffer_new (roi, babl_uvt_format);
+
+  iter = gegl_buffer_iterator_new (result->uvt, roi, NULL, GEGL_BUFFER_WRITE);
+
+  config.step_x = config.step_y = 1;
+  config.cpp = 4; /* Not that it will be used, but it won't harm */
+
+  while (gegl_buffer_iterator_next (iter))
+    {
+      config.min_x = iter->roi[0].x;
+      config.min_y = iter->roi[0].y;
+      config.x_samples = iter->roi[0].width;
+      config.y_samples = iter->roi[0].height;
+      p2tr_mesh_render_cache_uvt_exact (result->mesh, (P2tRuvt*) iter->data[0], iter->length, &config);
+    }
+  /* No need to free the iterator */
 
   *dest = result;
 
@@ -89,6 +109,7 @@ process (GeglOperation       *operation,
   sc_mesh_sampling_free (mesh_sampling);
   p2tr_triangulation_free (mesh);
   sc_outline_free (outline);
+  gegl_buffer_destroy (uvt);
   */
   
   return  TRUE;
diff --git a/operations/common/seamless-clone/seamless-clone-render.c b/operations/common/seamless-clone/seamless-clone-render.c
index b403fb9..6c8ab9c 100644
--- a/operations/common/seamless-clone/seamless-clone-render.c
+++ b/operations/common/seamless-clone/seamless-clone-render.c
@@ -147,10 +147,11 @@ process (GeglOperation       *operation,
   ScPreprocessResult *spr = o->prepare;
   
   gfloat    *out_raw, *pixel;
+  P2tRuvt *uvt_raw;
   gdouble    x, y;
 
   GeglRectangle aux_rect = *gegl_operation_source_get_bounding_box (operation, "aux");
-  GeglRectangle to_render;
+  GeglRectangle to_render, mesh_rect;
 
   ScColorComputeInfo  cci;
   P2tRImageConfig     imcfg;
@@ -173,6 +174,7 @@ process (GeglOperation       *operation,
 
   /* Alocate the output buffer */
   out_raw = g_new (gfloat, 4 * to_render.width * to_render.height);
+  uvt_raw = g_new (P2tRuvt, 3 * to_render.width * to_render.height);
 
   /* Render the mesh into it */
   cci.aux_buf = aux;
@@ -186,14 +188,15 @@ process (GeglOperation       *operation,
   cci.y = o->y;
 
   /* Render as if there is no offset, since the mesh has no offset */
-  imcfg.min_x = to_render.x - o->x;
-  imcfg.min_y = to_render.y - o->y;
+  mesh_rect.x = imcfg.min_x = to_render.x - o->x;
+  mesh_rect.y = imcfg.min_y = to_render.y - o->y;
   imcfg.step_x = imcfg.step_y = 1;
-  imcfg.x_samples = to_render.width;
-  imcfg.y_samples = to_render.height;
+  mesh_rect.width = imcfg.x_samples = to_render.width;
+  mesh_rect.height = imcfg.y_samples = to_render.height;
   imcfg.cpp = 4;
 
-  p2tr_mesh_render_scanline (spr->mesh, out_raw, &imcfg, sc_point_to_color_func, &cci);
+  gegl_buffer_get (spr->uvt, 1.0, &mesh_rect, babl_uvt_format, uvt_raw, GEGL_AUTO_ROWSTRIDE);
+  p2tr_mesh_render_scanline2 (uvt_raw, out_raw, &imcfg, sc_point_to_color_func, &cci);
 
   pixel = out_raw;
 
@@ -217,6 +220,7 @@ process (GeglOperation       *operation,
   gegl_buffer_set (output, &to_render, babl_format("R'G'B'A float"), out_raw, GEGL_AUTO_ROWSTRIDE);
 
   g_free (out_raw);
+  g_free (uvt_raw);
   g_hash_table_destroy (cci.pt2col);
   
   return TRUE;
diff --git a/operations/common/seamless-clone/seamless-clone.h b/operations/common/seamless-clone/seamless-clone.h
index 96254a8..ddb1571 100644
--- a/operations/common/seamless-clone/seamless-clone.h
+++ b/operations/common/seamless-clone/seamless-clone.h
@@ -31,6 +31,7 @@ typedef struct {
   P2tRTriangulation *mesh;
   GeglRectangle      mesh_bounds;
   ScMeshSampling    *sampling;
+  GeglBuffer        *uvt;
 } ScPreprocessResult;
 
 #define sc_preprocess_new() (g_new0 (ScPreprocessResult, 1))
@@ -45,4 +46,7 @@ typedef struct {
 //  g_free (self);
 //}
 
+#define babl_uvt_type   (babl_type_new ("uvt", "bits", sizeof (P2tRuvt) * 8, NULL))
+#define babl_uvt_format (babl_format_n (babl_uvt_type, 3))
+
 #endif



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