[gimp] app: new gegl replace mode that uses mask and opacity inputs



commit 753bc238346b67df31cf1ea5e392de2f5a053943
Author: Ville Sokk <ville sokk gmail com>
Date:   Tue Apr 24 18:36:31 2012 +0300

    app: new gegl replace mode that uses mask and opacity inputs

 app/gegl/gimpoperationreplacemode.c |  136 ++++++++++++++++++++++++++++++-----
 app/gegl/gimpoperationreplacemode.h |   10 ++--
 2 files changed, 123 insertions(+), 23 deletions(-)
---
diff --git a/app/gegl/gimpoperationreplacemode.c b/app/gegl/gimpoperationreplacemode.c
index 2143772..8bf6408 100644
--- a/app/gegl/gimpoperationreplacemode.c
+++ b/app/gegl/gimpoperationreplacemode.c
@@ -28,34 +28,71 @@
 #include "gimpoperationreplacemode.h"
 
 
-static gboolean gimp_operation_replace_mode_process (GeglOperation       *operation,
-                                                     void                *in_buf,
-                                                     void                *aux_buf,
-                                                     void                *out_buf,
-                                                     glong                samples,
-                                                     const GeglRectangle *roi,
-                                                     gint                 level);
+enum
+{
+  PROP_0,
+  PROP_PREMULTIPLIED,
+  PROP_OPACITY
+};
+
+static void     gimp_operation_replace_mode_set_property (GObject             *object,
+                                                          guint                property_id,
+                                                          const GValue        *value,
+                                                          GParamSpec          *pspec);
+static void     gimp_operation_replace_mode_get_property (GObject             *object,
+                                                          guint                property_id,
+                                                          GValue              *value,
+                                                          GParamSpec          *pspec);
+static void     gimp_operation_replace_mode_prepare      (GeglOperation       *operation);
+static gboolean gimp_operation_replace_mode_process      (GeglOperation       *operation,
+                                                          void                *in_buf,
+                                                          void                *aux_buf,
+                                                          void                *aux2_buf,
+                                                          void                *out_buf,
+                                                          glong                samples,
+                                                          const GeglRectangle *roi,
+                                                          gint                 level);
 
 
 G_DEFINE_TYPE (GimpOperationReplaceMode, gimp_operation_replace_mode,
-               GIMP_TYPE_OPERATION_POINT_LAYER_MODE)
+               GEGL_TYPE_OPERATION_POINT_COMPOSER3)
 
 
 static void
 gimp_operation_replace_mode_class_init (GimpOperationReplaceModeClass *klass)
 {
-  GeglOperationClass              *operation_class;
-  GeglOperationPointComposerClass *point_class;
+  GObjectClass                     *object_class;
+  GeglOperationClass               *operation_class;
+  GeglOperationPointComposer3Class *point_class;
 
+  object_class    = G_OBJECT_CLASS (klass);
   operation_class = GEGL_OPERATION_CLASS (klass);
-  point_class     = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+  point_class     = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+
+  object_class->set_property = gimp_operation_replace_mode_set_property;
+  object_class->get_property = gimp_operation_replace_mode_get_property;
 
   gegl_operation_class_set_keys (operation_class,
                                  "name",        "gimp:replace-mode",
                                  "description", "GIMP replace mode operation",
                                  NULL);
 
-  point_class->process         = gimp_operation_replace_mode_process;
+  operation_class->prepare = gimp_operation_replace_mode_prepare;
+  point_class->process     = gimp_operation_replace_mode_process;
+
+  g_object_class_install_property (object_class, PROP_PREMULTIPLIED,
+                                   g_param_spec_boolean ("premultiplied",
+                                                         NULL, NULL,
+                                                         TRUE,
+                                                         GIMP_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT));
+  g_object_class_install_property (object_class, PROP_OPACITY,
+                                   g_param_spec_float ("opacity",
+                                                       NULL, NULL,
+                                                       0.0, 1.0,
+                                                       1.0,
+                                                       GIMP_PARAM_READWRITE |
+                                                       G_PARAM_CONSTRUCT));
 }
 
 static void
@@ -63,23 +100,85 @@ gimp_operation_replace_mode_init (GimpOperationReplaceMode *self)
 {
 }
 
+static void
+gimp_operation_replace_mode_set_property (GObject      *object,
+                                          guint         property_id,
+                                          const GValue *value,
+                                          GParamSpec   *pspec)
+{
+  GimpOperationReplaceMode *self = GIMP_OPERATION_REPLACE_MODE (object);
+
+  switch (property_id)
+    {
+    case PROP_PREMULTIPLIED:
+      self->premultiplied = g_value_get_boolean (value);
+      break;
+    case PROP_OPACITY:
+      self->opacity = g_value_get_float (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_operation_replace_mode_get_property (GObject      *object,
+                                          guint         property_id,
+                                          GValue       *value,
+                                          GParamSpec   *pspec)
+{
+  GimpOperationReplaceMode *self = GIMP_OPERATION_REPLACE_MODE (object);
+
+  switch (property_id)
+    {
+    case PROP_PREMULTIPLIED:
+      g_value_set_boolean (value, self->premultiplied);
+      break;
+    case PROP_OPACITY:
+      g_value_set_float (value, self->opacity);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_operation_replace_mode_prepare (GeglOperation *operation)
+{
+  const Babl *format = babl_format ("RGBA float");
+
+  gegl_operation_set_format (operation, "input",  format);
+  gegl_operation_set_format (operation, "aux",    format);
+  gegl_operation_set_format (operation, "aux2",   babl_format ("Y float"));
+  gegl_operation_set_format (operation, "output", format);
+}
+
 static gboolean
 gimp_operation_replace_mode_process (GeglOperation       *operation,
                                      void                *in_buf,
                                      void                *aux_buf,
+                                     void                *aux2_buf,
                                      void                *out_buf,
                                      glong                samples,
                                      const GeglRectangle *roi,
                                      gint                 level)
 {
-  gfloat *in    = in_buf;
-  gfloat *layer = aux_buf;
-  gfloat *out   = out_buf;
+  GimpOperationReplaceMode *self = GIMP_OPERATION_REPLACE_MODE (operation);
+  gfloat opacity                 = self->opacity;
+  gfloat *in                     = in_buf;
+  gfloat *layer                  = aux_buf;
+  gfloat *mask                   = aux2_buf;
+  gfloat *out                    = out_buf;
+
 
   while (samples--)
     {
       gint b;
-      gfloat ratio = 1 / layer[ALPHA] / layer[ALPHA];
+      gfloat new_alpha = (layer[ALPHA] - in[ALPHA]) * (*mask) * opacity + in[ALPHA];
+      gfloat ratio = *mask * opacity;
+      ratio = ratio / layer[ALPHA] / new_alpha;
 
       for (b = RED; b < ALPHA; b++)
         {
@@ -92,15 +191,16 @@ gimp_operation_replace_mode_process (GeglOperation       *operation,
             }
           else
             {
-              t= (in[b] - layer[b]) * ratio;
+              t = (in[b] - layer[b]) * ratio;
               out[b] = in[b] - t;
             }
         }
 
-      out[ALPHA] = layer[ALPHA];
+      out[ALPHA] = new_alpha;
 
       in    += 4;
       layer += 4;
+      mask  += 1;
       out   += 4;
     }
 
diff --git a/app/gegl/gimpoperationreplacemode.h b/app/gegl/gimpoperationreplacemode.h
index 866bb97..76fde6f 100644
--- a/app/gegl/gimpoperationreplacemode.h
+++ b/app/gegl/gimpoperationreplacemode.h
@@ -23,9 +23,6 @@
 #define __GIMP_OPERATION_REPLACE_MODE_H__
 
 
-#include "gimpoperationpointlayermode.h"
-
-
 #define GIMP_TYPE_OPERATION_REPLACE_MODE            (gimp_operation_replace_mode_get_type ())
 #define GIMP_OPERATION_REPLACE_MODE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPERATION_REPLACE_MODE, GimpOperationReplaceMode))
 #define GIMP_OPERATION_REPLACE_MODE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GIMP_TYPE_OPERATION_REPLACE_MODE, GimpOperationReplaceModeClass))
@@ -38,12 +35,15 @@ typedef struct _GimpOperationReplaceModeClass GimpOperationReplaceModeClass;
 
 struct _GimpOperationReplaceMode
 {
-  GimpOperationPointLayerMode  parent_instance;
+  GeglOperationPointComposer3 parent_instance;
+
+  gfloat   opacity;
+  gboolean premultiplied;
 };
 
 struct _GimpOperationReplaceModeClass
 {
-  GimpOperationPointLayerModeClass  parent_class;
+  GeglOperationPointComposer3Class parent_class;
 };
 
 



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