[gimp/goat-invasion] app: implement the GEGL histogram with an iterator loop for now
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/goat-invasion] app: implement the GEGL histogram with an iterator loop for now
- Date: Mon, 16 Apr 2012 20:27:52 +0000 (UTC)
commit 473a0a7e20c7ae23e529040c39f589161c9ccbb0
Author: Michael Natterer <mitch gimp org>
Date: Mon Apr 16 21:01:39 2012 +0200
app: implement the GEGL histogram with an iterator loop for now
its body can later be reused in the working histogram sink op.
app/core/gimpdrawable-histogram.c | 28 +++++
app/core/gimphistogram.c | 196 +++++++++++++++++++++++++++++++++++--
app/core/gimphistogram.h | 6 +
3 files changed, 222 insertions(+), 8 deletions(-)
---
diff --git a/app/core/gimpdrawable-histogram.c b/app/core/gimpdrawable-histogram.c
index ebe4ac9b..d5efdd8 100644
--- a/app/core/gimpdrawable-histogram.c
+++ b/app/core/gimpdrawable-histogram.c
@@ -28,6 +28,7 @@
#include "gegl/gimp-gegl-nodes.h"
#include "gimp.h" /* gimp_use_gegl */
+#include "gimp-utils.h"
#include "gimpchannel.h"
#include "gimpdrawable-histogram.h"
#include "gimphistogram.h"
@@ -52,6 +53,8 @@ gimp_drawable_calculate_histogram (GimpDrawable *drawable,
image = gimp_item_get_image (GIMP_ITEM (drawable));
mask = gimp_image_get_mask (image);
+ GIMP_TIMER_START();
+
if (FALSE) // gimp_use_gegl (image->gimp))
{
GeglNode *node = gegl_node_new ();
@@ -99,6 +102,29 @@ gimp_drawable_calculate_histogram (GimpDrawable *drawable,
g_object_unref (processor);
g_object_unref (node);
}
+ else if (gimp_use_gegl (image->gimp))
+ {
+ if (! gimp_channel_is_empty (mask))
+ {
+ gint off_x, off_y;
+
+ gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
+
+ gimp_histogram_calc_gegl (histogram,
+ gimp_drawable_get_buffer (drawable),
+ GEGL_RECTANGLE (x, y, width, height),
+ gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)),
+ GEGL_RECTANGLE (x - off_x, y - off_y,
+ width, height));
+ }
+ else
+ {
+ gimp_histogram_calc_gegl (histogram,
+ gimp_drawable_get_buffer (drawable),
+ GEGL_RECTANGLE (x, y, width, height),
+ NULL, NULL);
+ }
+ }
else
{
PixelRegion region;
@@ -122,4 +148,6 @@ gimp_drawable_calculate_histogram (GimpDrawable *drawable,
gimp_histogram_calculate (histogram, ®ion, NULL);
}
}
+
+ GIMP_TIMER_END("histogram");
}
diff --git a/app/core/gimphistogram.c b/app/core/gimphistogram.c
index 0133378..4a3b5c6 100644
--- a/app/core/gimphistogram.c
+++ b/app/core/gimphistogram.c
@@ -22,7 +22,7 @@
#include <string.h>
#undef G_DISABLE_DEPRECATED /* GStaticMutex */
-#include <glib-object.h>
+#include <gegl.h>
#include "libgimpmath/gimpmath.h"
@@ -33,7 +33,6 @@
#include "gimphistogram.h"
-
#ifdef ENABLE_MP
#define NUM_SLOTS GIMP_MAX_NUM_THREADS
#else
@@ -136,6 +135,183 @@ gimp_histogram_duplicate (GimpHistogram *histogram)
}
void
+gimp_histogram_calc_gegl (GimpHistogram *histogram,
+ GeglBuffer *buffer,
+ const GeglRectangle *buffer_rect,
+ GeglBuffer *mask,
+ const GeglRectangle *mask_rect)
+{
+ GeglBufferIterator *iter;
+ const Babl *format;
+ gint bpp;
+ gdouble *values;
+
+ g_return_if_fail (histogram != NULL);
+ g_return_if_fail (GEGL_IS_BUFFER (buffer));
+ g_return_if_fail (buffer_rect != NULL);
+
+ format = gegl_buffer_get_format (buffer);
+ bpp = babl_format_get_bytes_per_pixel (format);
+
+ gimp_histogram_alloc_values (histogram, bpp);
+
+ iter = gegl_buffer_iterator_new (buffer, buffer_rect, 0, NULL,
+ GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
+
+ if (mask)
+ gegl_buffer_iterator_add (iter, mask, mask_rect, 0,
+ babl_format ("Y float"),
+ GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
+
+ values = histogram->values[0];
+
+#define VALUE(c,i) (values[(c) * 256 + (i)])
+
+ while (gegl_buffer_iterator_next (iter))
+ {
+ const guchar *data = iter->data[0];
+ gint max;
+
+ if (mask)
+ {
+ const gfloat *mask_data = iter->data[1];
+
+ switch (bpp)
+ {
+ case 1:
+ while (iter->length)
+ {
+ const gdouble masked = *mask_data;
+
+ VALUE (0, data[0]) += masked;
+
+ data += bpp;
+ mask_data += 1;
+ }
+ break;
+
+ case 2:
+ while (iter->length--)
+ {
+ const gdouble masked = *mask_data;
+ const gdouble weight = data[1] / 255.0;
+
+ VALUE (0, data[0]) += weight * masked;
+ VALUE (1, data[1]) += masked;
+
+ data += bpp;
+ mask_data += 1;
+ }
+ break;
+
+ case 3: /* calculate separate value values */
+ while (iter->length--)
+ {
+ const gdouble masked = *mask_data;
+
+ VALUE (1, data[0]) += masked;
+ VALUE (2, data[1]) += masked;
+ VALUE (3, data[2]) += masked;
+
+ max = MAX (data[0], data[1]);
+ max = MAX (data[2], max);
+
+ VALUE (0, max) += masked;
+
+ data += bpp;
+ mask_data += 1;
+ }
+ break;
+
+ case 4: /* calculate separate value values */
+ while (iter->length--)
+ {
+ const gdouble masked = *mask_data;
+ const gdouble weight = data[3] / 255.0;
+
+ VALUE (1, data[0]) += weight * masked;
+ VALUE (2, data[1]) += weight * masked;
+ VALUE (3, data[2]) += weight * masked;
+ VALUE (4, data[3]) += masked;
+
+ max = MAX (data[0], data[1]);
+ max = MAX (data[2], max);
+
+ VALUE (0, max) += weight * masked;
+
+ data += bpp;
+ mask_data += 1;
+ }
+ break;
+ }
+ }
+ else /* no mask */
+ {
+ switch (bpp)
+ {
+ case 1:
+ while (iter->length--)
+ {
+ VALUE (0, data[0]) += 1.0;
+
+ data += bpp;
+ }
+ break;
+
+ case 2:
+ while (iter->length--)
+ {
+ const gdouble weight = data[1] / 255;
+
+ VALUE (0, data[0]) += weight;
+ VALUE (1, data[1]) += 1.0;
+
+ data += bpp;
+ }
+ break;
+
+ case 3: /* calculate separate value values */
+ while (iter->length--)
+ {
+ VALUE (1, data[0]) += 1.0;
+ VALUE (2, data[1]) += 1.0;
+ VALUE (3, data[2]) += 1.0;
+
+ max = MAX (data[0], data[1]);
+ max = MAX (data[2], max);
+
+ VALUE (0, max) += 1.0;
+
+ data += bpp;
+ }
+ break;
+
+ case 4: /* calculate separate value values */
+ while (iter->length--)
+ {
+ const gdouble weight = data[3] / 255;
+
+ VALUE (1, data[0]) += weight;
+ VALUE (2, data[1]) += weight;
+ VALUE (3, data[2]) += weight;
+ VALUE (4, data[3]) += 1.0;
+
+ max = MAX (data[0], data[1]);
+ max = MAX (data[2], max);
+
+ VALUE (0, max) += weight;
+
+ data += bpp;
+ }
+ break;
+ }
+ }
+ }
+
+#undef VALUE
+}
+
+void
gimp_histogram_calculate (GimpHistogram *histogram,
PixelRegion *region,
PixelRegion *mask)
@@ -147,11 +323,6 @@ gimp_histogram_calculate (GimpHistogram *histogram,
gimp_histogram_alloc_values (histogram, region->bytes);
- for (i = 0; i < NUM_SLOTS; i++)
- if (histogram->values[i])
- memset (histogram->values[i],
- 0, histogram->n_channels * 256 * sizeof (gdouble));
-
pixel_regions_process_parallel ((PixelProcessorFunc)
gimp_histogram_calculate_sub_region,
histogram, 2, region, mask);
@@ -565,7 +736,16 @@ gimp_histogram_alloc_values (GimpHistogram *histogram,
histogram->n_channels = bytes + 1;
- histogram->values[0] = g_new (gdouble, histogram->n_channels * 256);
+ histogram->values[0] = g_new0 (gdouble, histogram->n_channels * 256);
+ }
+ else
+ {
+ gint i;
+
+ for (i = 0; i < NUM_SLOTS; i++)
+ if (histogram->values[i])
+ memset (histogram->values[i],
+ 0, histogram->n_channels * 256 * sizeof (gdouble));
}
}
diff --git a/app/core/gimphistogram.h b/app/core/gimphistogram.h
index 2174122..76294fe 100644
--- a/app/core/gimphistogram.h
+++ b/app/core/gimphistogram.h
@@ -28,6 +28,12 @@ void gimp_histogram_unref (GimpHistogram *histogram);
GimpHistogram * gimp_histogram_duplicate (GimpHistogram *histogram);
+void gimp_histogram_calc_gegl (GimpHistogram *histogram,
+ GeglBuffer *buffer,
+ const GeglRectangle *buffer_rect,
+ GeglBuffer *mask,
+ const GeglRectangle *mask_rect);
+
void gimp_histogram_calculate (GimpHistogram *histogram,
PixelRegion *region,
PixelRegion *mask);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]