From cf86aeceb3df5592ad18f572ef8675e5d54b974e Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Sun, 25 Mar 2012 00:12:15 +0100 Subject: [PATCH] app: add GimpOperationEqualize and port equalize to it --- app/base/Makefile.am | 2 - app/base/lut-funcs.c | 101 -------------- app/base/lut-funcs.h | 26 ---- app/core/gimpdrawable-equalize.c | 22 +-- app/gegl/Makefile.am | 2 + app/gegl/gimp-gegl-types.h | 1 + app/gegl/gimp-gegl.c | 2 + app/gegl/gimpoperationequalize.c | 223 +++++++++++++++++++++++++++++++ app/gegl/gimpoperationequalize.h | 55 ++++++++ 9 files changed, 296 insertions(+), 138 deletions(-) delete mode 100644 app/base/lut-funcs.c delete mode 100644 app/base/lut-funcs.h create mode 100644 app/gegl/gimpoperationequalize.c create mode 100644 app/gegl/gimpoperationequalize.h diff --git a/app/base/Makefile.am b/app/base/Makefile.am index ace81463e7..59d31f6f5f 100644 --- a/app/base/Makefile.am +++ b/app/base/Makefile.am @@ -30,8 +30,6 @@ libappbase_a_SOURCES = \ gimplut.h \ hue-saturation.c \ hue-saturation.h \ - lut-funcs.c \ - lut-funcs.h \ pixel-processor.c \ pixel-processor.h \ pixel-region.c \ diff --git a/app/base/lut-funcs.c b/app/base/lut-funcs.c deleted file mode 100644 index e817e83e13..0000000000 --- a/app/base/lut-funcs.c +++ /dev/null @@ -1,101 +0,0 @@ -/* GIMP - The GNU Image Manipulation Program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "config.h" - -#include - -#include "libgimpmath/gimpmath.h" - -#include "core/core-types.h" - -#include "core/gimphistogram.h" -#include "gimplut.h" -#include "lut-funcs.h" - - -/* --------------- equalize ------------- */ - -typedef struct -{ - GimpHistogram *histogram; - gint part[5][256]; -} hist_lut_struct; - -static gfloat -equalize_lut_func (hist_lut_struct *hlut, - gint nchannels, - gint channel, - gfloat value) -{ - gint j; - - /* don't equalize the alpha channel */ - if ((nchannels == 2 || nchannels == 4) && channel == nchannels - 1) - return value; - - j = RINT (CLAMP (value * 255.0, 0, 255)); - - return hlut->part[channel][j] / 255.; -} - -static void -equalize_lut_setup (GimpLut *lut, - GimpHistogram *hist, - gint n_channels) -{ - gint i, k; - hist_lut_struct hlut; - gdouble pixels; - - g_return_if_fail (lut != NULL); - g_return_if_fail (hist != NULL); - - /* Find partition points */ - pixels = gimp_histogram_get_count (hist, GIMP_HISTOGRAM_VALUE, 0, 255); - - for (k = 0; k < n_channels; k++) - { - gdouble sum = 0; - - for (i = 0; i < 256; i++) - { - gdouble histi = gimp_histogram_get_channel (hist, k, i); - - sum += histi; - - hlut.part[k][i] = RINT (sum * 255. / pixels); - } - } - - gimp_lut_setup (lut, (GimpLutFunc) equalize_lut_func, &hlut, n_channels); -} - -GimpLut * -equalize_lut_new (GimpHistogram *histogram, - gint n_channels) -{ - GimpLut *lut; - - g_return_val_if_fail (histogram != NULL, NULL); - - lut = gimp_lut_new (); - - equalize_lut_setup (lut, histogram, n_channels); - - return lut; -} diff --git a/app/base/lut-funcs.h b/app/base/lut-funcs.h deleted file mode 100644 index 6e89bf47dc..0000000000 --- a/app/base/lut-funcs.h +++ /dev/null @@ -1,26 +0,0 @@ -/* GIMP - The GNU Image Manipulation Program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __LUT_FUNCS_H__ -#define __LUT_FUNCS_H__ - - -GimpLut * equalize_lut_new (GimpHistogram *histogram, - gint n_channels); - - -#endif /* __LUT_FUNCS_H__ */ diff --git a/app/core/gimpdrawable-equalize.c b/app/core/gimpdrawable-equalize.c index 5c473dead0..b2c05ea5f9 100644 --- a/app/core/gimpdrawable-equalize.c +++ b/app/core/gimpdrawable-equalize.c @@ -21,13 +21,10 @@ #include "core-types.h" -#include "base/gimplut.h" -#include "base/lut-funcs.h" - #include "gimpdrawable.h" #include "gimpdrawable-equalize.h" #include "gimpdrawable-histogram.h" -#include "gimpdrawable-process.h" +#include "gimpdrawable-operation.h" #include "gimphistogram.h" #include "gimp-intl.h" @@ -38,7 +35,7 @@ gimp_drawable_equalize (GimpDrawable *drawable, gboolean mask_only) { GimpHistogram *hist; - GimpLut *lut; + GeglNode *equalize; g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); @@ -46,9 +43,16 @@ gimp_drawable_equalize (GimpDrawable *drawable, hist = gimp_histogram_new (); gimp_drawable_calculate_histogram (drawable, hist); - lut = equalize_lut_new (hist, gimp_drawable_bytes (drawable)); - gimp_histogram_unref (hist); + equalize = gegl_node_new_child (NULL, + "operation", "gimp:equalize", + "histogram", hist, + NULL); - gimp_drawable_process_lut (drawable, NULL, C_("undo-type", "Equalize"), lut); - gimp_lut_free (lut); + gimp_drawable_apply_operation (drawable, NULL, + C_("undo-type", "Equalize"), + equalize, TRUE); + + g_object_unref (equalize); + + gimp_histogram_unref (hist); } diff --git a/app/gegl/Makefile.am b/app/gegl/Makefile.am index f26b8ca96b..afe483c9cf 100644 --- a/app/gegl/Makefile.am +++ b/app/gegl/Makefile.am @@ -67,6 +67,8 @@ libappgegl_a_sources = \ gimpoperationcurves.h \ gimpoperationdesaturate.c \ gimpoperationdesaturate.h \ + gimpoperationequalize.c \ + gimpoperationequalize.h \ gimpoperationhuesaturation.c \ gimpoperationhuesaturation.h \ gimpoperationlevels.c \ diff --git a/app/gegl/gimp-gegl-types.h b/app/gegl/gimp-gegl-types.h index a2e9100cf6..99eda62698 100644 --- a/app/gegl/gimp-gegl-types.h +++ b/app/gegl/gimp-gegl-types.h @@ -40,6 +40,7 @@ typedef struct _GimpOperationColorBalance GimpOperationColorBalance; typedef struct _GimpOperationColorize GimpOperationColorize; typedef struct _GimpOperationCurves GimpOperationCurves; typedef struct _GimpOperationDesaturate GimpOperationDesaturate; +typedef struct _GimpOperationEqualize GimpOperationEqualize; typedef struct _GimpOperationHueSaturation GimpOperationHueSaturation; typedef struct _GimpOperationLevels GimpOperationLevels; typedef struct _GimpOperationPosterize GimpOperationPosterize; diff --git a/app/gegl/gimp-gegl.c b/app/gegl/gimp-gegl.c index a938198153..61a6c94996 100644 --- a/app/gegl/gimp-gegl.c +++ b/app/gegl/gimp-gegl.c @@ -41,6 +41,7 @@ #include "gimpoperationcolorize.h" #include "gimpoperationcurves.h" #include "gimpoperationdesaturate.h" +#include "gimpoperationequalize.h" #include "gimpoperationhuesaturation.h" #include "gimpoperationlevels.h" #include "gimpoperationposterize.h" @@ -127,6 +128,7 @@ gimp_gegl_init (Gimp *gimp) g_type_class_ref (GIMP_TYPE_OPERATION_COLORIZE); g_type_class_ref (GIMP_TYPE_OPERATION_CURVES); g_type_class_ref (GIMP_TYPE_OPERATION_DESATURATE); + g_type_class_ref (GIMP_TYPE_OPERATION_EQUALIZE); g_type_class_ref (GIMP_TYPE_OPERATION_HUE_SATURATION); g_type_class_ref (GIMP_TYPE_OPERATION_LEVELS); g_type_class_ref (GIMP_TYPE_OPERATION_POSTERIZE); diff --git a/app/gegl/gimpoperationequalize.c b/app/gegl/gimpoperationequalize.c new file mode 100644 index 0000000000..fc78cadc35 --- /dev/null +++ b/app/gegl/gimpoperationequalize.c @@ -0,0 +1,223 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpoperationequalize.c + * Copyright (C) 2007 Michael Natterer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "libgimpcolor/gimpcolor.h" +#include "libgimpmath/gimpmath.h" + +#include "gimp-gegl-types.h" + +#include "core/gimphistogram.h" + +#include "gimpoperationequalize.h" + + +enum +{ + PROP_0, + PROP_HISTOGRAM +}; + + +static void gimp_operation_equalize_finalize (GObject *object); +static void gimp_operation_equalize_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void gimp_operation_equalize_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); + +static gboolean gimp_operation_equalize_process (GeglOperation *operation, + void *in_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi); + + +G_DEFINE_TYPE (GimpOperationEqualize, gimp_operation_equalize, + GIMP_TYPE_OPERATION_POINT_FILTER) + +#define parent_class gimp_operation_equalize_parent_class + + +static void +gimp_operation_equalize_class_init (GimpOperationEqualizeClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass); + GeglOperationPointFilterClass *point_class = GEGL_OPERATION_POINT_FILTER_CLASS (klass); + + object_class->finalize = gimp_operation_equalize_finalize; + object_class->set_property = gimp_operation_equalize_set_property; + object_class->get_property = gimp_operation_equalize_get_property; + + operation_class->name = "gimp:equalize"; + operation_class->categories = "color"; + operation_class->description = "GIMP Equalize operation"; + + point_class->process = gimp_operation_equalize_process; + + g_object_class_install_property (object_class, PROP_HISTOGRAM, + g_param_spec_pointer ("histogram", + "Histogram", + "The histogram", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gimp_operation_equalize_init (GimpOperationEqualize *self) +{ +} + +static void +gimp_operation_equalize_finalize (GObject *object) +{ + GimpOperationEqualize *self = GIMP_OPERATION_EQUALIZE (object); + + if (self->histogram) + { + gimp_histogram_unref (self->histogram); + self->histogram = NULL; + } +} + +static void +gimp_operation_equalize_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpOperationEqualize *self = GIMP_OPERATION_EQUALIZE (object); + + switch (property_id) + { + case PROP_HISTOGRAM: + g_value_set_pointer (value, self->histogram); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_operation_equalize_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpOperationEqualize *self = GIMP_OPERATION_EQUALIZE (object); + + switch (property_id) + { + case PROP_HISTOGRAM: + if (self->histogram) + gimp_histogram_unref (self->histogram); + self->histogram = g_value_get_pointer (value); + if (self->histogram) + { + gdouble pixels; + gint max; + gint k; + + gimp_histogram_ref (self->histogram); + + pixels = gimp_histogram_get_count (self->histogram, + GIMP_HISTOGRAM_VALUE, 0, 255); + + if (gimp_histogram_n_channels (self->histogram) == 1 || + gimp_histogram_n_channels (self->histogram) == 2) + max = 1; + else + max = 3; + + for (k = 0; k < 3; k++) + { + gdouble sum = 0; + gint i; + + for (i = 0; i < 256; i++) + { + gdouble histi; + + histi = gimp_histogram_get_channel (self->histogram, k, i); + + sum += histi; + + self->part[k][i] = sum / pixels; + + if (max == 1) + { + self->part[1][i] = self->part[0][i]; + self->part[2][i] = self->part[0][i]; + } + } + } + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static inline float +gimp_operation_equalize_map (GimpOperationEqualize *self, + gint component, + gfloat value) +{ + gint index = (gint) CLAMP (value * 255.0, 0, 255); + + return self->part[component][index]; +} + +static gboolean +gimp_operation_equalize_process (GeglOperation *operation, + void *in_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi) +{ + GimpOperationEqualize *self = GIMP_OPERATION_EQUALIZE (operation); + gfloat *src = in_buf; + gfloat *dest = out_buf; + + while (samples--) + { + dest[RED] = gimp_operation_equalize_map (self, RED, src[RED]); + dest[GREEN] = gimp_operation_equalize_map (self, GREEN, src[GREEN]); + dest[BLUE] = gimp_operation_equalize_map (self, BLUE, src[BLUE]); + dest[ALPHA] = src[ALPHA]; + + src += 4; + dest += 4; + } + + return TRUE; +} diff --git a/app/gegl/gimpoperationequalize.h b/app/gegl/gimpoperationequalize.h new file mode 100644 index 0000000000..38d120b097 --- /dev/null +++ b/app/gegl/gimpoperationequalize.h @@ -0,0 +1,55 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpoperationequalize.h + * Copyright (C) 2012 Michael Natterer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_OPERATION_EQUALIZE_H__ +#define __GIMP_OPERATION_EQUALIZE_H__ + + +#include "gimpoperationpointfilter.h" + + +#define GIMP_TYPE_OPERATION_EQUALIZE (gimp_operation_equalize_get_type ()) +#define GIMP_OPERATION_EQUALIZE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPERATION_EQUALIZE, GimpOperationEqualize)) +#define GIMP_OPERATION_EQUALIZE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_OPERATION_EQUALIZE, GimpOperationEqualizeClass)) +#define GIMP_IS_OPERATION_EQUALIZE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_OPERATION_EQUALIZE)) +#define GIMP_IS_OPERATION_EQUALIZE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_OPERATION_EQUALIZE)) +#define GIMP_OPERATION_EQUALIZE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_OPERATION_EQUALIZE, GimpOperationEqualizeClass)) + + +typedef struct _GimpOperationEqualizeClass GimpOperationEqualizeClass; + +struct _GimpOperationEqualize +{ + GimpOperationPointFilter parent_instance; + + GimpHistogram *histogram; + gfloat part[5][256]; +}; + +struct _GimpOperationEqualizeClass +{ + GimpOperationPointFilterClass parent_class; +}; + + +GType gimp_operation_equalize_get_type (void) G_GNUC_CONST; + + +#endif /* __GIMP_OPERATION_EQUALIZE_H__ */