[gimp/goat-invasion: 505/526] app: add gimp_gegl_smudge_blend(), a brute-force port of blend_region()
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/goat-invasion: 505/526] app: add gimp_gegl_smudge_blend(), a brute-force port of blend_region()
- Date: Sun, 22 Apr 2012 13:41:43 +0000 (UTC)
commit f8c8d6c8a7099c4af89143c606a40d987124d947
Author: Michael Natterer <mitch gimp org>
Date: Wed Apr 18 00:32:10 2012 +0200
app: add gimp_gegl_smudge_blend(), a brute-force port of blend_region()
and use it in GimpSmudge. This only to get functionality ported and
the API done, and not the final state.
app/gegl/gimp-gegl-loops.c | 99 ++++++++++++++++++++++++++++++++++++++++++++
app/gegl/gimp-gegl-loops.h | 40 +++++++++++-------
app/paint/gimpsmudge.c | 69 +++++++++++++++---------------
3 files changed, 157 insertions(+), 51 deletions(-)
---
diff --git a/app/gegl/gimp-gegl-loops.c b/app/gegl/gimp-gegl-loops.c
index 84d79ac..0983c9c 100644
--- a/app/gegl/gimp-gegl-loops.c
+++ b/app/gegl/gimp-gegl-loops.c
@@ -307,3 +307,102 @@ gimp_gegl_dodgeburn (GeglBuffer *src_buffer,
break;
}
}
+
+/*
+ * blend_pixels patched 8-24-05 to fix bug #163721. Note that this change
+ * causes the function to treat src1 and src2 asymmetrically. This gives the
+ * right behavior for the smudge tool, which is the only user of this function
+ * at the time of patching. If you want to use the function for something
+ * else, caveat emptor.
+ */
+void
+gimp_gegl_smudge_blend (GeglBuffer *top_buffer,
+ const GeglRectangle *top_rect,
+ GeglBuffer *bottom_buffer,
+ const GeglRectangle *bottom_rect,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ guchar blend)
+{
+ GeglBufferIterator *iter;
+ const Babl *top_format;
+ const Babl *bottom_format;
+ const Babl *dest_format;
+ gint top_bpp;
+ gint bottom_bpp;
+ gint dest_bpp;
+
+ top_format = gegl_buffer_get_format (top_buffer);
+ bottom_format = gegl_buffer_get_format (bottom_buffer);
+ dest_format = gegl_buffer_get_format (dest_buffer);
+
+ top_bpp = babl_format_get_bytes_per_pixel (top_format);
+ bottom_bpp = babl_format_get_bytes_per_pixel (bottom_format);
+ dest_bpp = babl_format_get_bytes_per_pixel (dest_format);
+
+ iter = gegl_buffer_iterator_new (top_buffer, top_rect, 0, NULL,
+ GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
+
+ gegl_buffer_iterator_add (iter, bottom_buffer, bottom_rect, 0, NULL,
+ GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
+
+ gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0, NULL,
+ GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
+
+ while (gegl_buffer_iterator_next (iter))
+ {
+ const guchar *top = iter->data[0];
+ const guchar *bottom = iter->data[1];
+ guchar *dest = iter->data[2];
+
+ if (babl_format_has_alpha (top_format))
+ {
+ const guint blend1 = 255 - blend;
+ const guint blend2 = blend + 1;
+ const guint c = top_bpp - 1;
+
+ while (iter->length--)
+ {
+ const gint a1 = blend1 * bottom[c];
+ const gint a2 = blend2 * top[c];
+ const gint a = a1 + a2;
+ guint b;
+
+ if (!a)
+ {
+ for (b = 0; b < top_bpp; b++)
+ dest[b] = 0;
+ }
+ else
+ {
+ for (b = 0; b < c; b++)
+ dest[b] =
+ bottom[b] + (bottom[b] * a1 + top[b] * a2 - a * bottom[b]) / a;
+
+ dest[c] = a >> 8;
+ }
+
+ top += top_bpp;
+ bottom += bottom_bpp;
+ dest += dest_bpp;
+ }
+ }
+ else
+ {
+ const guchar blend1 = 255 - blend;
+
+ while (iter->length--)
+ {
+ guint b;
+
+ for (b = 0; b < top_bpp; b++)
+ dest[b] =
+ bottom[b] + (bottom[b] * blend1 + top[b] * blend - bottom[b] * 255) / 255;
+
+ top += top_bpp;
+ bottom += bottom_bpp;
+ dest += dest_bpp;
+ }
+ }
+ }
+}
diff --git a/app/gegl/gimp-gegl-loops.h b/app/gegl/gimp-gegl-loops.h
index 525c799..a85bb5b 100644
--- a/app/gegl/gimp-gegl-loops.h
+++ b/app/gegl/gimp-gegl-loops.h
@@ -25,23 +25,31 @@
/* this is a pretty stupid port of concolve_region() that only works
* on a linear source buffer
*/
-void gimp_gegl_convolve (GeglBuffer *src_buffer,
- const GeglRectangle *src_rect,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect,
- const gfloat *kernel,
- gint kernel_size,
- gdouble divisor,
- GimpConvolutionType mode,
- gboolean alpha_weighting);
+void gimp_gegl_convolve (GeglBuffer *src_buffer,
+ const GeglRectangle *src_rect,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ const gfloat *kernel,
+ gint kernel_size,
+ gdouble divisor,
+ GimpConvolutionType mode,
+ gboolean alpha_weighting);
-void gimp_gegl_dodgeburn (GeglBuffer *src_buffer,
- const GeglRectangle *src_rect,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect,
- gdouble exposure,
- GimpDodgeBurnType type,
- GimpTransferMode mode);
+void gimp_gegl_dodgeburn (GeglBuffer *src_buffer,
+ const GeglRectangle *src_rect,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gdouble exposure,
+ GimpDodgeBurnType type,
+ GimpTransferMode mode);
+
+void gimp_gegl_smudge_blend (GeglBuffer *top_buffer,
+ const GeglRectangle *top_rect,
+ GeglBuffer *bottom_buffer,
+ const GeglRectangle *bottom_rect,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ guchar blend);
#endif /* __GIMP_GEGL_LOOPS_H__ */
diff --git a/app/paint/gimpsmudge.c b/app/paint/gimpsmudge.c
index a4b7494..8129a40 100644
--- a/app/paint/gimpsmudge.c
+++ b/app/paint/gimpsmudge.c
@@ -23,13 +23,9 @@
#include "paint-types.h"
-#include "base/pixel-region.h"
-
-#include "paint-funcs/paint-funcs.h"
-
+#include "gegl/gimp-gegl-loops.h"
#include "gegl/gimp-gegl-utils.h"
-#include "core/gimp.h"
#include "core/gimpbrush.h"
#include "core/gimpdrawable.h"
#include "core/gimpdynamics.h"
@@ -164,13 +160,12 @@ gimp_smudge_start (GimpPaintCore *paint_core,
GimpPaintOptions *paint_options,
const GimpCoords *coords)
{
- GimpSmudge *smudge = GIMP_SMUDGE (paint_core);
- GeglBuffer *paint_buffer;
- gint paint_buffer_x;
- gint paint_buffer_y;
- GimpTempBuf *accum_temp;
- gint accum_size;
- gint x, y;
+ GimpSmudge *smudge = GIMP_SMUDGE (paint_core);
+ GeglBuffer *paint_buffer;
+ gint paint_buffer_x;
+ gint paint_buffer_y;
+ gint accum_size;
+ gint x, y;
if (gimp_drawable_is_indexed (drawable))
return FALSE;
@@ -185,10 +180,10 @@ gimp_smudge_start (GimpPaintCore *paint_core,
gimp_smudge_accumulator_size (paint_options, &accum_size);
/* Allocate the accumulation buffer */
- accum_temp = gimp_temp_buf_new (accum_size, accum_size,
- gimp_drawable_get_format (drawable));
- smudge->accum_buffer = gimp_temp_buf_create_buffer (accum_temp);
- gimp_temp_buf_unref (accum_temp);
+ smudge->accum_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+ accum_size,
+ accum_size),
+ gimp_drawable_get_format (drawable));
/* adjust the x and y coordinates to the upper left corner of the
* accumulator
@@ -251,7 +246,8 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
GeglBuffer *paint_buffer;
gint paint_buffer_x;
gint paint_buffer_y;
- PixelRegion srcPR, tempPR;
+ gint paint_buffer_width;
+ gint paint_buffer_height;
gdouble fade_point;
gdouble opacity;
gdouble rate;
@@ -284,16 +280,12 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
if (! paint_buffer)
return;
+ paint_buffer_width = gegl_buffer_get_width (paint_buffer);
+ paint_buffer_height = gegl_buffer_get_height (paint_buffer);
+
/* Get the unclipped acumulator coordinates */
gimp_smudge_accumulator_coords (paint_core, coords, &x, &y);
- /* srcPR will be the pixels under the current painthit from the drawable */
- pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
- paint_buffer_x,
- paint_buffer_y,
- gegl_buffer_get_width (paint_buffer),
- gegl_buffer_get_height (paint_buffer), FALSE);
-
/* Enable dynamic rate */
rate_output = gimp_dynamics_get_output (dynamics,
GIMP_DYNAMICS_OUTPUT_RATE);
@@ -305,14 +297,6 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
rate = (options->rate / 100.0) * dynamic_rate;
- /* The tempPR will be the built up buffer (for smudge) */
- pixel_region_init_temp_buf (&tempPR,
- gimp_gegl_buffer_get_temp_buf (smudge->accum_buffer),
- paint_buffer_x - x,
- paint_buffer_y - y,
- gegl_buffer_get_width (paint_buffer),
- gegl_buffer_get_height (paint_buffer));
-
/* Smudge uses the buffer Accum.
* For each successive painthit Accum is built like this
* Accum = rate*Accum + (1-rate)*I.
@@ -321,13 +305,28 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
* (Accum,1) (if no alpha),
*/
- blend_region (&srcPR, &tempPR, &tempPR, ROUND (rate * 255.0));
+ gimp_gegl_smudge_blend (smudge->accum_buffer,
+ GEGL_RECTANGLE (paint_buffer_x - x,
+ paint_buffer_y - y,
+ paint_buffer_width,
+ paint_buffer_height),
+ gimp_drawable_get_buffer (drawable),
+ GEGL_RECTANGLE (paint_buffer_x,
+ paint_buffer_y,
+ paint_buffer_width,
+ paint_buffer_height),
+ smudge->accum_buffer,
+ GEGL_RECTANGLE (paint_buffer_x - x,
+ paint_buffer_y - y,
+ paint_buffer_width,
+ paint_buffer_height),
+ ROUND (rate * 255.0));
gegl_buffer_copy (smudge->accum_buffer,
GEGL_RECTANGLE (paint_buffer_x - x,
paint_buffer_y - y,
- gegl_buffer_get_width (paint_buffer),
- gegl_buffer_get_height (paint_buffer)),
+ paint_buffer_width,
+ paint_buffer_height),
paint_buffer,
GEGL_RECTANGLE (0, 0, 0, 0));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]