[gimp] app: add gimp_histogram_calculate_async()
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add gimp_histogram_calculate_async()
- Date: Fri, 11 May 2018 18:02:40 +0000 (UTC)
commit 9ea560d4a9d0208172a67858a9843df0592bd9f7
Author: Ell <ell_se yahoo com>
Date: Fri May 11 11:51:30 2018 -0400
app: add gimp_histogram_calculate_async()
... which is similar to gimp_histogram_calculate(), calculating the
histogram asynchronously on a separate thread.
app/core/gimphistogram.c | 760 ++++++++++++++++++++++++++++++----------------
app/core/gimphistogram.h | 93 +++---
2 files changed, 548 insertions(+), 305 deletions(-)
---
diff --git a/app/core/gimphistogram.c b/app/core/gimphistogram.c
index 8ae8aaa..4314d50 100644
--- a/app/core/gimphistogram.c
+++ b/app/core/gimphistogram.c
@@ -31,6 +31,8 @@
#include "gegl/gimp-babl.h"
+#include "gimp-parallel.h"
+#include "gimpasync.h"
#include "gimphistogram.h"
@@ -44,31 +46,55 @@ enum
struct _GimpHistogramPrivate
{
- gboolean linear;
- gint n_channels;
- gint n_bins;
- gdouble *values;
+ gboolean linear;
+ gint n_channels;
+ gint n_bins;
+ gdouble *values;
+ GimpAsync *calculate_async;
};
+typedef struct
+{
+ GimpHistogram *histogram;
+ GeglBuffer *buffer;
+ GeglRectangle buffer_rect;
+ GeglBuffer *mask;
+ GeglRectangle mask_rect;
-/* local function prototypes */
+ gint n_components;
+ gint n_bins;
+ gdouble *values;
+} CalculateContext;
-static void gimp_histogram_finalize (GObject *object);
-static void gimp_histogram_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_histogram_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-static gint64 gimp_histogram_get_memsize (GimpObject *object,
- gint64 *gui_size);
+/* local function prototypes */
-static void gimp_histogram_alloc_values (GimpHistogram *histogram,
- gint n_components,
- gint n_bins);
+static void gimp_histogram_dispose (GObject *object);
+static void gimp_histogram_finalize (GObject *object);
+static void gimp_histogram_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_histogram_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static gint64 gimp_histogram_get_memsize (GimpObject *object,
+ gint64 *gui_size);
+
+static gdouble * gimp_histogram_alloc_values (GimpHistogram *histogram,
+ gint n_components,
+ gint n_bins);
+static void gimp_histogram_set_values (GimpHistogram *histogram,
+ gint n_components,
+ gint n_bins,
+ gdouble *values);
+
+static void gimp_histogram_calculate_internal (GimpAsync *async,
+ CalculateContext *context);
+static void gimp_histogram_calculate_async_callback (GimpAsync *async,
+ CalculateContext *context);
G_DEFINE_TYPE (GimpHistogram, gimp_histogram, GIMP_TYPE_OBJECT)
@@ -82,6 +108,7 @@ gimp_histogram_class_init (GimpHistogramClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
+ object_class->dispose = gimp_histogram_dispose;
object_class->finalize = gimp_histogram_finalize;
object_class->set_property = gimp_histogram_set_property;
object_class->get_property = gimp_histogram_get_property;
@@ -118,6 +145,20 @@ gimp_histogram_init (GimpHistogram *histogram)
}
static void
+gimp_histogram_dispose (GObject *object)
+{
+ GimpHistogram *histogram = GIMP_HISTOGRAM (object);
+
+ if (histogram->priv->calculate_async)
+ {
+ gimp_async_cancel (histogram->priv->calculate_async);
+ gimp_async_wait (histogram->priv->calculate_async);
+ }
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
gimp_histogram_finalize (GObject *object)
{
GimpHistogram *histogram = GIMP_HISTOGRAM (object);
@@ -213,6 +254,9 @@ gimp_histogram_duplicate (GimpHistogram *histogram)
g_return_val_if_fail (GIMP_IS_HISTOGRAM (histogram), NULL);
+ if (histogram->priv->calculate_async)
+ gimp_async_wait (histogram->priv->calculate_async);
+
dup = gimp_histogram_new (histogram->priv->linear);
dup->priv->n_channels = histogram->priv->n_channels;
@@ -232,264 +276,92 @@ gimp_histogram_calculate (GimpHistogram *histogram,
GeglBuffer *mask,
const GeglRectangle *mask_rect)
{
- GimpHistogramPrivate *priv;
- GeglBufferIterator *iter;
- const Babl *format;
- gint n_components;
- gint n_bins;
- gfloat n_bins_1f;
- gfloat temp;
+ CalculateContext context = {};
g_return_if_fail (GIMP_IS_HISTOGRAM (histogram));
g_return_if_fail (GEGL_IS_BUFFER (buffer));
g_return_if_fail (buffer_rect != NULL);
- priv = histogram->priv;
-
- format = gegl_buffer_get_format (buffer);
-
- if (babl_format_get_type (format, 0) == babl_type ("u8"))
- n_bins = 256;
- else
- n_bins = 1024;
-
- if (babl_format_is_palette (format))
+ if (histogram->priv->calculate_async)
{
- if (babl_format_has_alpha (format))
- {
- if (priv->linear)
- format = babl_format ("RGB float");
- else
- format = babl_format ("R'G'B' float");
- }
- else
- {
- if (priv->linear)
- format = babl_format ("RGBA float");
- else
- format = babl_format ("R'G'B'A float");
- }
- }
- else
- {
- const Babl *model = babl_format_get_model (format);
-
- if (model == babl_model ("Y") ||
- model == babl_model ("Y'"))
- {
- if (priv->linear)
- format = babl_format ("Y float");
- else
- format = babl_format ("Y' float");
- }
- else if (model == babl_model ("YA") ||
- model == babl_model ("Y'A"))
- {
- if (priv->linear)
- format = babl_format ("YA float");
- else
- format = babl_format ("Y'A float");
- }
- else if (model == babl_model ("RGB") ||
- model == babl_model ("R'G'B'"))
- {
- if (priv->linear)
- format = babl_format ("RGB float");
- else
- format = babl_format ("R'G'B' float");
- }
- else if (model == babl_model ("RGBA") ||
- model == babl_model ("R'G'B'A"))
- {
- if (priv->linear)
- format = babl_format ("RGBA float");
- else
- format = babl_format ("R'G'B'A float");
- }
- else
- {
- g_return_if_reached ();
- }
+ gimp_async_cancel (histogram->priv->calculate_async);
+ gimp_async_wait (histogram->priv->calculate_async);
}
- n_components = babl_format_get_n_components (format);
-
- g_object_freeze_notify (G_OBJECT (histogram));
-
- gimp_histogram_alloc_values (histogram, n_components, n_bins);
-
- iter = gegl_buffer_iterator_new (buffer, buffer_rect, 0, format,
- GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ context.histogram = histogram;
+ context.buffer = buffer;
+ context.buffer_rect = *buffer_rect;
if (mask)
- gegl_buffer_iterator_add (iter, mask, mask_rect, 0,
- babl_format ("Y float"),
- GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
-
- n_bins_1f = priv->n_bins - 1;
-
-#define VALUE(c,i) (*(temp = (i) * n_bins_1f, \
- &priv->values[(c) * priv->n_bins + \
- SIGNED_ROUND (SAFE_CLAMP (temp, \
- 0.0f, \
- n_bins_1f))]))
-
- while (gegl_buffer_iterator_next (iter))
{
- const gfloat *data = iter->data[0];
- gint length = iter->length;
- gfloat max;
- gfloat luminance;
-
- if (mask)
- {
- const gfloat *mask_data = iter->data[1];
-
- switch (n_components)
- {
- case 1:
- while (length--)
- {
- const gdouble masked = *mask_data;
-
- VALUE (0, data[0]) += masked;
-
- data += n_components;
- mask_data += 1;
- }
- break;
-
- case 2:
- while (length--)
- {
- const gdouble masked = *mask_data;
- const gdouble weight = data[1];
-
- VALUE (0, data[0]) += weight * masked;
- VALUE (1, data[1]) += masked;
-
- data += n_components;
- mask_data += 1;
- }
- break;
-
- case 3: /* calculate separate value values */
- while (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;
-
- luminance = GIMP_RGB_LUMINANCE (data[0], data[1], data[2]);
- VALUE (4, luminance) += masked;
-
- data += n_components;
- mask_data += 1;
- }
- break;
+ context.mask = mask;
- case 4: /* calculate separate value values */
- while (length--)
- {
- const gdouble masked = *mask_data;
- const gdouble weight = data[3];
-
- 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;
-
- luminance = GIMP_RGB_LUMINANCE (data[0], data[1], data[2]);
- VALUE (5, luminance) += weight * masked;
-
- data += n_components;
- mask_data += 1;
- }
- break;
- }
- }
- else /* no mask */
- {
- switch (n_components)
- {
- case 1:
- while (length--)
- {
- VALUE (0, data[0]) += 1.0;
-
- data += n_components;
- }
- break;
-
- case 2:
- while (length--)
- {
- const gdouble weight = data[1];
+ if (mask_rect)
+ context.mask_rect = *mask_rect;
+ else
+ context.mask_rect = *gegl_buffer_get_extent (mask);
+ }
- VALUE (0, data[0]) += weight;
- VALUE (1, data[1]) += 1.0;
+ gimp_histogram_calculate_internal (NULL, &context);
- data += n_components;
- }
- break;
+ gimp_histogram_set_values (histogram,
+ context.n_components, context.n_bins,
+ context.values);
+}
- case 3: /* calculate separate value values */
- while (length--)
- {
- VALUE (1, data[0]) += 1.0;
- VALUE (2, data[1]) += 1.0;
- VALUE (3, data[2]) += 1.0;
+GimpAsync *
+gimp_histogram_calculate_async (GimpHistogram *histogram,
+ GeglBuffer *buffer,
+ const GeglRectangle *buffer_rect,
+ GeglBuffer *mask,
+ const GeglRectangle *mask_rect)
+{
+ CalculateContext *context;
- max = MAX (data[0], data[1]);
- max = MAX (data[2], max);
- VALUE (0, max) += 1.0;
+ g_return_val_if_fail (GIMP_IS_HISTOGRAM (histogram), NULL);
+ g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
+ g_return_val_if_fail (buffer_rect != NULL, NULL);
- luminance = GIMP_RGB_LUMINANCE (data[0], data[1], data[2]);
- VALUE (4, luminance) += 1.0;
+ if (histogram->priv->calculate_async)
+ {
+ gimp_async_cancel (histogram->priv->calculate_async);
+ gimp_async_wait (histogram->priv->calculate_async);
+ }
- data += n_components;
- }
- break;
+ context = g_slice_new0 (CalculateContext);
- case 4: /* calculate separate value values */
- while (length--)
- {
- const gdouble weight = data[3];
+ context->histogram = histogram;
+ context->buffer = gegl_buffer_new (buffer_rect,
+ gegl_buffer_get_format (buffer));
+ context->buffer_rect = *buffer_rect;
- VALUE (1, data[0]) += weight;
- VALUE (2, data[1]) += weight;
- VALUE (3, data[2]) += weight;
- VALUE (4, data[3]) += 1.0;
+ gegl_buffer_copy (buffer, buffer_rect, GEGL_ABYSS_NONE,
+ context->buffer, NULL);
- max = MAX (data[0], data[1]);
- max = MAX (data[2], max);
- VALUE (0, max) += weight;
+ if (mask)
+ {
+ if (mask_rect)
+ context->mask_rect = *mask_rect;
+ else
+ context->mask_rect = *gegl_buffer_get_extent (mask);
- luminance = GIMP_RGB_LUMINANCE (data[0], data[1], data[2]);
- VALUE (5, luminance) += weight;
+ context->mask = gegl_buffer_new (&context->mask_rect,
+ gegl_buffer_get_format (mask));
- data += n_components;
- }
- break;
- }
- }
+ gegl_buffer_copy (mask, &context->mask_rect, GEGL_ABYSS_NONE,
+ context->mask, NULL);
}
- g_object_notify (G_OBJECT (histogram), "values");
+ histogram->priv->calculate_async = gimp_parallel_run_async (
+ (GimpParallelRunAsyncFunc) gimp_histogram_calculate_internal,
+ context);
- g_object_thaw_notify (G_OBJECT (histogram));
+ gimp_async_add_callback (
+ histogram->priv->calculate_async,
+ (GimpAsyncCallback) gimp_histogram_calculate_async_callback,
+ context);
-#undef VALUE
+ return histogram->priv->calculate_async;
}
void
@@ -951,7 +823,7 @@ gimp_histogram_get_std_dev (GimpHistogram *histogram,
/* private functions */
-static void
+static gdouble *
gimp_histogram_alloc_values (GimpHistogram *histogram,
gint n_components,
gint n_bins)
@@ -961,27 +833,393 @@ gimp_histogram_alloc_values (GimpHistogram *histogram,
if (n_components + 2 != priv->n_channels ||
n_bins != priv->n_bins)
{
- gimp_histogram_clear_values (histogram);
+ return g_new0 (gdouble, (n_components + 2) * n_bins);
+ }
+ else
+ {
+ memset (priv->values, 0,
+ priv->n_channels * priv->n_bins * sizeof (gdouble));
+
+ return priv->values;
+ }
+}
+
+static void
+gimp_histogram_set_values (GimpHistogram *histogram,
+ gint n_components,
+ gint n_bins,
+ gdouble *values)
+{
+ GimpHistogramPrivate *priv = histogram->priv;
+ gboolean notify_n_channels = FALSE;
+ gboolean notify_n_bins = FALSE;
+
+ if (n_components + 2 != priv->n_channels)
+ {
+ priv->n_channels = n_components + 2;
+
+ notify_n_channels = TRUE;
+ }
+
+ if (n_bins != priv->n_bins)
+ {
+ priv->n_bins = n_bins;
+
+ notify_n_bins = TRUE;
+ }
+
+ if (values != priv->values)
+ {
+ if (priv->values)
+ g_free (priv->values);
+
+ priv->values = values;
+ }
+
+ if (notify_n_channels)
+ g_object_notify (G_OBJECT (histogram), "n-channels");
+
+ if (notify_n_bins)
+ g_object_notify (G_OBJECT (histogram), "n-bins");
- if (n_components + 2 != priv->n_channels)
+ g_object_notify (G_OBJECT (histogram), "values");
+}
+
+static void
+gimp_histogram_calculate_internal (GimpAsync *async,
+ CalculateContext *context)
+{
+ GimpHistogramPrivate *priv;
+ GeglBufferIterator *iter;
+ const Babl *format;
+ gdouble *values;
+ gint n_components;
+ gint n_bins;
+ gfloat n_bins_1f;
+ gfloat temp;
+
+ priv = context->histogram->priv;
+
+ format = gegl_buffer_get_format (context->buffer);
+
+ if (babl_format_get_type (format, 0) == babl_type ("u8"))
+ n_bins = 256;
+ else
+ n_bins = 1024;
+
+ if (babl_format_is_palette (format))
+ {
+ if (babl_format_has_alpha (format))
+ {
+ if (priv->linear)
+ format = babl_format ("RGB float");
+ else
+ format = babl_format ("R'G'B' float");
+ }
+ else
+ {
+ if (priv->linear)
+ format = babl_format ("RGBA float");
+ else
+ format = babl_format ("R'G'B'A float");
+ }
+ }
+ else
+ {
+ const Babl *model = babl_format_get_model (format);
+
+ if (model == babl_model ("Y") ||
+ model == babl_model ("Y'"))
+ {
+ if (priv->linear)
+ format = babl_format ("Y float");
+ else
+ format = babl_format ("Y' float");
+ }
+ else if (model == babl_model ("YA") ||
+ model == babl_model ("Y'A"))
+ {
+ if (priv->linear)
+ format = babl_format ("YA float");
+ else
+ format = babl_format ("Y'A float");
+ }
+ else if (model == babl_model ("RGB") ||
+ model == babl_model ("R'G'B'"))
+ {
+ if (priv->linear)
+ format = babl_format ("RGB float");
+ else
+ format = babl_format ("R'G'B' float");
+ }
+ else if (model == babl_model ("RGBA") ||
+ model == babl_model ("R'G'B'A"))
{
- priv->n_channels = n_components + 2;
+ if (priv->linear)
+ format = babl_format ("RGBA float");
+ else
+ format = babl_format ("R'G'B'A float");
+ }
+ else
+ {
+ if (async)
+ gimp_async_abort (async);
- g_object_notify (G_OBJECT (histogram), "n-channels");
+ g_return_if_reached ();
}
+ }
+
+ n_components = babl_format_get_n_components (format);
+
+ if (async)
+ {
+ values = g_new0 (gdouble, (n_components + 2) * n_bins);
+ }
+ else
+ {
+ values = gimp_histogram_alloc_values (context->histogram,
+ n_components, n_bins);
+ }
- if (n_bins != priv->n_bins)
+ iter = gegl_buffer_iterator_new (context->buffer, &context->buffer_rect, 0,
+ format,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+
+ if (context->mask)
+ gegl_buffer_iterator_add (iter, context->mask, &context->mask_rect, 0,
+ babl_format ("Y float"),
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+
+ n_bins_1f = n_bins - 1;
+
+#define VALUE(c,i) (*(temp = (i) * n_bins_1f, \
+ &values[(c) * n_bins + \
+ SIGNED_ROUND (SAFE_CLAMP (temp, \
+ 0.0f, \
+ n_bins_1f))]))
+
+#define CHECK_CANCELED(length) \
+ G_STMT_START \
+ { \
+ if ((length) % 32 == 0 && async && gimp_async_is_canceled (async)) \
+ { \
+ gegl_buffer_iterator_stop (iter); \
+ \
+ goto end; \
+ } \
+ } \
+ G_STMT_END
+
+ while (gegl_buffer_iterator_next (iter))
+ {
+ const gfloat *data = iter->data[0];
+ gint length = iter->length;
+ gfloat max;
+ gfloat luminance;
+
+ CHECK_CANCELED (0);
+
+ if (context->mask)
{
- priv->n_bins = n_bins;
+ const gfloat *mask_data = iter->data[1];
- g_object_notify (G_OBJECT (histogram), "n-bins");
+ switch (n_components)
+ {
+ case 1:
+ while (length--)
+ {
+ const gdouble masked = *mask_data;
+
+ VALUE (0, data[0]) += masked;
+
+ data += n_components;
+ mask_data += 1;
+
+ CHECK_CANCELED (length);
+ }
+ break;
+
+ case 2:
+ while (length--)
+ {
+ const gdouble masked = *mask_data;
+ const gdouble weight = data[1];
+
+ VALUE (0, data[0]) += weight * masked;
+ VALUE (1, data[1]) += masked;
+
+ data += n_components;
+ mask_data += 1;
+
+ CHECK_CANCELED (length);
+ }
+ break;
+
+ case 3: /* calculate separate value values */
+ while (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;
+
+ luminance = GIMP_RGB_LUMINANCE (data[0], data[1], data[2]);
+ VALUE (4, luminance) += masked;
+
+ data += n_components;
+ mask_data += 1;
+
+ CHECK_CANCELED (length);
+ }
+ break;
+
+ case 4: /* calculate separate value values */
+ while (length--)
+ {
+ const gdouble masked = *mask_data;
+ const gdouble weight = data[3];
+
+ 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;
+
+ luminance = GIMP_RGB_LUMINANCE (data[0], data[1], data[2]);
+ VALUE (5, luminance) += weight * masked;
+
+ data += n_components;
+ mask_data += 1;
+
+ CHECK_CANCELED (length);
+ }
+ break;
+ }
}
+ else /* no mask */
+ {
+ switch (n_components)
+ {
+ case 1:
+ while (length--)
+ {
+ VALUE (0, data[0]) += 1.0;
- priv->values = g_new0 (gdouble, priv->n_channels * priv->n_bins);
+ data += n_components;
+
+ CHECK_CANCELED (length);
+ }
+ break;
+
+ case 2:
+ while (length--)
+ {
+ const gdouble weight = data[1];
+
+ VALUE (0, data[0]) += weight;
+ VALUE (1, data[1]) += 1.0;
+
+ data += n_components;
+
+ CHECK_CANCELED (length);
+ }
+ break;
+
+ case 3: /* calculate separate value values */
+ while (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;
+
+ luminance = GIMP_RGB_LUMINANCE (data[0], data[1], data[2]);
+ VALUE (4, luminance) += 1.0;
+
+ data += n_components;
+
+ CHECK_CANCELED (length);
+ }
+ break;
+
+ case 4: /* calculate separate value values */
+ while (length--)
+ {
+ const gdouble weight = data[3];
+
+ 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;
+
+ luminance = GIMP_RGB_LUMINANCE (data[0], data[1], data[2]);
+ VALUE (5, luminance) += weight;
+
+ data += n_components;
+
+ CHECK_CANCELED (length);
+ }
+ break;
+ }
+ }
+ }
+end:
+
+ context->n_components = n_components;
+ context->n_bins = n_bins;
+ context->values = values;
+
+ if (async)
+ {
+ if (! gimp_async_is_canceled (async))
+ {
+ gimp_async_finish (async, NULL);
+ }
+ else
+ {
+ gimp_async_abort (async);
+ }
+ }
+
+#undef VALUE
+#undef CHECK_CANCELED
+}
+
+static void
+gimp_histogram_calculate_async_callback (GimpAsync *async,
+ CalculateContext *context)
+{
+ context->histogram->priv->calculate_async = NULL;
+
+ if (gimp_async_is_finished (async))
+ {
+ gimp_histogram_set_values (context->histogram,
+ context->n_components, context->n_bins,
+ context->values);
}
else
{
- memset (priv->values, 0,
- priv->n_channels * priv->n_bins * sizeof (gdouble));
+ g_free (context->values);
}
+
+ g_object_unref (context->buffer);
+ if (context->mask)
+ g_object_unref (context->mask);
+
+ g_slice_free (CalculateContext, context);
}
diff --git a/app/core/gimphistogram.h b/app/core/gimphistogram.h
index c511e69..1c2a810 100644
--- a/app/core/gimphistogram.h
+++ b/app/core/gimphistogram.h
@@ -48,50 +48,55 @@ struct _GimpHistogramClass
};
-GType gimp_histogram_get_type (void) G_GNUC_CONST;
-
-GimpHistogram * gimp_histogram_new (gboolean linear);
-
-GimpHistogram * gimp_histogram_duplicate (GimpHistogram *histogram);
-
-void gimp_histogram_calculate (GimpHistogram *histogram,
- GeglBuffer *buffer,
- const GeglRectangle *buffer_rect,
- GeglBuffer *mask,
- const GeglRectangle *mask_rect);
-
-void gimp_histogram_clear_values (GimpHistogram *histogram);
-
-gdouble gimp_histogram_get_maximum (GimpHistogram *histogram,
- GimpHistogramChannel channel);
-gdouble gimp_histogram_get_count (GimpHistogram *histogram,
- GimpHistogramChannel channel,
- gint start,
- gint end);
-gdouble gimp_histogram_get_mean (GimpHistogram *histogram,
- GimpHistogramChannel channel,
- gint start,
- gint end);
-gdouble gimp_histogram_get_median (GimpHistogram *histogram,
- GimpHistogramChannel channel,
- gint start,
- gint end);
-gdouble gimp_histogram_get_std_dev (GimpHistogram *histogram,
- GimpHistogramChannel channel,
- gint start,
- gint end);
-gdouble gimp_histogram_get_threshold (GimpHistogram *histogram,
- GimpHistogramChannel channel,
- gint start,
- gint end);
-gdouble gimp_histogram_get_value (GimpHistogram *histogram,
- GimpHistogramChannel channel,
- gint bin);
-gdouble gimp_histogram_get_component (GimpHistogram *histogram,
- gint component,
- gint bin);
-gint gimp_histogram_n_channels (GimpHistogram *histogram);
-gint gimp_histogram_n_bins (GimpHistogram *histogram);
+GType gimp_histogram_get_type (void) G_GNUC_CONST;
+
+GimpHistogram * gimp_histogram_new (gboolean linear);
+
+GimpHistogram * gimp_histogram_duplicate (GimpHistogram *histogram);
+
+void gimp_histogram_calculate (GimpHistogram *histogram,
+ GeglBuffer *buffer,
+ const GeglRectangle *buffer_rect,
+ GeglBuffer *mask,
+ const GeglRectangle *mask_rect);
+GimpAsync * gimp_histogram_calculate_async (GimpHistogram *histogram,
+ GeglBuffer *buffer,
+ const GeglRectangle *buffer_rect,
+ GeglBuffer *mask,
+ const GeglRectangle *mask_rect);
+
+void gimp_histogram_clear_values (GimpHistogram *histogram);
+
+gdouble gimp_histogram_get_maximum (GimpHistogram *histogram,
+ GimpHistogramChannel channel);
+gdouble gimp_histogram_get_count (GimpHistogram *histogram,
+ GimpHistogramChannel channel,
+ gint start,
+ gint end);
+gdouble gimp_histogram_get_mean (GimpHistogram *histogram,
+ GimpHistogramChannel channel,
+ gint start,
+ gint end);
+gdouble gimp_histogram_get_median (GimpHistogram *histogram,
+ GimpHistogramChannel channel,
+ gint start,
+ gint end);
+gdouble gimp_histogram_get_std_dev (GimpHistogram *histogram,
+ GimpHistogramChannel channel,
+ gint start,
+ gint end);
+gdouble gimp_histogram_get_threshold (GimpHistogram *histogram,
+ GimpHistogramChannel channel,
+ gint start,
+ gint end);
+gdouble gimp_histogram_get_value (GimpHistogram *histogram,
+ GimpHistogramChannel channel,
+ gint bin);
+gdouble gimp_histogram_get_component (GimpHistogram *histogram,
+ gint component,
+ gint bin);
+gint gimp_histogram_n_channels (GimpHistogram *histogram);
+gint gimp_histogram_n_bins (GimpHistogram *histogram);
#endif /* __GIMP_HISTOGRAM_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]