[gimp/goat-invasion: 520/526] app: added hard light, difference, subtract, grain extract, grain merge and difference gegl blending



commit 2c3fb41c9d6752f33633fa1a9d9e846b6be1cce7
Author: Ville Sokk <ville sokk gmail com>
Date:   Sat Apr 21 22:05:49 2012 +0300

    app: added hard light, difference, subtract, grain extract, grain merge and difference gegl blending modes

 app/gegl/gimp-gegl-nodes.c               |    6 ----
 app/gegl/gimpoperationadditionmode.c     |    3 +-
 app/gegl/gimpoperationburnmode.c         |    2 +-
 app/gegl/gimpoperationdifferencemode.c   |   31 +++++++++++++++++++---
 app/gegl/gimpoperationdividemode.c       |   32 ++++++++++++++++++++---
 app/gegl/gimpoperationdodgemode.c        |    3 +-
 app/gegl/gimpoperationgrainextractmode.c |   32 ++++++++++++++++++++---
 app/gegl/gimpoperationgrainmergemode.c   |   32 ++++++++++++++++++++---
 app/gegl/gimpoperationhardlightmode.c    |   41 +++++++++++++++++++++++++++---
 app/gegl/gimpoperationmultiplymode.c     |    3 +-
 app/gegl/gimpoperationsubtractmode.c     |   31 +++++++++++++++++++---
 11 files changed, 182 insertions(+), 34 deletions(-)
---
diff --git a/app/gegl/gimp-gegl-nodes.c b/app/gegl/gimp-gegl-nodes.c
index 45506eb..dde78ce 100644
--- a/app/gegl/gimp-gegl-nodes.c
+++ b/app/gegl/gimp-gegl-nodes.c
@@ -250,16 +250,10 @@ gimp_gegl_node_set_layer_mode (GeglNode             *node,
   switch (mode)
     {
     case GIMP_BEHIND_MODE:
-    case GIMP_DIFFERENCE_MODE:
-    case GIMP_SUBTRACT_MODE:
     case GIMP_HUE_MODE:
     case GIMP_SATURATION_MODE:
     case GIMP_COLOR_MODE:
     case GIMP_VALUE_MODE:
-    case GIMP_DIVIDE_MODE:
-    case GIMP_HARDLIGHT_MODE:
-    case GIMP_GRAIN_EXTRACT_MODE:
-    case GIMP_GRAIN_MERGE_MODE:
     case GIMP_COLOR_ERASE_MODE:
     case GIMP_ERASE_MODE:
     case GIMP_REPLACE_MODE:
diff --git a/app/gegl/gimpoperationadditionmode.c b/app/gegl/gimpoperationadditionmode.c
index a483b10..71b819c 100644
--- a/app/gegl/gimpoperationadditionmode.c
+++ b/app/gegl/gimpoperationadditionmode.c
@@ -98,7 +98,8 @@ gimp_operation_addition_mode_process (GeglOperation       *operation,
 
       for (b = RED; b < ALPHA; b++)
         {
-          gfloat comp = CLAMP (in[b] + layer[b], 0.0, 1.0);
+          gfloat comp = in[b] + layer[b];
+          comp = CLAMP (comp, 0, 1);
 
           out[b] = comp * ratio + in[b] * (1 - ratio);
         }
diff --git a/app/gegl/gimpoperationburnmode.c b/app/gegl/gimpoperationburnmode.c
index 5bf4ed3..180e225 100644
--- a/app/gegl/gimpoperationburnmode.c
+++ b/app/gegl/gimpoperationburnmode.c
@@ -99,7 +99,7 @@ gimp_operation_burn_mode_process (GeglOperation       *operation,
       for (b = RED; b < ALPHA; b++)
         {
           gfloat comp = (1 - in[b]) / layer[b];
-          comp = CLAMP (1 - comp, 0.0, 1.0);
+          comp = CLAMP (1 - comp, 0, 1);
 
           out[b] = comp * ratio + in[b] * (1 - ratio);
         }
diff --git a/app/gegl/gimpoperationdifferencemode.c b/app/gegl/gimpoperationdifferencemode.c
index 35bea77..5bd81e6 100644
--- a/app/gegl/gimpoperationdifferencemode.c
+++ b/app/gegl/gimpoperationdifferencemode.c
@@ -3,6 +3,7 @@
  *
  * gimpoperationdifferencemode.c
  * Copyright (C) 2008 Michael Natterer <mitch gimp org>
+ *               2012 Ville Sokk <ville sokk gmail com>
  *
  * 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
@@ -28,6 +29,7 @@
 #include "gimpoperationdifferencemode.h"
 
 
+static void     gimp_operation_difference_mode_prepare (GeglOperation       *operation);
 static gboolean gimp_operation_difference_mode_process (GeglOperation       *operation,
                                                         void                *in_buf,
                                                         void                *aux_buf,
@@ -55,7 +57,8 @@ gimp_operation_difference_mode_class_init (GimpOperationDifferenceModeClass *kla
                                  "description", "GIMP difference mode operation",
                                  NULL);
 
-  point_class->process         = gimp_operation_difference_mode_process;
+  operation_class->prepare = gimp_operation_difference_mode_prepare;
+  point_class->process     = gimp_operation_difference_mode_process;
 }
 
 static void
@@ -63,6 +66,16 @@ gimp_operation_difference_mode_init (GimpOperationDifferenceMode *self)
 {
 }
 
+static void
+gimp_operation_difference_mode_prepare (GeglOperation *operation)
+{
+  const Babl *format = babl_format ("R'G'B'A float");
+
+  gegl_operation_set_format (operation, "input",  format);
+  gegl_operation_set_format (operation, "aux",    format);
+  gegl_operation_set_format (operation, "output", format);
+}
+
 static gboolean
 gimp_operation_difference_mode_process (GeglOperation       *operation,
                                         void                *in_buf,
@@ -78,9 +91,19 @@ gimp_operation_difference_mode_process (GeglOperation       *operation,
 
   while (samples--)
     {
-      out[RED]   = in[RED];
-      out[GREEN] = in[GREEN];
-      out[BLUE]  = in[BLUE];
+      gint b;
+      gfloat comp_alpha = in[ALPHA] * layer[ALPHA];
+      gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat ratio      = comp_alpha / new_alpha;
+
+      for (b = RED; b < ALPHA; b++)
+        {
+          gfloat comp = in[b] - layer[b];
+          comp = (comp < 0) ? -comp : comp;
+
+          out[b] = comp * ratio + in[b] * (1 - ratio);
+        }
+
       out[ALPHA] = in[ALPHA];
 
       in    += 4;
diff --git a/app/gegl/gimpoperationdividemode.c b/app/gegl/gimpoperationdividemode.c
index 2ad9c0d..e94b3cc 100644
--- a/app/gegl/gimpoperationdividemode.c
+++ b/app/gegl/gimpoperationdividemode.c
@@ -3,6 +3,7 @@
  *
  * gimpoperationdividemode.c
  * Copyright (C) 2008 Michael Natterer <mitch gimp org>
+ *               2012 Ville Sokk <ville sokk gmail com>
  *
  * 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
@@ -28,6 +29,7 @@
 #include "gimpoperationdividemode.h"
 
 
+static void     gimp_operation_divide_mode_prepare (GeglOperation       *operation);
 static gboolean gimp_operation_divide_mode_process (GeglOperation       *operation,
                                                     void                *in_buf,
                                                     void                *aux_buf,
@@ -55,7 +57,8 @@ gimp_operation_divide_mode_class_init (GimpOperationDivideModeClass *klass)
                                  "description", "GIMP divide mode operation",
                                  NULL);
 
-  point_class->process         = gimp_operation_divide_mode_process;
+  operation_class->prepare = gimp_operation_divide_mode_prepare;
+  point_class->process     = gimp_operation_divide_mode_process;
 }
 
 static void
@@ -63,6 +66,17 @@ gimp_operation_divide_mode_init (GimpOperationDivideMode *self)
 {
 }
 
+static void
+gimp_operation_divide_mode_prepare (GeglOperation *operation)
+{
+  const Babl *format = babl_format ("R'G'B'A float");
+
+  gegl_operation_set_format (operation, "input",  format);
+  gegl_operation_set_format (operation, "aux",    format);
+  gegl_operation_set_format (operation, "output", format);
+}
+
+
 static gboolean
 gimp_operation_divide_mode_process (GeglOperation       *operation,
                                     void                *in_buf,
@@ -78,9 +92,19 @@ gimp_operation_divide_mode_process (GeglOperation       *operation,
 
   while (samples--)
     {
-      out[RED]   = in[RED];
-      out[GREEN] = in[GREEN];
-      out[BLUE]  = in[BLUE];
+      gint b;
+      gfloat comp_alpha = in[ALPHA] * layer[ALPHA];
+      gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat ratio      = comp_alpha / new_alpha;
+
+      for (b = RED; b < ALPHA; b++)
+        {
+          gfloat comp = in[b] / layer[b];
+          comp = MIN (comp, 1);
+
+          out[b] = comp * ratio + in[b] * (1 - ratio);
+        }
+
       out[ALPHA] = in[ALPHA];
 
       in    += 4;
diff --git a/app/gegl/gimpoperationdodgemode.c b/app/gegl/gimpoperationdodgemode.c
index e53e6ec..a33e495 100644
--- a/app/gegl/gimpoperationdodgemode.c
+++ b/app/gegl/gimpoperationdodgemode.c
@@ -98,7 +98,8 @@ gimp_operation_dodge_mode_process (GeglOperation       *operation,
 
       for (b = RED; b < ALPHA; b++)
         {
-          gfloat comp = MIN (in[b] / (1 - layer[b]), 1);
+          gfloat comp = in[b] / (1 - layer[b]);
+          comp = MIN (comp, 1);
 
           out[b] = comp * ratio + in[b] * (1 - ratio);
         }
diff --git a/app/gegl/gimpoperationgrainextractmode.c b/app/gegl/gimpoperationgrainextractmode.c
index b76cd7b..2a7886f 100644
--- a/app/gegl/gimpoperationgrainextractmode.c
+++ b/app/gegl/gimpoperationgrainextractmode.c
@@ -3,6 +3,7 @@
  *
  * gimpoperationgrainextractmode.c
  * Copyright (C) 2008 Michael Natterer <mitch gimp org>
+ *               2012 Ville Sokk <ville sokk gmail com>
  *
  * 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
@@ -28,6 +29,7 @@
 #include "gimpoperationgrainextractmode.h"
 
 
+static void     gimp_operation_grain_extract_mode_prepare (GeglOperation       *operation);
 static gboolean gimp_operation_grain_extract_mode_process (GeglOperation       *operation,
                                                            void                *in_buf,
                                                            void                *aux_buf,
@@ -55,7 +57,8 @@ gimp_operation_grain_extract_mode_class_init (GimpOperationGrainExtractModeClass
                                  "description", "GIMP grain extract mode operation",
                                  NULL);
 
-  point_class->process         = gimp_operation_grain_extract_mode_process;
+  operation_class->prepare = gimp_operation_grain_extract_mode_prepare;
+  point_class->process     = gimp_operation_grain_extract_mode_process;
 }
 
 static void
@@ -63,6 +66,17 @@ gimp_operation_grain_extract_mode_init (GimpOperationGrainExtractMode *self)
 {
 }
 
+static void
+gimp_operation_grain_extract_mode_prepare (GeglOperation *operation)
+{
+  const Babl *format = babl_format ("R'G'B'A float");
+
+  gegl_operation_set_format (operation, "input",  format);
+  gegl_operation_set_format (operation, "aux",    format);
+  gegl_operation_set_format (operation, "output", format);
+}
+
+
 static gboolean
 gimp_operation_grain_extract_mode_process (GeglOperation       *operation,
                                            void                *in_buf,
@@ -78,9 +92,19 @@ gimp_operation_grain_extract_mode_process (GeglOperation       *operation,
 
   while (samples--)
     {
-      out[RED]   = in[RED];
-      out[GREEN] = in[GREEN];
-      out[BLUE]  = in[BLUE];
+      gint b;
+      gfloat comp_alpha = in[ALPHA] * layer[ALPHA];
+      gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat ratio      = comp_alpha / new_alpha;
+
+      for (b = RED; b < ALPHA; b++)
+        {
+          gfloat comp = in[b] - layer[b] + 0.5;
+          comp = CLAMP (comp, 0, 1);
+
+          out[b] = comp * ratio + in[b] * (1 - ratio);
+        }
+
       out[ALPHA] = in[ALPHA];
 
       in    += 4;
diff --git a/app/gegl/gimpoperationgrainmergemode.c b/app/gegl/gimpoperationgrainmergemode.c
index d1cea9d..f1a32d8 100644
--- a/app/gegl/gimpoperationgrainmergemode.c
+++ b/app/gegl/gimpoperationgrainmergemode.c
@@ -3,6 +3,7 @@
  *
  * gimpoperationgrainmergemode.c
  * Copyright (C) 2008 Michael Natterer <mitch gimp org>
+ *               2012 Ville Sokk <ville sokk gmail com>
  *
  * 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
@@ -28,6 +29,7 @@
 #include "gimpoperationgrainmergemode.h"
 
 
+static void     gimp_operation_grain_merge_mode_prepare (GeglOperation       *operation);
 static gboolean gimp_operation_grain_merge_mode_process (GeglOperation       *operation,
                                                          void                *in_buf,
                                                          void                *aux_buf,
@@ -55,7 +57,8 @@ gimp_operation_grain_merge_mode_class_init (GimpOperationGrainMergeModeClass *kl
                                  "description", "GIMP grain merge mode operation",
                                  NULL);
 
-  point_class->process         = gimp_operation_grain_merge_mode_process;
+  operation_class->prepare = gimp_operation_grain_merge_mode_prepare;
+  point_class->process     = gimp_operation_grain_merge_mode_process;
 }
 
 static void
@@ -63,6 +66,17 @@ gimp_operation_grain_merge_mode_init (GimpOperationGrainMergeMode *self)
 {
 }
 
+static void
+gimp_operation_grain_merge_mode_prepare (GeglOperation *operation)
+{
+  const Babl *format = babl_format ("R'G'B'A float");
+
+  gegl_operation_set_format (operation, "input",  format);
+  gegl_operation_set_format (operation, "aux",    format);
+  gegl_operation_set_format (operation, "output", format);
+}
+
+
 static gboolean
 gimp_operation_grain_merge_mode_process (GeglOperation       *operation,
                                          void                *in_buf,
@@ -78,9 +92,19 @@ gimp_operation_grain_merge_mode_process (GeglOperation       *operation,
 
   while (samples--)
     {
-      out[RED]   = in[RED];
-      out[GREEN] = in[GREEN];
-      out[BLUE]  = in[BLUE];
+      gint b;
+      gfloat comp_alpha = in[ALPHA] * layer[ALPHA];
+      gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat ratio      = comp_alpha / new_alpha;
+
+      for (b = RED; b < ALPHA; b++)
+        {
+          gfloat comp = in[b] + layer[b] - 0.5;
+          comp = CLAMP (comp, 0, 1);
+
+          out[b] = comp * ratio + in[b] * (1 - ratio);
+        }
+
       out[ALPHA] = in[ALPHA];
 
       in    += 4;
diff --git a/app/gegl/gimpoperationhardlightmode.c b/app/gegl/gimpoperationhardlightmode.c
index 4de5f0f..2845b41 100644
--- a/app/gegl/gimpoperationhardlightmode.c
+++ b/app/gegl/gimpoperationhardlightmode.c
@@ -3,6 +3,7 @@
  *
  * gimpoperationhardlightmode.c
  * Copyright (C) 2008 Michael Natterer <mitch gimp org>
+ *               2012 Ville Sokk <ville sokk gmail com>
  *
  * 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
@@ -28,6 +29,7 @@
 #include "gimpoperationhardlightmode.h"
 
 
+static void     gimp_operation_hardlight_mode_prepare (GeglOperation       *operation);
 static gboolean gimp_operation_hardlight_mode_process (GeglOperation       *operation,
                                                        void                *in_buf,
                                                        void                *aux_buf,
@@ -55,7 +57,8 @@ gimp_operation_hardlight_mode_class_init (GimpOperationHardlightModeClass *klass
                                  "description", "GIMP hardlight mode operation",
                                  NULL);
 
-  point_class->process         = gimp_operation_hardlight_mode_process;
+  operation_class->prepare = gimp_operation_hardlight_mode_prepare;
+  point_class->process     = gimp_operation_hardlight_mode_process;
 }
 
 static void
@@ -63,6 +66,16 @@ gimp_operation_hardlight_mode_init (GimpOperationHardlightMode *self)
 {
 }
 
+static void
+gimp_operation_hardlight_mode_prepare (GeglOperation *operation)
+{
+  const Babl *format = babl_format ("R'G'B'A float");
+
+  gegl_operation_set_format (operation, "input",  format);
+  gegl_operation_set_format (operation, "aux",    format);
+  gegl_operation_set_format (operation, "output", format);
+}
+
 static gboolean
 gimp_operation_hardlight_mode_process (GeglOperation       *operation,
                                        void                *in_buf,
@@ -78,9 +91,29 @@ gimp_operation_hardlight_mode_process (GeglOperation       *operation,
 
   while (samples--)
     {
-      out[RED]   = in[RED];
-      out[GREEN] = in[GREEN];
-      out[BLUE]  = in[BLUE];
+      gint b;
+      gfloat comp_alpha = in[ALPHA] * layer[ALPHA];
+      gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat ratio      = comp_alpha / new_alpha;
+
+      for (b = RED; b < ALPHA; b++)
+        {
+          gfloat comp;
+
+          if (layer[b] > 0.5)
+            {
+              comp = (1 - in[b]) * (1 - (layer[b] - 0.5) * 2);
+              comp = MIN (1 - comp, 1);
+            }
+          else
+            {
+              comp = in[b] * (layer[b] * 2);
+              comp = MIN (comp, 1);
+            }
+
+          out[b] = comp * ratio + in[b] * (1 - ratio);
+        }
+
       out[ALPHA] = in[ALPHA];
 
       in    += 4;
diff --git a/app/gegl/gimpoperationmultiplymode.c b/app/gegl/gimpoperationmultiplymode.c
index 5964a20..4aa3b0a 100644
--- a/app/gegl/gimpoperationmultiplymode.c
+++ b/app/gegl/gimpoperationmultiplymode.c
@@ -98,7 +98,8 @@ gimp_operation_multiply_mode_process (GeglOperation       *operation,
 
       for (b = RED; b < ALPHA; b++)
         {
-          gfloat comp = CLAMP (layer[b] * in[b], 0.0, 1.0);
+          gfloat comp = layer[b] * in[b];
+          comp = CLAMP (comp, 0, 1);
 
           out[b] = comp * ratio + in[b] * (1 - ratio);
         }
diff --git a/app/gegl/gimpoperationsubtractmode.c b/app/gegl/gimpoperationsubtractmode.c
index 71a6fd7..77f2544 100644
--- a/app/gegl/gimpoperationsubtractmode.c
+++ b/app/gegl/gimpoperationsubtractmode.c
@@ -3,6 +3,7 @@
  *
  * gimpoperationsubtractmode.c
  * Copyright (C) 2008 Michael Natterer <mitch gimp org>
+ *               2012 Ville Sokk <ville sokk gmail com>
  *
  * 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
@@ -28,6 +29,7 @@
 #include "gimpoperationsubtractmode.h"
 
 
+static void     gimp_operation_subtract_mode_prepare (GeglOperation       *operation);
 static gboolean gimp_operation_subtract_mode_process (GeglOperation       *operation,
                                                       void                *in_buf,
                                                       void                *aux_buf,
@@ -55,7 +57,8 @@ gimp_operation_subtract_mode_class_init (GimpOperationSubtractModeClass *klass)
                                  "description", "GIMP subtract mode operation",
                                  NULL);
 
-  point_class->process         = gimp_operation_subtract_mode_process;
+  operation_class->prepare = gimp_operation_subtract_mode_prepare;
+  point_class->process     = gimp_operation_subtract_mode_process;
 }
 
 static void
@@ -63,6 +66,16 @@ gimp_operation_subtract_mode_init (GimpOperationSubtractMode *self)
 {
 }
 
+static void
+gimp_operation_subtract_mode_prepare (GeglOperation *operation)
+{
+  const Babl *format = babl_format ("R'G'B'A float");
+
+  gegl_operation_set_format (operation, "input",  format);
+  gegl_operation_set_format (operation, "aux",    format);
+  gegl_operation_set_format (operation, "output", format);
+}
+
 static gboolean
 gimp_operation_subtract_mode_process (GeglOperation       *operation,
                                       void                *in_buf,
@@ -78,9 +91,19 @@ gimp_operation_subtract_mode_process (GeglOperation       *operation,
 
   while (samples--)
     {
-      out[RED]   = in[RED];
-      out[GREEN] = in[GREEN];
-      out[BLUE]  = in[BLUE];
+      gint b;
+      gfloat comp_alpha = in[ALPHA] * layer[ALPHA];
+      gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat ratio      = comp_alpha / new_alpha;
+
+      for (b = RED; b < ALPHA; b++)
+        {
+          gfloat comp = in[b] - layer[b];
+          comp = (comp < 0) ? 0 : comp;
+
+          out[b] = comp * ratio + in[b] * (1 - ratio);
+        }
+
       out[ALPHA] = in[ALPHA];
 
       in    += 4;



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