[gegl] c2g,stress: avoid infinite loop on fully transparent buffers



commit d17b50f2a43b54da73233efa826a3f9d8fd7dc16
Author: Øyvind Kolås <pippin gimp org>
Date:   Mon Jul 17 17:09:52 2017 +0200

    c2g,stress: avoid infinite loop on fully transparent buffers
    
    bug #784768
    
    Only permit goto retry a limited amount of times, equal to number of samples
    seems to work well slowing the degenerate case down a little - but not getting
    stuck in an infinite loop.

 gcut/gcut-ui.c                |   56 +++++++++++++++++++++++++++++++++++++++-
 operations/common/envelopes.h |   10 ++++++-
 2 files changed, 62 insertions(+), 4 deletions(-)
---
diff --git a/gcut/gcut-ui.c b/gcut/gcut-ui.c
index 1e13a45..2ca46e4 100644
--- a/gcut/gcut-ui.c
+++ b/gcut/gcut-ui.c
@@ -1480,6 +1480,7 @@ static void toggle_bool (MrgEvent *e, void *data1, void *data2)
 
 GeglNode *snode = NULL;
 const char *sprop = NULL;
+char *tmpstr = NULL;
 
 static void edit_string (MrgEvent *e, void *data1, void *data2)
 {
@@ -1494,6 +1495,29 @@ static void edit_string (MrgEvent *e, void *data1, void *data2)
   tweaked_state (e->mrg);
 }
 
+static void edit_int_string (MrgEvent *e, void *data1, void *data2)
+{
+  GeglNode *node = data1;
+  const char *prop = data2;
+  if (tmpstr)
+    g_warning ("tmp str set\n");
+  if (!tmpstr)
+    tmpstr = g_malloc0 (20);
+
+  snode = node;
+  sprop = prop;
+  {
+    int val;
+    g_object_get (node, prop, &val, NULL);
+    sprintf (tmpstr, "%d", val);
+  }
+  changed++;
+  mrg_event_stop_propagate (e);
+  mrg_set_cursor_pos (e->mrg, 0); // XXX: could fech strlen and use that
+  mrg_queue_draw (e->mrg, NULL);
+  tweaked_state (e->mrg);
+}
+
 static void jump_to_pos (MrgEvent *e, void *data1, void *data2)
 {
   GeglEDL *edl = data1;
@@ -1509,6 +1533,11 @@ static void end_edit (MrgEvent *e, void *data1, void *data2)
 {
   snode = NULL;
   sprop = NULL;
+  if (tmpstr)
+  {
+    g_free (tmpstr);
+    tmpstr = NULL;
+  }
   mrg_event_stop_propagate (e);
   mrg_set_cursor_pos (e->mrg, 0); // XXX: could fech strlen and use that
   mrg_queue_draw (e->mrg, NULL);
@@ -1652,6 +1681,14 @@ static void drag_int_slider (MrgEvent *e, void *data1, void *data2)
   tweaked_state (e->mrg);
 }
 
+static void update_int_string (const char *new_string, void *user_data)
+{
+  int val = atoi (new_string);
+  if (snode && sprop)
+    gegl_node_set (snode, sprop, val, NULL);
+  ui_tweaks++;
+}
+
 static void update_string (const char *new_string, void *user_data)
 {
   if (snode && sprop)
@@ -1769,8 +1806,23 @@ static float print_props (Mrg *mrg, GeglEDL *edl, GeglNode *node, float x, float
 
       cairo_restore (mrg_cr (mrg));
 
-      str = g_strdup_printf ("%s:%d", props[i]->name, val);
-      mrg_printf (mrg, "%s", str);
+      mrg_printf (mrg, "%s: ", props[i]->name);
+      str = g_strdup_printf ("%d", val);
+
+      if (snode && !strcmp (props[i]->name, sprop))
+      {
+        mrg_edit_start (mrg, update_int_string, edl);
+      }
+      else
+        mrg_text_listen (mrg, MRG_CLICK, edit_int_string, node, (void*)g_intern_string(props[i]->name));
+      
+      mrg_printf (mrg, "%s", tmpstr);
+
+      if (snode && !strcmp (props[i]->name, sprop))
+        mrg_edit_end (mrg);
+      else
+        mrg_text_listen_done (mrg);
+      str = g_strdup ("");
     }
     else if (g_type_is_a (type, G_TYPE_BOOLEAN))
     {
diff --git a/operations/common/envelopes.h b/operations/common/envelopes.h
index 2180de8..1cf22e9 100644
--- a/operations/common/envelopes.h
+++ b/operations/common/envelopes.h
@@ -81,10 +81,12 @@ sample_min_max (GeglBuffer  *buffer,
       gint u, v;
       gint angle;
       gfloat rmag;
+      gint max_retries = samples;
+
 retry:                      /* if we've sampled outside the valid image
                                area, we grab another sample instead, this
                                should potentially work better than mirroring
-                               or extending the image
+                               or extending with an abyss policy
                              */
       angle = angle_no++;
       rmag = radiuses[radius_no++] * radius;
@@ -101,7 +103,9 @@ retry:                      /* if we've sampled outside the valid image
           u<0 ||
           v>=height ||
           v<0)
+      {
         goto retry;
+      }
 
       {
         gfloat pixel[4];
@@ -120,7 +124,9 @@ retry:                      /* if we've sampled outside the valid image
           }
         else
           {
-            goto retry;
+            max_retries--;
+            if (max_retries>0)
+              goto retry;
           }
       }
     }


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