[gegl] distance-transform: Handle image edges a little more correctly (Issue #213)
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] distance-transform: Handle image edges a little more correctly (Issue #213)
- Date: Mon, 18 Nov 2019 19:39:06 +0000 (UTC)
commit c8409355870435b5e238905c4516110845ba237a
Author: woob <thetoastcaper gmail com>
Date: Mon Nov 4 14:45:13 2019 -0500
distance-transform: Handle image edges a little more correctly (Issue #213)
In binary_dt_2nd_pass(), abyss is now handled by computing the second
pass using a copy of the current destination row, widened to have an
abyss value of zero at either side of the destination row's values.
Fixes issues caused by previous behavior of maxing the left and right
values of the dest row to 1, producing incorrect results when these
values are still being used to represent a vertical distance.
operations/common-cxx/distance-transform.cc | 33 +++++++++++++++--------------
1 file changed, 17 insertions(+), 16 deletions(-)
---
diff --git a/operations/common-cxx/distance-transform.cc b/operations/common-cxx/distance-transform.cc
index 9d7d2c304..3da93a7bb 100644
--- a/operations/common-cxx/distance-transform.cc
+++ b/operations/common-cxx/distance-transform.cc
@@ -189,27 +189,30 @@ binary_dt_2nd_pass (GeglOperation *operation,
height, gegl_operation_get_pixels_per_thread (operation) / width,
[&] (gint y0, gint size)
{
- gfloat *g, *row_copy;
+ gfloat *g, *dest_row;
gint q, w, *t, *s;
gint u, y;
/* sorry for the variable naming, they are taken from the paper */
- s = (gint *) gegl_calloc (sizeof (gint), width);
- t = (gint *) gegl_calloc (sizeof (gint), width);
- row_copy = (gfloat *) gegl_calloc (sizeof (gfloat), width);
+ s = (gint *) gegl_calloc (sizeof (gint), width + 1);
+ t = (gint *) gegl_calloc (sizeof (gint), width + 1);
+ g = (gfloat *) gegl_calloc (sizeof (gfloat), width + 2);
for (y = y0; y < y0 + size; y++)
{
+ dest_row = &dest[0 + y * width];
+
+ /* Use a copy of the dest row, lined with a zero on either side.
+ Mind the offset and difference in width when working between g
+ and the dest row. */
+ memcpy (&g[1], dest_row, width * sizeof (gfloat));
+
q = 0;
s[0] = 0;
t[0] = 0;
- g = dest + y * width;
- dest[0 + y * width] = MIN (dest[0 + y * width], 1.0);
- dest[width - 1 + y * width] = MIN (dest[width - 1 + y * width], 1.0);
-
- for (u = 1; u < width; u++)
+ for (u = 1; u < width + 2; u++)
{
while (q >= 0 &&
dt_f (t[q], s[q], g[s[q]]) >= dt_f (t[q], u, g[u]) + EPSILON)
@@ -228,7 +231,7 @@ binary_dt_2nd_pass (GeglOperation *operation,
w = dt_sep (s[q], u, g[s[q]], g[u]);
w += 1;
- if (w < width)
+ if (w < width + 1)
{
q ++;
s[q] = u;
@@ -237,14 +240,12 @@ binary_dt_2nd_pass (GeglOperation *operation,
}
}
- memcpy (row_copy, g, width * sizeof (gfloat));
-
- for (u = width - 1; u >= 0; u--)
+ for (u = width; u >= 1; u--)
{
if (u == s[q])
- g[u] = row_copy[u];
+ dest_row[u - 1] = g[u];
else
- g[u] = dt_f (u, s[q], row_copy[s[q]]);
+ dest_row[u - 1] = dt_f (u, s[q], g[s[q]]);
if (q > 0 && u == t[q])
{
@@ -255,7 +256,7 @@ binary_dt_2nd_pass (GeglOperation *operation,
gegl_free (t);
gegl_free (s);
- gegl_free (row_copy);
+ gegl_free (g);
});
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]