[gimp] app: use more GeglBufferIterator.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: use more GeglBufferIterator.
- Date: Wed, 14 Nov 2018 12:41:38 +0000 (UTC)
commit 1822ea399a3c03db043aea87937e5545ffcd43a9
Author: Jehan <jehan girinstud io>
Date: Sun Oct 14 15:30:38 2018 +0200
app: use more GeglBufferIterator.
In this case, it makes the code a bit more messy, but hopefully more
efficient.
app/core/gimplineart.c | 260 +++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 228 insertions(+), 32 deletions(-)
---
diff --git a/app/core/gimplineart.c b/app/core/gimplineart.c
index 18a711c804..af44d2ac79 100644
--- a/app/core/gimplineart.c
+++ b/app/core/gimplineart.c
@@ -1993,47 +1993,243 @@ gimp_edgel_region_area (const GeglBuffer *mask,
static GArray *
gimp_edgelset_new (GeglBuffer *buffer)
{
- GArray *set;
- GHashTable *edgel2index;
- int lx = gegl_buffer_get_width (buffer) - 1;
- int ly = gegl_buffer_get_height (buffer) - 1;
+ GeglBufferIterator *gi;
+ GArray *set;
+ GHashTable *edgel2index;
+ gint width = gegl_buffer_get_width (buffer);
+ gint height = gegl_buffer_get_height (buffer);
set = g_array_new (TRUE, TRUE, sizeof (Edgel *));
g_array_set_clear_func (set, (GDestroyNotify) gimp_edgel_clear);
+ if (width <= 1 || height <= 1)
+ return set;
+
edgel2index = g_hash_table_new ((GHashFunc) edgel2index_hash_fun,
(GEqualFunc) edgel2index_equal_fun);
- for (int y = 0; y < (int) gegl_buffer_get_height (buffer); ++y)
- for (int x = 0; x < (int) gegl_buffer_get_width (buffer); ++x)
- {
- guchar has_stroke;
-
- gegl_buffer_sample (buffer, x, y, NULL, &has_stroke, NULL,
- GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- if (has_stroke)
+ /* Top border */
+ gi = gegl_buffer_iterator_new (buffer, GEGL_RECTANGLE (1, 0, width - 2, 1),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 4);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (0, 0, width - 2, 1),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (2, 0, width - 2, 1),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (1, 1, width - 2, 1),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ while (gegl_buffer_iterator_next (gi))
+ {
+ guint8 *p = (guint8*) gi->items[0].data;
+ guint8 *prevx = (guint8*) gi->items[1].data;
+ guint8 *nextx = (guint8*) gi->items[2].data;
+ guint8 *nexty = (guint8*) gi->items[3].data;
+ gint pwidth = gi->items[0].roi.width;
+ gint x = gi->items[0].roi.x;
+ gint endx = x + pwidth;
+
+ if (x == 1 && *(prevx))
+ gimp_edgelset_add (set, 0, 0, XMinusDirection, edgel2index);
+ else if (endx == width - 1 && nextx[pwidth - 1])
+ gimp_edgelset_add (set, width - 1, 0, XPlusDirection, edgel2index);
+
+ for (; x < endx; x++)
+ {
+ if (*(p++))
+ {
+ gimp_edgelset_add (set, x, 0, YMinusDirection, edgel2index);
+ if (! *prevx)
+ gimp_edgelset_add (set, x, 0, XMinusDirection, edgel2index);
+ if (! *nextx)
+ gimp_edgelset_add (set, x, 0, XPlusDirection, edgel2index);
+ if (! *nexty)
+ gimp_edgelset_add (set, x, 0, YPlusDirection, edgel2index);
+ }
+ prevx++;
+ nextx++;
+ nexty++;
+ }
+ }
+ /* Left border */
+ gi = gegl_buffer_iterator_new (buffer, GEGL_RECTANGLE (0, 1, 1, height - 2),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 4);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (0, 0, 1, height - 2),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (0, 2, 1, height - 2),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (1, 1, 1, height - 2),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ while (gegl_buffer_iterator_next (gi))
+ {
+ guint8 *p = (guint8*) gi->items[0].data;
+ guint8 *prevy = (guint8*) gi->items[1].data;
+ guint8 *nexty = (guint8*) gi->items[2].data;
+ guint8 *nextx = (guint8*) gi->items[3].data;
+ gint pheight = gi->items[0].roi.height;
+ gint y = gi->items[0].roi.y;
+ gint endy = y + pheight;
+
+ if (y == 1 && *(prevy))
+ gimp_edgelset_add (set, 0, 0, YMinusDirection, edgel2index);
+ else if (endy == height - 1 && nexty[pheight - 1])
+ gimp_edgelset_add (set, 0, height - 1, YPlusDirection, edgel2index);
+
+ for (; y < endy; y++)
+ {
+ if (*(p++))
+ {
+ gimp_edgelset_add (set, 0, y, XMinusDirection, edgel2index);
+ if (! *prevy)
+ gimp_edgelset_add (set, 0, y, YMinusDirection, edgel2index);
+ if (! *nexty)
+ gimp_edgelset_add (set, 0, y, YPlusDirection, edgel2index);
+ if (! *nextx)
+ gimp_edgelset_add (set, 0, y, XPlusDirection, edgel2index);
+ }
+ prevy++;
+ nexty++;
+ nextx++;
+ }
+ }
+ /* Bottom border */
+ gi = gegl_buffer_iterator_new (buffer, GEGL_RECTANGLE (1, height - 1, width - 2, 1),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 4);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (0, height - 1, width - 2, 1),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (2, height - 1, width - 2, 1),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (1, height - 2, width - 2, 1),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ while (gegl_buffer_iterator_next (gi))
+ {
+ guint8 *p = (guint8*) gi->items[0].data;
+ guint8 *prevx = (guint8*) gi->items[1].data;
+ guint8 *nextx = (guint8*) gi->items[2].data;
+ guint8 *prevy = (guint8*) gi->items[3].data;
+ gint pwidth = gi->items[0].roi.width;
+ gint x = gi->items[0].roi.x;
+ gint endx = x + pwidth;
+
+ if (x == 1 && *(prevx))
+ gimp_edgelset_add (set, 0, height - 1, XMinusDirection, edgel2index);
+ else if (endx == width - 1 && nextx[pwidth - 1])
+ gimp_edgelset_add (set, width - 1, height - 1, XPlusDirection, edgel2index);
+
+ for (; x < endx; x++)
+ {
+ if (*(p++))
+ {
+ gimp_edgelset_add (set, x, height - 1, YPlusDirection, edgel2index);
+ if (! *prevx)
+ gimp_edgelset_add (set, x, height - 1, XMinusDirection, edgel2index);
+ if (! *nextx)
+ gimp_edgelset_add (set, x, height - 1, XPlusDirection, edgel2index);
+ if (! *prevy)
+ gimp_edgelset_add (set, x, height - 1, YMinusDirection, edgel2index);
+ }
+ prevx++;
+ nextx++;
+ prevy++;
+ }
+ }
+ /* Right border */
+ gi = gegl_buffer_iterator_new (buffer, GEGL_RECTANGLE (width - 1, 1, 1, height - 2),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 4);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (width - 1, 0, 1, height - 2),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (width - 1, 2, 1, height - 2),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (width - 2, 1, 1, height - 2),
+ 0, NULL,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ while (gegl_buffer_iterator_next (gi))
+ {
+ guint8 *p = (guint8*) gi->items[0].data;
+ guint8 *prevy = (guint8*) gi->items[1].data;
+ guint8 *nexty = (guint8*) gi->items[2].data;
+ guint8 *prevx = (guint8*) gi->items[3].data;
+ gint pheight = gi->items[0].roi.height;
+ gint y = gi->items[0].roi.y;
+ gint endy = y + pheight;
+
+ if (y == 1 && *(prevy))
+ gimp_edgelset_add (set, width - 1, 0, YMinusDirection, edgel2index);
+ else if (endy == height - 1 && nexty[pheight - 1])
+ gimp_edgelset_add (set, width - 1, height - 1, YPlusDirection, edgel2index);
+
+ for (; y < endy; y++)
+ {
+ if (*(p++))
+ {
+ gimp_edgelset_add (set, width - 1, y, XPlusDirection, edgel2index);
+ if (! *prevy)
+ gimp_edgelset_add (set, width - 1, y, YMinusDirection, edgel2index);
+ if (! *nexty)
+ gimp_edgelset_add (set, width - 1, y, YPlusDirection, edgel2index);
+ if (! *prevx)
+ gimp_edgelset_add (set, width - 1, y, XMinusDirection, edgel2index);
+ }
+ prevy++;
+ nexty++;
+ prevx++;
+ }
+ }
+ /* The rest */
+ gi = gegl_buffer_iterator_new (buffer, GEGL_RECTANGLE (1, 1, width - 2, height - 2),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 5);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (1, 0, width - 2, height - 2),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (1, 2, width - 2, height - 2),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (0, 1, width - 2, height - 2),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (2, 1, width - 2, height - 2),
+ 0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ while (gegl_buffer_iterator_next (gi))
+ {
+ guint8 *p = (guint8*) gi->items[0].data;
+ guint8 *prevy = (guint8*) gi->items[1].data;
+ guint8 *nexty = (guint8*) gi->items[2].data;
+ guint8 *prevx = (guint8*) gi->items[3].data;
+ guint8 *nextx = (guint8*) gi->items[4].data;
+ gint startx = gi->items[0].roi.x;
+ gint starty = gi->items[0].roi.y;
+ gint endy = starty + gi->items[0].roi.height;
+ gint endx = startx + gi->items[0].roi.width;
+ gint x;
+ gint y;
+
+ for (y = starty; y < endy; y++)
+ for (x = startx; x < endx; x++)
{
- gegl_buffer_sample (buffer, x, y - 1, NULL, &has_stroke, NULL,
- GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- if (! y || ! has_stroke)
- gimp_edgelset_add (set, x, y, YMinusDirection, edgel2index);
-
- gegl_buffer_sample (buffer, x, y + 1, NULL, &has_stroke, NULL,
- GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- if ((y == ly) || ! has_stroke)
- gimp_edgelset_add (set, x, y, YPlusDirection, edgel2index);
-
- gegl_buffer_sample (buffer, x - 1, y, NULL, &has_stroke, NULL,
- GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- if (!x || ! has_stroke)
- gimp_edgelset_add (set, x, y, XMinusDirection, edgel2index);
-
- gegl_buffer_sample (buffer, x + 1, y, NULL, &has_stroke, NULL,
- GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- if ((x == lx) || ! has_stroke)
- gimp_edgelset_add (set, x, y, XPlusDirection, edgel2index);
+ if (*(p++))
+ {
+ if (! *prevy)
+ gimp_edgelset_add (set, x, y, YMinusDirection, edgel2index);
+ if (! *nexty)
+ gimp_edgelset_add (set, x, y, YPlusDirection, edgel2index);
+ if (! *prevx)
+ gimp_edgelset_add (set, x, y, XMinusDirection, edgel2index);
+ if (! *nextx)
+ gimp_edgelset_add (set, x, y, XPlusDirection, edgel2index);
+ }
+ prevy++;
+ nexty++;
+ prevx++;
+ nextx++;
}
- }
+ }
+
gimp_edgelset_build_graph (set, buffer, edgel2index);
g_hash_table_destroy (edgel2index);
gimp_edgelset_init_normals (set);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]