[gimp/gimp-2-10] app: create a simple priority map for line art selection flooding.



commit 8dc6bcafa3e7cf76e4cdea8c44a3bb44960dc59f
Author: Jehan <jehan girinstud io>
Date:   Fri Oct 26 13:38:57 2018 +0200

    app: create a simple priority map for line art selection flooding.
    
    We actually don't need to compute distance map. I just make the simplest
    priority map, with 1 any line art pixel and 0 any other pixel (in mask
    or not), lowest priority being propagated first.
    And let the flooding begin!
    
    (cherry picked from commit 410c747509685a3359f8cc5468ce24e73ecab6eb)

 app/core/gimppickable-contiguous-region.c | 80 ++++++++++---------------------
 1 file changed, 24 insertions(+), 56 deletions(-)
---
diff --git a/app/core/gimppickable-contiguous-region.c b/app/core/gimppickable-contiguous-region.c
index 193b661b83..5effb026d6 100644
--- a/app/core/gimppickable-contiguous-region.c
+++ b/app/core/gimppickable-contiguous-region.c
@@ -226,7 +226,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable        *pickable,
        * unknown pixels be labelled by flooding through watershed.
        */
       GeglBufferIterator *gi;
-      GeglBuffer         *distmap;
+      GeglBuffer         *priomap;
       GeglBuffer         *tmp;
       GeglNode           *graph;
       GeglNode           *input;
@@ -236,73 +236,41 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable        *pickable,
 
       GIMP_TIMER_START();
 
-      /* Compute a distance map for the labels. */
-      graph = gegl_node_new ();
-      input = gegl_node_new_child (graph,
-                                   "operation", "gegl:buffer-source",
-                                   "buffer", mask_buffer,
-                                   NULL);
-      op  = gegl_node_new_child (graph,
-                                 "operation", "gegl:distance-transform",
-                                 "metric", GEGL_DISTANCE_METRIC_EUCLIDEAN,
-                                 "normalize", FALSE,
-                                 NULL);
-      sink  = gegl_node_new_child (graph,
-                                   "operation", "gegl:buffer-sink",
-                                   "buffer", &distmap,
-                                   NULL);
-      gegl_node_connect_to (input, "output",
-                            op, "input");
-      gegl_node_connect_to (op, "output",
-                            sink, "input");
-      gegl_node_process (sink);
-      g_object_unref (graph);
-
-      /* gegl:distance-transform returns distances as float. I want them as
-       * unsigned ints without converting (i.e. not assuming pixel values).
-       * Let's just loop through the map).
-       */
-      tmp = gegl_buffer_new (gegl_buffer_get_extent (distmap),
-                             babl_format ("Y u8"));
-      gi = gegl_buffer_iterator_new (distmap, NULL, 0, NULL,
-                                     GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
-      gegl_buffer_iterator_add (gi, tmp, NULL, 0, NULL,
-                                GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
-      while (gegl_buffer_iterator_next (gi))
-        {
-          float  *data = (float*) gi->items[0].data;
-          guint8 *out = (guint8*) gi->items[1].data;
-          gint    k;
+      /* Flag the mask on the line art and create a priority map. */
+      priomap = gegl_buffer_new (gegl_buffer_get_extent (mask_buffer),
+                                 babl_format ("Y u8"));
 
-          for (k = 0; k < gi->length; k++)
-            {
-              *out = (guint8) G_MAXUINT32 - MIN (round (*data), G_MAXUINT8);
-              data++;
-              out++;
-            }
-        }
-      g_object_unref (distmap);
-      distmap = tmp;
-
-      /* Flag the mask on the line art. */
       gi = gegl_buffer_iterator_new (src_buffer, NULL, 0, NULL,
-                                     GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
+                                     GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 3);
       gegl_buffer_iterator_add (gi, mask_buffer, NULL, 0,
                                 babl_format ("Y float"),
                                 GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE);
+      gegl_buffer_iterator_add (gi, priomap, NULL, 0,
+                                babl_format ("Y u8"),
+                                GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
 
       while (gegl_buffer_iterator_next (gi))
         {
-          guchar  *lineart = (guchar*) gi->items[0].data;
-          gfloat  *mask    = (gfloat*) gi->items[1].data;
+          guchar *lineart = (guchar*) gi->items[0].data;
+          gfloat *mask    = (gfloat*) gi->items[1].data;
+          guint8 *prio    = (guint8*) gi->items[2].data;
           gint    k;
 
           for (k = 0; k < gi->length; k++)
             {
-              if (*lineart && ! *mask)
-                *mask = flag;
+              if (*lineart)
+                {
+                  *prio = 1;
+                  if (! *mask)
+                    *mask = flag;
+                }
+              else
+                {
+                  *prio = 0;
+                }
               lineart++;
               mask++;
+              prio++;
             }
         }
       g_object_unref (src_buffer);
@@ -315,7 +283,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable        *pickable,
                                    NULL);
       aux = gegl_node_new_child (graph,
                                  "operation", "gegl:buffer-source",
-                                 "buffer", distmap,
+                                 "buffer", priomap,
                                  NULL);
       op  = gegl_node_new_child (graph,
                                  "operation", "gegl:watershed-transform",
@@ -334,7 +302,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable        *pickable,
                             sink, "input");
       gegl_node_process (sink);
       g_object_unref (graph);
-      g_object_unref (distmap);
+      g_object_unref (priomap);
 
       gegl_buffer_copy (tmp, NULL, GEGL_ABYSS_NONE, mask_buffer, NULL);
       g_object_unref (tmp);


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