[gimp] Bug 725556 - Feather selection extremely slow
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 725556 - Feather selection extremely slow
- Date: Tue, 4 Mar 2014 21:12:59 +0000 (UTC)
commit 30ae88ef073db163489de7cad07a07afe56ba692
Author: Michael Natterer <mitch gimp org>
Date: Tue Mar 4 22:09:11 2014 +0100
Bug 725556 - Feather selection extremely slow
gimp_gegl_apply_feather(): add a "dest_rect" parameter to restrict
the feather area. Pass the selection bounds plus the feather radius.
For consistency, newly add gimp_gegl_apply_border,grow,shrink() and use
them in gimpchannel.c
app/core/gimpchannel-select.c | 10 ++--
app/core/gimpchannel.c | 91 ++++++++++++---------------
app/gegl/gimp-gegl-apply-operation.c | 114 +++++++++++++++++++++++++++++----
app/gegl/gimp-gegl-apply-operation.h | 29 +++++++++
4 files changed, 173 insertions(+), 71 deletions(-)
---
diff --git a/app/core/gimpchannel-select.c b/app/core/gimpchannel-select.c
index 765aa52..b804bc1 100644
--- a/app/core/gimpchannel-select.c
+++ b/app/core/gimpchannel-select.c
@@ -83,7 +83,7 @@ gimp_channel_select_rectangle (GimpChannel *channel,
gimp_gegl_mask_combine_rect (add_on, GIMP_CHANNEL_OP_ADD, x, y, w, h);
if (feather)
- gimp_gegl_apply_feather (add_on, NULL, NULL, add_on,
+ gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL,
feather_radius_x,
feather_radius_y);
@@ -136,7 +136,7 @@ gimp_channel_select_ellipse (GimpChannel *channel,
x, y, w, h, antialias);
if (feather)
- gimp_gegl_apply_feather (add_on, NULL, NULL, add_on,
+ gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL,
feather_radius_x,
feather_radius_y);
@@ -193,7 +193,7 @@ gimp_channel_select_round_rect (GimpChannel *channel,
antialias);
if (feather)
- gimp_gegl_apply_feather (add_on, NULL, NULL, add_on,
+ gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL,
feather_radius_x,
feather_radius_y);
@@ -249,7 +249,7 @@ gimp_channel_select_scan_convert (GimpChannel *channel,
offset_x, offset_y, antialias);
if (feather)
- gimp_gegl_apply_feather (add_on, NULL, NULL, add_on,
+ gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL,
feather_radius_x,
feather_radius_y);
@@ -363,7 +363,7 @@ gimp_channel_select_buffer (GimpChannel *channel,
offset_x, offset_y);
if (feather)
- gimp_gegl_apply_feather (add_on2, NULL, NULL, add_on2,
+ gimp_gegl_apply_feather (add_on2, NULL, NULL, add_on2, NULL,
feather_radius_x,
feather_radius_y);
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index 6aeefd8..4f466e1 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -23,6 +23,7 @@
#include <gegl.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "libgimpmath/gimpmath.h"
#include "libgimpcolor/gimpcolor.h"
#include "core-types.h"
@@ -1181,17 +1182,33 @@ gimp_channel_real_feather (GimpChannel *channel,
gdouble radius_y,
gboolean push_undo)
{
- GimpDrawable *drawable = GIMP_DRAWABLE (channel);
+ gint x1, y1, x2, y2;
+
+ if (radius_x <= 0.0 && radius_y <= 0.0)
+ return;
+
+ if (! gimp_channel_bounds (channel, &x1, &y1, &x2, &y2))
+ return;
+
+ if (gimp_channel_is_empty (channel))
+ return;
+
+ x1 = MAX (0, x1 - ceil (radius_x));
+ y1 = MAX (0, y1 - ceil (radius_y));
+
+ x2 = MIN (gimp_item_get_width (GIMP_ITEM (channel)), x2 + ceil (radius_x));
+ y2 = MIN (gimp_item_get_height (GIMP_ITEM (channel)), y2 + ceil (radius_y));
if (push_undo)
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->feather_desc);
else
- gimp_drawable_invalidate_boundary (drawable);
+ gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
- gimp_gegl_apply_feather (gimp_drawable_get_buffer (drawable),
+ gimp_gegl_apply_feather (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
NULL, NULL,
- gimp_drawable_get_buffer (drawable),
+ gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+ GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
radius_x,
radius_y);
@@ -1338,8 +1355,7 @@ gimp_channel_real_border (GimpChannel *channel,
gboolean edge_lock,
gboolean push_undo)
{
- GeglNode *border;
- gint x1, y1, x2, y2;
+ gint x1, y1, x2, y2;
if (radius_x < 0 || radius_y < 0)
return;
@@ -1376,21 +1392,11 @@ gimp_channel_real_border (GimpChannel *channel,
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
- border = gegl_node_new_child (NULL,
- "operation", "gimp:border",
- "radius-x", radius_x,
- "radius-y", radius_y,
- "feather", feather,
- "edge-lock", edge_lock,
- NULL);
-
- gimp_gegl_apply_operation (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
- NULL, NULL,
- border,
- gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
- GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1));
-
- g_object_unref (border);
+ gimp_gegl_apply_border (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+ NULL, NULL,
+ gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+ GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
+ radius_x, radius_y, feather, edge_lock);
channel->bounds_known = FALSE;
@@ -1405,8 +1411,7 @@ gimp_channel_real_grow (GimpChannel *channel,
gint radius_y,
gboolean push_undo)
{
- GeglNode *grow;
- gint x1, y1, x2, y2;
+ gint x1, y1, x2, y2;
if (radius_x == 0 && radius_y == 0)
return;
@@ -1452,19 +1457,11 @@ gimp_channel_real_grow (GimpChannel *channel,
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
- grow = gegl_node_new_child (NULL,
- "operation", "gimp:grow",
- "radius-x", radius_x,
- "radius-y", radius_y,
- NULL);
-
- gimp_gegl_apply_operation (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
- NULL, NULL,
- grow,
- gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
- GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1));
-
- g_object_unref (grow);
+ gimp_gegl_apply_grow (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+ NULL, NULL,
+ gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+ GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
+ radius_x, radius_y);
channel->bounds_known = FALSE;
@@ -1480,8 +1477,7 @@ gimp_channel_real_shrink (GimpChannel *channel,
gboolean edge_lock,
gboolean push_undo)
{
- GeglNode *shrink;
- gint x1, y1, x2, y2;
+ gint x1, y1, x2, y2;
if (radius_x == 0 && radius_y == 0)
return;
@@ -1516,20 +1512,11 @@ gimp_channel_real_shrink (GimpChannel *channel,
else
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
- shrink = gegl_node_new_child (NULL,
- "operation", "gimp:shrink",
- "radius-x", radius_x,
- "radius-y", radius_y,
- "edge-lock", edge_lock,
- NULL);
-
- gimp_gegl_apply_operation (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
- NULL, NULL,
- shrink,
- gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
- GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1));
-
- g_object_unref (shrink);
+ gimp_gegl_apply_shrink (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+ NULL, NULL,
+ gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+ GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
+ radius_x, radius_y, edge_lock);
channel->bounds_known = FALSE;
diff --git a/app/gegl/gimp-gegl-apply-operation.c b/app/gegl/gimp-gegl-apply-operation.c
index 180007c..059150d 100644
--- a/app/gegl/gimp-gegl-apply-operation.c
+++ b/app/gegl/gimp-gegl-apply-operation.c
@@ -185,12 +185,13 @@ gimp_gegl_apply_flatten (GeglBuffer *src_buffer,
}
void
-gimp_gegl_apply_feather (GeglBuffer *src_buffer,
- GimpProgress *progress,
- const gchar *undo_desc,
- GeglBuffer *dest_buffer,
- gdouble radius_x,
- gdouble radius_y)
+gimp_gegl_apply_feather (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gdouble radius_x,
+ gdouble radius_y)
{
g_return_if_fail (GEGL_IS_BUFFER (src_buffer));
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
@@ -201,18 +202,103 @@ gimp_gegl_apply_feather (GeglBuffer *src_buffer,
*/
gimp_gegl_apply_gaussian_blur (src_buffer,
progress, undo_desc,
- dest_buffer,
+ dest_buffer, dest_rect,
radius_x / 3.5,
radius_y / 3.5);
}
void
-gimp_gegl_apply_gaussian_blur (GeglBuffer *src_buffer,
- GimpProgress *progress,
- const gchar *undo_desc,
- GeglBuffer *dest_buffer,
- gdouble std_dev_x,
- gdouble std_dev_y)
+gimp_gegl_apply_border (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gint radius_x,
+ gint radius_y,
+ gboolean feather,
+ gboolean edge_lock)
+{
+ GeglNode *node;
+
+ g_return_if_fail (GEGL_IS_BUFFER (src_buffer));
+ g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
+ g_return_if_fail (GEGL_IS_BUFFER (dest_buffer));
+
+ node = gegl_node_new_child (NULL,
+ "operation", "gimp:border",
+ "radius-x", radius_x,
+ "radius-y", radius_y,
+ "feather", feather,
+ "edge-lock", edge_lock,
+ NULL);
+
+ gimp_gegl_apply_operation (src_buffer, progress, undo_desc,
+ node, dest_buffer, dest_rect);
+ g_object_unref (node);
+}
+
+void
+gimp_gegl_apply_grow (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gint radius_x,
+ gint radius_y)
+{
+ GeglNode *node;
+
+ g_return_if_fail (GEGL_IS_BUFFER (src_buffer));
+ g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
+ g_return_if_fail (GEGL_IS_BUFFER (dest_buffer));
+
+ node = gegl_node_new_child (NULL,
+ "operation", "gimp:grow",
+ "radius-x", radius_x,
+ "radius-y", radius_y,
+ NULL);
+
+ gimp_gegl_apply_operation (src_buffer, progress, undo_desc,
+ node, dest_buffer, dest_rect);
+ g_object_unref (node);
+}
+
+void
+gimp_gegl_apply_shrink (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gint radius_x,
+ gint radius_y,
+ gboolean edge_lock)
+{
+ GeglNode *node;
+
+ g_return_if_fail (GEGL_IS_BUFFER (src_buffer));
+ g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
+ g_return_if_fail (GEGL_IS_BUFFER (dest_buffer));
+
+ node = gegl_node_new_child (NULL,
+ "operation", "gimp:shrink",
+ "radius-x", radius_x,
+ "radius-y", radius_y,
+ "edge-lock", edge_lock,
+ NULL);
+
+ gimp_gegl_apply_operation (src_buffer, progress, undo_desc,
+ node, dest_buffer, dest_rect);
+ g_object_unref (node);
+}
+
+void
+gimp_gegl_apply_gaussian_blur (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gdouble std_dev_x,
+ gdouble std_dev_y)
{
GeglNode *node;
@@ -227,7 +313,7 @@ gimp_gegl_apply_gaussian_blur (GeglBuffer *src_buffer,
NULL);
gimp_gegl_apply_operation (src_buffer, progress, undo_desc,
- node, dest_buffer, NULL);
+ node, dest_buffer, dest_rect);
g_object_unref (node);
}
diff --git a/app/gegl/gimp-gegl-apply-operation.h b/app/gegl/gimp-gegl-apply-operation.h
index 14e3822..06edaa5 100644
--- a/app/gegl/gimp-gegl-apply-operation.h
+++ b/app/gegl/gimp-gegl-apply-operation.h
@@ -53,13 +53,42 @@ void gimp_gegl_apply_feather (GeglBuffer *src_buffer,
GimpProgress *progress,
const gchar *undo_desc,
GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
gdouble radius_x,
gdouble radius_y);
+void gimp_gegl_apply_border (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gint radius_x,
+ gint radius_y,
+ gboolean feather,
+ gboolean edge_lock);
+
+void gimp_gegl_apply_grow (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gint radius_x,
+ gint radius_y);
+
+void gimp_gegl_apply_shrink (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gint radius_x,
+ gint radius_y,
+ gboolean edge_lock);
+
void gimp_gegl_apply_gaussian_blur (GeglBuffer *src_buffer,
GimpProgress *progress,
const gchar *undo_desc,
GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
gdouble std_dev_x,
gdouble std_dev_y);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]