[gimp/goat-invasion] app: add GimpOperationEqualize and port equalize to it



commit de4e4dca8231fb9b05f5185ab2a13b3aca6d1e86
Author: Michael Natterer <mitch gimp org>
Date:   Sun Mar 25 00:12:15 2012 +0100

    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(-)
---
diff --git a/app/base/Makefile.am b/app/base/Makefile.am
index ace8146..59d31f6 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/core/gimpdrawable-equalize.c b/app/core/gimpdrawable-equalize.c
index 5c473de..b2c05ea 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_apply_operation (drawable, NULL,
+                                 C_("undo-type", "Equalize"),
+                                 equalize, TRUE);
 
-  gimp_drawable_process_lut (drawable, NULL, C_("undo-type", "Equalize"), lut);
-  gimp_lut_free (lut);
+  g_object_unref (equalize);
+
+  gimp_histogram_unref (hist);
 }
diff --git a/app/gegl/Makefile.am b/app/gegl/Makefile.am
index f26b8ca..afe483c 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 a2e9100..99eda62 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 a938198..61a6c94 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 0000000..fc78cad
--- /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 <mitch gimp org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <cairo.h>
+#include <gegl.h>
+
+#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 0000000..38d120b
--- /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 <mitch gimp org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]