[gimp/goat-invasion: 239/526] app: add our own GimpOperationNormalMode so we can opt out of premultiply



commit da0689874be60e51d379f0c9e8aef23fce083ad8
Author: Michael Natterer <mitch gimp org>
Date:   Sat Mar 24 16:22:02 2012 +0100

    app: add our own GimpOperationNormalMode so we can opt out of premultiply

 app/gegl/Makefile.am                   |    2 +
 app/gegl/gimp-gegl-types.h             |    1 +
 app/gegl/gimp-gegl.c                   |    2 +
 app/gegl/gimpoperationnormalmode.c     |  158 ++++++++++++++++++++++++++++++++
 app/gegl/gimpoperationnormalmode.h     |   53 +++++++++++
 app/gegl/gimpoperationpointlayermode.c |    5 +-
 6 files changed, 219 insertions(+), 2 deletions(-)
---
diff --git a/app/gegl/Makefile.am b/app/gegl/Makefile.am
index 1340cc6..f26b8ca 100644
--- a/app/gegl/Makefile.am
+++ b/app/gegl/Makefile.am
@@ -78,6 +78,8 @@ libappgegl_a_sources = \
 	\
 	gimpoperationpointlayermode.c		\
 	gimpoperationpointlayermode.h		\
+	gimpoperationnormalmode.c		\
+	gimpoperationnormalmode.h		\
 	gimpoperationdissolvemode.c     	\
 	gimpoperationdissolvemode.h     	\
 	gimpoperationbehindmode.c       	\
diff --git a/app/gegl/gimp-gegl-types.h b/app/gegl/gimp-gegl-types.h
index 5eddece..a2e9100 100644
--- a/app/gegl/gimp-gegl-types.h
+++ b/app/gegl/gimp-gegl-types.h
@@ -46,6 +46,7 @@ typedef struct _GimpOperationPosterize          GimpOperationPosterize;
 typedef struct _GimpOperationThreshold          GimpOperationThreshold;
 
 typedef struct _GimpOperationPointLayerMode     GimpOperationPointLayerMode;
+typedef struct _GimpOperationNormalMode         GimpOperationNormalMode;
 typedef struct _GimpOperationDissolveMode       GimpOperationDissolveMode;
 typedef struct _GimpOperationBehindMode         GimpOperationBehindMode;
 typedef struct _GimpOperationMultiplyMode       GimpOperationMultiplyMode;
diff --git a/app/gegl/gimp-gegl.c b/app/gegl/gimp-gegl.c
index f714888..a938198 100644
--- a/app/gegl/gimp-gegl.c
+++ b/app/gegl/gimp-gegl.c
@@ -47,6 +47,7 @@
 #include "gimpoperationthreshold.h"
 
 #include "gimpoperationpointlayermode.h"
+#include "gimpoperationnormalmode.h"
 #include "gimpoperationdissolvemode.h"
 #include "gimpoperationbehindmode.h"
 #include "gimpoperationmultiplymode.h"
@@ -132,6 +133,7 @@ gimp_gegl_init (Gimp *gimp)
   g_type_class_ref (GIMP_TYPE_OPERATION_THRESHOLD);
 
   g_type_class_ref (GIMP_TYPE_OPERATION_POINT_LAYER_MODE);
+  g_type_class_ref (GIMP_TYPE_OPERATION_NORMAL_MODE);
   g_type_class_ref (GIMP_TYPE_OPERATION_DISSOLVE_MODE);
   g_type_class_ref (GIMP_TYPE_OPERATION_BEHIND_MODE);
   g_type_class_ref (GIMP_TYPE_OPERATION_MULTIPLY_MODE);
diff --git a/app/gegl/gimpoperationnormalmode.c b/app/gegl/gimpoperationnormalmode.c
new file mode 100644
index 0000000..2dd5bae
--- /dev/null
+++ b/app/gegl/gimpoperationnormalmode.c
@@ -0,0 +1,158 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationnormalmode.c
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gegl-plugin.h>
+
+#include "gimp-gegl-types.h"
+
+#include "gimpoperationnormalmode.h"
+
+
+static gboolean gimp_operation_normal_parent_process (GeglOperation        *operation,
+                                                      GeglOperationContext *context,
+                                                      const gchar          *output_prop,
+                                                      const GeglRectangle  *result);
+static gboolean gimp_operation_normal_mode_process   (GeglOperation        *operation,
+                                                      void                 *in_buf,
+                                                      void                 *aux_buf,
+                                                      void                 *out_buf,
+                                                      glong                 samples,
+                                                      const GeglRectangle *roi);
+
+
+G_DEFINE_TYPE (GimpOperationNormalMode, gimp_operation_normal_mode,
+               GIMP_TYPE_OPERATION_POINT_LAYER_MODE)
+
+#define parent_class gimp_operation_normal_mode_parent_class
+
+
+static void
+gimp_operation_normal_mode_class_init (GimpOperationNormalModeClass *klass)
+{
+  GeglOperationClass              *operation_class;
+  GeglOperationPointComposerClass *point_class;
+
+  operation_class = GEGL_OPERATION_CLASS (klass);
+  point_class     = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+
+  operation_class->name        = "gimp:normal-mode";
+  operation_class->description = "GIMP normal mode operation";
+  operation_class->process     = gimp_operation_normal_parent_process;
+
+  point_class->process         = gimp_operation_normal_mode_process;
+}
+
+static void
+gimp_operation_normal_mode_init (GimpOperationNormalMode *self)
+{
+}
+
+static gboolean
+gimp_operation_normal_parent_process (GeglOperation        *operation,
+                                      GeglOperationContext *context,
+                                      const gchar          *output_prop,
+                                      const GeglRectangle  *result)
+{
+  const GeglRectangle *in_extent  = NULL;
+  const GeglRectangle *aux_extent = NULL;
+  GObject             *input;
+  GObject             *aux;
+
+  /* get the raw values this does not increase the reference count */
+  input = gegl_operation_context_get_object (context, "input");
+  aux   = gegl_operation_context_get_object (context, "aux");
+
+  /* pass the input/aux buffers directly through if they are not
+   * overlapping
+   */
+  if (input)
+    in_extent = gegl_buffer_get_abyss (GEGL_BUFFER (input));
+
+  if (! input ||
+      (aux && ! gegl_rectangle_intersect (NULL, in_extent, result)))
+    {
+      gegl_operation_context_set_object (context, "output", aux);
+      return TRUE;
+    }
+
+  if (aux)
+    aux_extent = gegl_buffer_get_abyss (GEGL_BUFFER (aux));
+
+  if (! aux ||
+      (input && ! gegl_rectangle_intersect (NULL, aux_extent, result)))
+    {
+      gegl_operation_context_set_object (context, "output", input);
+      return TRUE;
+    }
+
+  /* chain up, which will create the needed buffers for our actual
+   * process function
+   */
+  return GEGL_OPERATION_CLASS (parent_class)->process (operation, context,
+                                                       output_prop, result);
+}
+
+static gboolean
+gimp_operation_normal_mode_process (GeglOperation       *operation,
+                                    void                *in_buf,
+                                    void                *aux_buf,
+                                    void                *out_buf,
+                                    glong                samples,
+                                    const GeglRectangle *roi)
+{
+  GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+  gfloat                      *in    = in_buf;
+  gfloat                      *aux   = aux_buf;
+  gfloat                      *out   = out_buf;
+
+  if (point->premultiplied)
+    {
+      while (samples--)
+        {
+          out[0] = aux[0] + in[0] * (1.0f - aux[3]);
+          out[1] = aux[1] + in[1] * (1.0f - aux[3]);
+          out[2] = aux[2] + in[2] * (1.0f - aux[3]);
+          out[3] = aux[3] + in[3] - aux[3] * in[3];
+
+          in  += 4;
+          aux += 4;
+          out += 4;
+        }
+    }
+  else
+    {
+      while (samples--)
+        {
+          out[RED]   = in[RED]   * (1.0 - aux[ALPHA]) + aux[RED]   * aux[ALPHA];
+          out[GREEN] = in[GREEN] * (1.0 - aux[ALPHA]) + aux[GREEN] * aux[ALPHA];
+          out[BLUE]  = in[BLUE]  * (1.0 - aux[ALPHA]) + aux[BLUE]  * aux[ALPHA];
+          out[ALPHA] = in[ALPHA] + aux[ALPHA] * (1.0 - in[ALPHA]);
+
+          in  += 4;
+          aux += 4;
+          out += 4;
+        }
+    }
+
+  return TRUE;
+}
diff --git a/app/gegl/gimpoperationnormalmode.h b/app/gegl/gimpoperationnormalmode.h
new file mode 100644
index 0000000..b5eadda
--- /dev/null
+++ b/app/gegl/gimpoperationnormalmode.h
@@ -0,0 +1,53 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationnormalmode.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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GIMP_OPERATION_NORMAL_MODE_H__
+#define __GIMP_OPERATION_NORMAL_MODE_H__
+
+
+#include "gimpoperationpointlayermode.h"
+
+
+#define GIMP_TYPE_OPERATION_NORMAL_MODE            (gimp_operation_normal_mode_get_type ())
+#define GIMP_OPERATION_NORMAL_MODE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPERATION_NORMAL_MODE, GimpOperationNormalMode))
+#define GIMP_OPERATION_NORMAL_MODE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GIMP_TYPE_OPERATION_NORMAL_MODE, GimpOperationNormalModeClass))
+#define GIMP_IS_OPERATION_NORMAL_MODE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_OPERATION_NORMAL_MODE))
+#define GIMP_IS_OPERATION_NORMAL_MODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GIMP_TYPE_OPERATION_NORMAL_MODE))
+#define GIMP_OPERATION_NORMAL_MODE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GIMP_TYPE_OPERATION_NORMAL_MODE, GimpOperationNormalModeClass))
+
+
+typedef struct _GimpOperationNormalModeClass GimpOperationNormalModeClass;
+
+struct _GimpOperationNormalMode
+{
+  GimpOperationPointLayerMode  parent_instance;
+};
+
+struct _GimpOperationNormalModeClass
+{
+  GimpOperationPointLayerModeClass  parent_class;
+};
+
+
+GType   gimp_operation_normal_mode_get_type (void) G_GNUC_CONST;
+
+
+#endif /* __GIMP_OPERATION_NORMAL_MODE_H__ */
diff --git a/app/gegl/gimpoperationpointlayermode.c b/app/gegl/gimpoperationpointlayermode.c
index 780a28a..0d26d8b 100644
--- a/app/gegl/gimpoperationpointlayermode.c
+++ b/app/gegl/gimpoperationpointlayermode.c
@@ -127,7 +127,8 @@ gimp_operation_point_layer_mode_class_init (GimpOperationPointLayerModeClass *kl
                                    g_param_spec_enum ("blend-mode", NULL, NULL,
                                                       GIMP_TYPE_LAYER_MODE_EFFECTS,
                                                       GIMP_NORMAL_MODE,
-                                                      GIMP_PARAM_READWRITE));
+                                                      GIMP_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (object_class, PROP_PREMULTIPLIED,
                                    g_param_spec_boolean ("premultiplied",
@@ -162,7 +163,7 @@ gimp_operation_point_layer_mode_set_property (GObject      *object,
       break;
 
     case PROP_PREMULTIPLIED:
-      self->premultiplied = g_value_get_enum (value);
+      self->premultiplied = g_value_get_boolean (value);
       break;
 
     default:



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