[gimp] app: use char array for temporary data (rather than a GEGL buffer).
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: use char array for temporary data (rather than a GEGL buffer).
- Date: Wed, 14 Nov 2018 12:41:58 +0000 (UTC)
commit 0c80f8a7182a646f7c1d7eb869f2b7f940ce2b20
Author: Jehan <jehan girinstud io>
Date: Wed Oct 17 17:21:26 2018 +0200
app: use char array for temporary data (rather than a GEGL buffer).
Also use more GeglBufferIterator on input GEGL buffer.
Using a char array is much less expensive and accelerated the line
erosion a lot!
Moving to GeglBufferIterator is not finished, but I do in steps.
app/core/gimplineart.c | 158 ++++++++++++++++++++++++++-----------------------
1 file changed, 84 insertions(+), 74 deletions(-)
---
diff --git a/app/core/gimplineart.c b/app/core/gimplineart.c
index f384bf2455..181c1a56d4 100644
--- a/app/core/gimplineart.c
+++ b/app/core/gimplineart.c
@@ -304,7 +304,6 @@ gimp_lineart_close (GeglBuffer *line_art,
if (erode_size)
gimp_lineart_erode (strokes, 2 * erode_size);
}
-
/* Denoise (remove small connected components) */
gimp_lineart_denoise (strokes, minimal_lineart_area);
@@ -591,9 +590,16 @@ static void
gimp_lineart_erode (GeglBuffer *buffer,
gint s)
{
- const Babl *format;
- gint width;
- gint height;
+ /* Erode image by a rectangular structuring element of specified
+ * size.
+ */
+ const Babl *format;
+ const gint _s2 = s / 2 + 1;
+ const gint _s1 = s - _s2;
+ GeglBufferIterator *gi;
+ guchar *buf;
+ gint width;
+ gint height;
if (s <= 1)
return;
@@ -605,39 +611,43 @@ gimp_lineart_erode (GeglBuffer *buffer,
if (width > 1)
{
/* Erosion along X-axis. */
- GeglBuffer *buf;
- const int _s2 = s / 2 + 1;
- const int _s1 = s - _s2;
- const int s1 = _s1 > width ? width : _s1;
- const int s2 = _s2 > width ? width : _s2;
+ const gint s1 = _s1 > width ? width : _s1;
+ const gint s2 = _s2 > width ? width : _s2;
+ gint y;
- buf = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, 1), format);
-
- for (int y = 0; y < height; ++y)
+ buf = g_new0 (guchar, width);
+ for (y = 0; y < height; ++y)
{
guchar cur;
- gint xs = 0;
+ gint xs = width;
gint xd = 0;
gboolean is_first = TRUE;
- gegl_buffer_sample (buffer, xs, y, NULL, &cur, NULL,
- GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- xs++;
- for (int p = s2 - 1; p > 0 && xs < width; --p)
+ gi = gegl_buffer_iterator_new (buffer, GEGL_RECTANGLE (0, y, MIN (s2, width), 1),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1);
+ while (gegl_buffer_iterator_next (gi))
{
- guchar val;
+ guint8 *val = (guint8*) gi->items[0].data;
+ gint k = 0;
- gegl_buffer_sample (buffer, xs, y, NULL, &val, NULL,
- GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- xs++;
- if (val <= cur)
+ if (gi->items[0].roi.x == 0)
{
- cur = val;
- is_first = FALSE;
+ cur = *val;
+ k = 1;
+ val++;
+ }
+ for (; k < gi->length; k++)
+ {
+ if (*val <= cur)
+ {
+ xs = gi->items[0].roi.x + k + 1;
+ cur = *val;
+ is_first = FALSE;
+ }
+ val++;
}
}
- gegl_buffer_set (buf, GEGL_RECTANGLE (xd, 0, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
+ buf[xd] = cur;
xd++;
if (xs >= width - 1)
@@ -647,30 +657,42 @@ gimp_lineart_erode (GeglBuffer *buffer,
gegl_buffer_sample (buffer, width - 1, y, NULL, &se, NULL,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
cur = MIN (cur, se);
- for (int x = 0; x < width; ++x)
- {
- gegl_buffer_set (buffer, GEGL_RECTANGLE (x, y, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
- }
+ gegl_buffer_set_color_from_pixel (buffer, GEGL_RECTANGLE (0, y, width, 1),
+ &cur, NULL);
}
else
{
- for (int p = s1; p > 0 && xd < width; --p)
+ gint _width = MIN (width - xs - 1, s1);
+ gint p = s1;
+
+ _width = MIN (_width, width - xd);
+ gi = gegl_buffer_iterator_new (buffer, GEGL_RECTANGLE (xs, y, _width, 1),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1);
+ while (gegl_buffer_iterator_next (gi))
{
- guchar val;
+ guint8 *val = (guint8*) gi->items[0].data;
+ gint k;
- gegl_buffer_sample (buffer, xs, y, NULL, &val, NULL,
- GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- if (xs < width - 1)
- xs++;
- if (val <= cur)
+ for (k = 0; k < gi->length; k++)
{
- cur = val;
- is_first = FALSE;
+ if (*val <= cur)
+ {
+ cur = *val;
+ is_first = FALSE;
+ }
+ buf[xd] = cur;
+ xd++;
+
+ xs++;
+ val++;
+ p--;
}
- gegl_buffer_set (buf, GEGL_RECTANGLE (xd, 0, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
+ }
+ while (p > 0)
+ {
+ buf[xd] = cur;
xd++;
+ --p;
}
for (int p = width - s - 1; p > 0; --p)
{
@@ -720,8 +742,7 @@ gimp_lineart_erode (GeglBuffer *buffer,
is_first = TRUE;
}
}
- gegl_buffer_set (buf, GEGL_RECTANGLE (xd, 0, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
+ buf[xd] = cur;
xd++;
}
xd = width - 1;
@@ -739,8 +760,7 @@ gimp_lineart_erode (GeglBuffer *buffer,
if (val < cur)
cur = val;
}
- gegl_buffer_set (buf, GEGL_RECTANGLE (xd, 0, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
+ buf[xd] = cur;
xd--;
for (int p = s2 - 1; p > 0 && xd >= 0; --p)
{
@@ -752,29 +772,25 @@ gimp_lineart_erode (GeglBuffer *buffer,
xs--;
if (val < cur)
cur = val;
- gegl_buffer_set (buf, GEGL_RECTANGLE (xd, 0, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
+ buf[xd] = cur;
xd--;
}
- gegl_buffer_copy (buf, GEGL_RECTANGLE (0, 0, width, 1),
- GEGL_ABYSS_NONE,
- buffer, GEGL_RECTANGLE (0, y, width, 1));
+ gegl_buffer_set (buffer, GEGL_RECTANGLE (0, y, width, 1), 0,
+ format, buf, GEGL_AUTO_ROWSTRIDE);
}
}
- g_object_unref (buf);
+ g_free (buf);
}
if (height > 1)
{
- GeglBuffer *buf;
- const int _s2 = s / 2 + 1;
- const int _s1 = s - _s2;
- const int s1 = _s1 > height ? height : _s1;
- const int s2 = _s2 > height ? height : _s2;
+ /* Erosion along Y-axis. */
+ const gint s1 = _s1 > height ? height : _s1;
+ const gint s2 = _s2 > height ? height : _s2;
+ gint x;
- buf = gegl_buffer_new (GEGL_RECTANGLE (0, 0, 1, height), format);
-
- for (int x = 0; x < width; ++x)
+ buf = g_new0 (guchar, height);
+ for (x = 0; x < width; ++x)
{
guchar cur;
gint ys = 0;
@@ -797,8 +813,7 @@ gimp_lineart_erode (GeglBuffer *buffer,
is_first = FALSE;
}
}
- gegl_buffer_set (buf, GEGL_RECTANGLE (0, ys, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
+ buf[yd] = cur;
yd++;
if (ys >= height - 1)
@@ -829,8 +844,7 @@ gimp_lineart_erode (GeglBuffer *buffer,
cur = val;
is_first = FALSE;
}
- gegl_buffer_set (buf, GEGL_RECTANGLE (0, yd, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
+ buf[yd] = cur;
yd++;
}
for (int p = height - s - 1; p > 0; --p)
@@ -881,8 +895,7 @@ gimp_lineart_erode (GeglBuffer *buffer,
is_first = TRUE;
}
}
- gegl_buffer_set (buf, GEGL_RECTANGLE (0, yd, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
+ buf[yd] = cur;
yd++;
}
yd = height - 1;
@@ -900,8 +913,7 @@ gimp_lineart_erode (GeglBuffer *buffer,
if (val < cur)
cur = val;
}
- gegl_buffer_set (buf, GEGL_RECTANGLE (0, yd, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
+ buf[yd] = cur;
yd--;
for (int p = s2 - 1; p > 0 && yd >= 0; --p)
{
@@ -913,16 +925,14 @@ gimp_lineart_erode (GeglBuffer *buffer,
ys--;
if (val < cur)
cur = val;
- gegl_buffer_set (buf, GEGL_RECTANGLE (0, yd, 1, 1), 0,
- format, &cur, GEGL_AUTO_ROWSTRIDE);
+ buf[yd] = cur;
yd--;
}
- gegl_buffer_copy (buf, GEGL_RECTANGLE (0, 0, 1, height),
- GEGL_ABYSS_NONE,
- buffer, GEGL_RECTANGLE (x, 0, 1, height));
+ gegl_buffer_set (buffer, GEGL_RECTANGLE (x, 0, 1, height), 0,
+ format, buf, GEGL_AUTO_ROWSTRIDE);
}
}
- g_object_unref (buf);
+ g_free (buf);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]