[gimp] app: cleaned code of blending modes



commit e2510b2f985eb21bbdd1f3c82fa051d43ae9516e
Author: Ville Sokk <ville sokk gmail com>
Date:   Thu May 31 22:06:31 2012 +0300

    app: cleaned code of blending modes

 app/operations/gimpoperationadditionmode.c     |   99 ++++++-------------
 app/operations/gimpoperationantierasemode.c    |   61 +++++-------
 app/operations/gimpoperationbehindmode.c       |  125 ++++++++---------------
 app/operations/gimpoperationburnmode.c         |   42 ++++----
 app/operations/gimpoperationcolormode.c        |   43 +++++----
 app/operations/gimpoperationdarkenonlymode.c   |   38 ++++----
 app/operations/gimpoperationdifferencemode.c   |   99 ++++++-------------
 app/operations/gimpoperationdissolvemode.c     |  105 +++++++-------------
 app/operations/gimpoperationdividemode.c       |   42 ++++----
 app/operations/gimpoperationdodgemode.c        |   42 ++++----
 app/operations/gimpoperationerasemode.c        |   50 +++++++---
 app/operations/gimpoperationgrainextractmode.c |   40 ++++----
 app/operations/gimpoperationgrainmergemode.c   |   40 ++++----
 app/operations/gimpoperationhardlightmode.c    |   44 +++++----
 app/operations/gimpoperationhuemode.c          |   47 +++++----
 app/operations/gimpoperationlightenonlymode.c  |   39 ++++----
 app/operations/gimpoperationmultiplymode.c     |  103 +++++++-------------
 app/operations/gimpoperationnormalmode.c       |  109 +++++++++------------
 app/operations/gimpoperationoverlaymode.c      |   96 ++++++------------
 app/operations/gimpoperationsaturationmode.c   |   43 +++++----
 app/operations/gimpoperationscreenmode.c       |  100 +++++++-------------
 app/operations/gimpoperationsoftlightmode.c    |   42 ++++----
 app/operations/gimpoperationsubtractmode.c     |   39 ++++----
 app/operations/gimpoperationvaluemode.c        |   43 +++++----
 24 files changed, 663 insertions(+), 868 deletions(-)
---
diff --git a/app/operations/gimpoperationadditionmode.c b/app/operations/gimpoperationadditionmode.c
index dda4585..12ad623 100644
--- a/app/operations/gimpoperationadditionmode.c
+++ b/app/operations/gimpoperationadditionmode.c
@@ -88,89 +88,54 @@ gimp_operation_addition_mode_process (GeglOperation       *operation,
                                       const GeglRectangle *roi,
                                       gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
-
-  if (mask)
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
+
+  while (samples--)
     {
-      while (samples--)
-        {
-          gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
-          gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat comp_alpha, new_alpha;
 
-          if (comp_alpha && new_alpha)
-            {
-              gfloat ratio = comp_alpha / new_alpha;
-              gint   b;
+      comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+      if (has_mask)
+        comp_alpha *= *mask;
 
-              for (b = RED; b < ALPHA; b++)
-                {
-                  gfloat comp = in[b] + layer[b];
-                  comp = CLAMP (comp, 0, 1);
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
-                  out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
-                }
+      if (comp_alpha && new_alpha)
+        {
+          gfloat ratio = comp_alpha / new_alpha;
+          gint   b;
 
-              out[ALPHA] = in[ALPHA];
-            }
-          else
+          for (b = RED; b < ALPHA; b++)
             {
-              gint b;
+              gfloat comp = in[b] + layer[b];
+              comp = CLAMP (comp, 0.0, 1.0);
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b];
-                }
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          in    += 4;
-          layer += 4;
-          mask  += 1;
-          out   += 4;
         }
-    }
-  else
-    {
-      while (samples--)
+      else
         {
-          gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-          gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+          gint b;
 
-          if (comp_alpha && new_alpha)
+          for (b = RED; b < ALPHA; b++)
             {
-              gfloat ratio = comp_alpha / new_alpha;
-              gint   b;
-
-              for (b = RED; b < ALPHA; b++)
-                {
-                  gfloat comp = in[b] + layer[b];
-                  comp = CLAMP (comp, 0, 1);
-
-                  out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
-                }
-
-              out[ALPHA] = in[ALPHA];
+              out[b] = in[b];
             }
-          else
-            {
-              gint b;
+        }
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b];
-                }
-            }
+      out[ALPHA] = in[ALPHA];
 
-          out[ALPHA] = in[ALPHA];
+      in    += 4;
+      layer += 4;
+      out   += 4;
 
-          in    += 4;
-          layer += 4;
-          out   += 4;
-        }
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationantierasemode.c b/app/operations/gimpoperationantierasemode.c
index 3553613..5ae51ca 100644
--- a/app/operations/gimpoperationantierasemode.c
+++ b/app/operations/gimpoperationantierasemode.c
@@ -47,7 +47,7 @@ G_DEFINE_TYPE (GimpOperationAntiEraseMode, gimp_operation_anti_erase_mode,
 static void
 gimp_operation_anti_erase_mode_class_init (GimpOperationAntiEraseModeClass *klass)
 {
-  GeglOperationClass              *operation_class;
+  GeglOperationClass               *operation_class;
   GeglOperationPointComposer3Class *point_class;
 
   operation_class = GEGL_OPERATION_CLASS (klass);
@@ -70,7 +70,7 @@ gimp_operation_anti_erase_mode_init (GimpOperationAntiEraseMode *self)
 static void
 gimp_operation_anti_erase_mode_prepare (GeglOperation *operation)
 {
-  const Babl *format = babl_format ("R'G'B'A float");
+  const Babl *format = babl_format ("RGBA float");
 
   gegl_operation_set_format (operation, "input",  format);
   gegl_operation_set_format (operation, "aux",    format);
@@ -88,49 +88,34 @@ gimp_operation_anti_erase_mode_process (GeglOperation       *operation,
                                         const GeglRectangle *roi,
                                         gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
-
-  if (mask)
+  gdouble         opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat         *in       = in_buf;
+  gfloat         *layer    = aux_buf;
+  gfloat         *mask     = aux2_buf;
+  gfloat         *out      = out_buf;
+  const gboolean  has_mask = mask != NULL;
+
+  while (samples--)
     {
-      while (samples--)
-        {
-          gint b;
+      gdouble value = opacity;
+      gint    b;
 
-          for (b = RED; b < ALPHA; b++)
-            {
-              out[b] = in[b];
-            }
+      if (has_mask)
+        value *= *mask;
 
-          out[ALPHA] = in[ALPHA] + (1 - in[ALPHA]) * layer[ALPHA] * opacity * (*mask);
+      out[ALPHA] = in[ALPHA] + (1.0 - in[ALPHA]) * layer[ALPHA] * value;
 
-          in    += 4;
-          layer += 4;
-          mask  += 1;
-          out   += 4;
-        }
-    }
-  else
-    {
-      while (samples--)
+      for (b = RED; b < ALPHA; b++)
         {
-          gint b;
-
-          for (b = RED; b < ALPHA; b++)
-            {
-              out[b] = in[b];
-            }
+          out[b] = in[b];
+        }
 
-          out[ALPHA] = in[ALPHA] + (1 - in[ALPHA]) * layer[ALPHA] * opacity;
+      in    += 4;
+      layer += 4;
+      out   += 4;
 
-          in    += 4;
-          layer += 4;
-          out   += 4;
-        }
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationbehindmode.c b/app/operations/gimpoperationbehindmode.c
index 857cc30..7d833fc 100644
--- a/app/operations/gimpoperationbehindmode.c
+++ b/app/operations/gimpoperationbehindmode.c
@@ -46,7 +46,7 @@ G_DEFINE_TYPE (GimpOperationBehindMode, gimp_operation_behind_mode,
 static void
 gimp_operation_behind_mode_class_init (GimpOperationBehindModeClass *klass)
 {
-  GeglOperationClass              *operation_class;
+  GeglOperationClass               *operation_class;
   GeglOperationPointComposer3Class *point_class;
 
   operation_class = GEGL_OPERATION_CLASS (klass);
@@ -57,7 +57,7 @@ gimp_operation_behind_mode_class_init (GimpOperationBehindModeClass *klass)
                                  "description", "GIMP behind mode operation",
                                  NULL);
 
-  point_class->process         = gimp_operation_behind_mode_process;
+  point_class->process = gimp_operation_behind_mode_process;
 }
 
 static void
@@ -75,107 +75,70 @@ gimp_operation_behind_mode_process (GeglOperation       *operation,
                                     const GeglRectangle *roi,
                                     gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  GimpOperationPointLayerMode *point    = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+  gdouble                      opacity  = point->opacity;
+  gfloat                      *in       = in_buf;
+  gfloat                      *layer    = aux_buf;
+  gfloat                      *mask     = aux2_buf;
+  gfloat                      *out      = out_buf;
+  const gboolean               has_mask = mask != NULL;
 
   if (point->premultiplied)
     {
-      if (mask)
+      while (samples--)
         {
-          while (samples--)
-            {
-              gint b;
-              gfloat value = opacity * (*mask);
+          gint    b;
+          gdouble value = opacity;
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b] + layer[b] * value * (1 - in[ALPHA]);
-                }
+          if (has_mask)
+            value *= *mask;
 
-              in    += 4;
-              layer += 4;
-              mask  += 1;
-              out   += 4;
-            }
-        }
-      else
-        {
-          while (samples--)
+          for (b = RED; b <= ALPHA; b++)
             {
-              gint b;
+              out[b] = in[b] + layer[b] * value * (1.0 - in[ALPHA]);
+            }
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b] + layer[b] * opacity * (1 - in[ALPHA]);
-                }
+          in    += 4;
+          layer += 4;
+          out   += 4;
 
-              in    += 4;
-              layer += 4;
-              out   += 4;
-            }
+          if (has_mask)
+            mask++;
         }
     }
   else
     {
-      if (mask)
+      while (samples--)
         {
-          while (samples--)
-            {
-              gint b;
-              gfloat value = opacity * (*mask);
+          gint    b;
+          gdouble value = opacity;
 
-              out[ALPHA] = in[ALPHA] + (1 - in[ALPHA]) * layer[ALPHA] * value;
-              if (out[ALPHA])
-                {
-                  for (b = RED; b < ALPHA; b++)
-                    {
-                      out[b] = (in[b] * in[ALPHA] + layer[b] * value * layer[ALPHA] * value * (1 - in[ALPHA])) / out[ALPHA];
-                    }
-                }
-              else
-                {
-                  for (b = RED; b <= ALPHA; b++)
-                    {
-                      out[b] = in[b];
-                    }
-                }
+          if (has_mask)
+            value *= *mask;
 
-              in    += 4;
-              layer += 4;
-              mask  += 1;
-              out   += 4;
-            }
-        }
-      else
-        {
-          while (samples--)
-            {
-              gint b;
+          out[ALPHA] = in[ALPHA] + (1.0 - in[ALPHA]) * layer[ALPHA] * value;
 
-              out[ALPHA] = in[ALPHA] + (1 - in[ALPHA]) * layer[ALPHA] * opacity;
-              if (out[ALPHA])
+          if (out[ALPHA])
+            {
+              for (b = RED; b < ALPHA; b++)
                 {
-                  for (b = RED; b < ALPHA; b++)
-                    {
-                      out[b] = (in[b] * in[ALPHA] + layer[b] * opacity * layer[ALPHA] * opacity * (1 - in[ALPHA])) / out[ALPHA];
-                    }
+                  out[b] = (in[b] * in[ALPHA] + layer[b] * value * layer[ALPHA] * value * (1.0 - in[ALPHA])) / out[ALPHA];
                 }
-              else
+            }
+          else
+            {
+              for (b = RED; b <= ALPHA; b++)
                 {
-                  for (b = RED; b <= ALPHA; b++)
-                    {
-                      out[b] = in[b];
-                    }
+                  out[b] = in[b];
                 }
-
-              in    += 4;
-              layer += 4;
-              out   += 4;
             }
+
+          in    += 4;
+          layer += 4;
+          out   += 4;
+
+          if (has_mask)
+            mask++;
         }
     }
 
diff --git a/app/operations/gimpoperationburnmode.c b/app/operations/gimpoperationburnmode.c
index f2ea7fb..c16da46 100644
--- a/app/operations/gimpoperationburnmode.c
+++ b/app/operations/gimpoperationburnmode.c
@@ -88,52 +88,54 @@ gimp_operation_burn_mode_process (GeglOperation       *operation,
                                   const GeglRectangle *roi,
                                   gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint b;
-      gfloat comp_alpha, new_alpha, ratio;
+      gfloat comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gfloat ratio = comp_alpha / new_alpha;
+          gint   b;
 
           for (b = RED; b < ALPHA; b++)
             {
-              gfloat comp = (1 - in[b]) / layer[b];
-              comp = CLAMP (1 - comp, 0, 1);
+              gfloat comp = (1.0 - in[b]) / layer[b];
+              comp = CLAMP (1.0 - comp, 0.0, 1.0);
 
-              out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          out[ALPHA] = in[ALPHA];
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationcolormode.c b/app/operations/gimpoperationcolormode.c
index caa19f6..e4a7dbe 100644
--- a/app/operations/gimpoperationcolormode.c
+++ b/app/operations/gimpoperationcolormode.c
@@ -92,30 +92,30 @@ gimp_operation_color_mode_process (GeglOperation       *operation,
                                    const GeglRectangle *roi,
                                    gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint    b;
       GimpHSL layer_hsl, out_hsl;
-      GimpRGB layer_rgb  = {layer[0], layer[1], layer[2]};
-      GimpRGB out_rgb    = {in[0], in[1], in[2]};
-      gfloat comp_alpha, new_alpha, ratio;
+      GimpRGB layer_rgb = {layer[0], layer[1], layer[2]};
+      GimpRGB out_rgb   = {in[0], in[1], in[2]};
+      gfloat  comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gint   b;
+          gfloat ratio = comp_alpha / new_alpha;
 
           gimp_rgb_to_hsl (&layer_rgb, &layer_hsl);
           gimp_rgb_to_hsl (&out_rgb, &out_hsl);
@@ -127,25 +127,30 @@ gimp_operation_color_mode_process (GeglOperation       *operation,
           out[0] = out_rgb.r;
           out[1] = out_rgb.g;
           out[2] = out_rgb.b;
-          out[3] = in[3];
 
           for (b = RED; b < ALPHA; b++)
-            out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+            {
+              out[b] = out[b] * ratio + in[b] * (1.0 - ratio);
+            }
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationdarkenonlymode.c b/app/operations/gimpoperationdarkenonlymode.c
index b4a6e74..8945e62 100644
--- a/app/operations/gimpoperationdarkenonlymode.c
+++ b/app/operations/gimpoperationdarkenonlymode.c
@@ -88,51 +88,53 @@ gimp_operation_darken_only_mode_process (GeglOperation       *operation,
                                          const GeglRectangle *roi,
                                          gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint b;
-      gfloat comp_alpha, new_alpha, ratio;
+      gfloat comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (new_alpha && comp_alpha)
         {
-          ratio = comp_alpha / new_alpha;
+          gint   b;
+          gfloat ratio = comp_alpha / new_alpha;
 
           for (b = RED; b < ALPHA; b++)
             {
               gfloat comp = MIN (in[b], layer[b]);
 
-              out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          out[ALPHA] = in[ALPHA];
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationdifferencemode.c b/app/operations/gimpoperationdifferencemode.c
index dcca241..295dc1b 100644
--- a/app/operations/gimpoperationdifferencemode.c
+++ b/app/operations/gimpoperationdifferencemode.c
@@ -88,87 +88,54 @@ gimp_operation_difference_mode_process (GeglOperation       *operation,
                                         const GeglRectangle *roi,
                                         gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
-
-  if (mask)
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
+
+  while (samples--)
     {
-      while (samples--)
-        {
-          gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
-          gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat comp_alpha, new_alpha;
 
-          if (comp_alpha && new_alpha)
-            {
-              gfloat ratio = comp_alpha / new_alpha;
-              gint   b;
+      comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+      if (has_mask)
+        comp_alpha *= *mask;
 
-              for (b = RED; b < ALPHA; b++)
-                {
-                  gfloat comp = in[b] - layer[b];
-                  comp = (comp < 0) ? -comp : comp;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
-                  out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
-                }
+      if (comp_alpha && new_alpha)
+        {
+          gfloat ratio = comp_alpha / new_alpha;
+          gint   b;
 
-              out[ALPHA] = in[ALPHA];
-            }
-          else
+          for (b = RED; b < ALPHA; b++)
             {
-              gint b;
+              gfloat comp = in[b] - layer[b];
+              comp = (comp < 0) ? -comp : comp;
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b];
-                }
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          in    += 4;
-          layer += 4;
-          mask  += 1;
-          out   += 4;
         }
-    }
-  else
-    {
-      while (samples--)
+      else
         {
-          gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-          gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+          gint b;
 
-          if (comp_alpha && new_alpha)
+          for (b = RED; b < ALPHA; b++)
             {
-              gfloat ratio = comp_alpha / new_alpha;
-              gint   b;
-
-              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) + 0.0001;
-                }
-
-              out[ALPHA] = in[ALPHA];
+              out[b] = in[b];
             }
-          else
-            {
-              gint b;
+        }
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b];
-                }
-            }
+      out[ALPHA] = in[ALPHA];
 
-          in    += 4;
-          layer += 4;
-          out   += 4;
-        }
+      in    += 4;
+      layer += 4;
+      out   += 4;
+
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationdissolvemode.c b/app/operations/gimpoperationdissolvemode.c
index c906416..bc264b5 100644
--- a/app/operations/gimpoperationdissolvemode.c
+++ b/app/operations/gimpoperationdissolvemode.c
@@ -103,83 +103,52 @@ gimp_operation_dissolve_mode_process (GeglOperation       *operation,
                                       const GeglRectangle *result,
                                       gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *out     = out_buf;
-  gfloat                      *aux     = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gint                         x, y;
-
-  if (mask)
+  gdouble         opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat         *in       = in_buf;
+  gfloat         *out      = out_buf;
+  gfloat         *aux      = aux_buf;
+  gfloat         *mask     = aux2_buf;
+  const gboolean  has_mask = mask != NULL;
+  gint            x, y;
+
+  for (y = result->y; y < result->y + result->height; y++)
     {
-      for (y = result->y; y < result->y + result->height; y++)
-        {
-          GRand *gr = g_rand_new_with_seed (random_table[y % RANDOM_TABLE_SIZE]);
+      GRand *gr = g_rand_new_with_seed (random_table[y % RANDOM_TABLE_SIZE]);
 
-          /* fast forward through the rows pseudo random sequence */
-          for (x = 0; x < result->x; x++)
-            g_rand_int (gr);
+      /* fast forward through the rows pseudo random sequence */
+      for (x = 0; x < result->x; x++)
+        g_rand_int (gr);
 
-          for (x = result->x; x < result->x + result->width; x++)
-            {
-              gfloat value = opacity * (*mask);
-
-              if (g_rand_int_range (gr, 0, 255) >= aux[3] * value * 255)
-                {
-                  out[0] = in[0];
-                  out[1] = in[1];
-                  out[2] = in[2];
-                  out[3] = in[3];
-                }
-              else
-                {
-                  out[0] = aux[0];
-                  out[1] = aux[1];
-                  out[2] = aux[2];
-                  out[3] = 1.0;
-                }
-
-              in   += 4;
-              out  += 4;
-              aux  += 4;
-              mask += 1;
-            }
-          g_rand_free (gr);
-        }
-    }
-  else
-    {
-      for (y = result->y; y < result->y + result->height; y++)
+      for (x = result->x; x < result->x + result->width; x++)
         {
-          GRand *gr = g_rand_new_with_seed (random_table[y % RANDOM_TABLE_SIZE]);
+          gfloat value = aux[ALPHA] * opacity * 255;
 
-          /* fast forward through the rows pseudo random sequence */
-          for (x = 0; x < result->x; x++)
-            g_rand_int (gr);
+          if (has_mask)
+            value *= *mask;
 
-          for (x = result->x; x < result->x + result->width; x++)
+          if (g_rand_int_range (gr, 0, 255) >= value)
+            {
+              out[0] = in[0];
+              out[1] = in[1];
+              out[2] = in[2];
+              out[3] = in[3];
+            }
+          else
             {
-              if (g_rand_int_range (gr, 0, 255) >= aux[3] * opacity * 255)
-                {
-                  out[0] = in[0];
-                  out[1] = in[1];
-                  out[2] = in[2];
-                  out[3] = in[3];
-                }
-              else
-                {
-                  out[0] = aux[0];
-                  out[1] = aux[1];
-                  out[2] = aux[2];
-                  out[3] = 1.0;
-                }
-              in   += 4;
-              out  += 4;
-              aux  += 4;
+              out[0] = aux[0];
+              out[1] = aux[1];
+              out[2] = aux[2];
+              out[3] = 1.0;
             }
-          g_rand_free (gr);
+
+          in   += 4;
+          out  += 4;
+          aux  += 4;
+
+          if (has_mask)
+            mask ++;
         }
+      g_rand_free (gr);
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationdividemode.c b/app/operations/gimpoperationdividemode.c
index 7840821..597d61f 100644
--- a/app/operations/gimpoperationdividemode.c
+++ b/app/operations/gimpoperationdividemode.c
@@ -88,52 +88,54 @@ gimp_operation_divide_mode_process (GeglOperation       *operation,
                                     const GeglRectangle *roi,
                                     gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint b;
-      gfloat comp_alpha, new_alpha, ratio;
+      gfloat comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gint   b;
+          gfloat ratio = comp_alpha / new_alpha;
 
           for (b = RED; b < ALPHA; b++)
             {
-              gfloat comp = (256 / 255.0 * in[b]) / (1 / 255.0 + layer[b]);
-              comp = MIN (comp, 1);
+              gfloat comp = (256.0 / 255.0 * in[b]) / (1.0 / 255.0 + layer[b]);
+              comp = MIN (comp, 1.0);
 
-              out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          out[ALPHA] = in[ALPHA];
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationdodgemode.c b/app/operations/gimpoperationdodgemode.c
index 992532e..bdaeec6 100644
--- a/app/operations/gimpoperationdodgemode.c
+++ b/app/operations/gimpoperationdodgemode.c
@@ -88,52 +88,54 @@ gimp_operation_dodge_mode_process (GeglOperation       *operation,
                                    const GeglRectangle *roi,
                                    gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint b;
-      gfloat comp_alpha, new_alpha, ratio;
+      gfloat comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gint   b;
+          gfloat ratio = comp_alpha / new_alpha;
 
           for (b = RED; b < ALPHA; b++)
             {
-              gfloat comp = in[b] / (1 - layer[b]);
-              comp = MIN (comp, 1);
+              gfloat comp = in[b] / (1.0 - layer[b]);
+              comp = MIN (comp, 1.0);
 
-              out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          out[ALPHA] = in[ALPHA];
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationerasemode.c b/app/operations/gimpoperationerasemode.c
index b027474..1947783 100644
--- a/app/operations/gimpoperationerasemode.c
+++ b/app/operations/gimpoperationerasemode.c
@@ -29,6 +29,7 @@
 #include "gimpoperationerasemode.h"
 
 
+static void prepare (GeglOperation *operation);
 static gboolean gimp_operation_erase_mode_process (GeglOperation       *operation,
                                                    void                *in_buf,
                                                    void                *aux_buf,
@@ -57,6 +58,7 @@ gimp_operation_erase_mode_class_init (GimpOperationEraseModeClass *klass)
                                  "description", "GIMP erase mode operation",
                                  NULL);
 
+  operation_class->prepare = prepare;
   point_class->process         = gimp_operation_erase_mode_process;
 }
 
@@ -65,6 +67,17 @@ gimp_operation_erase_mode_init (GimpOperationEraseMode *self)
 {
 }
 
+static void
+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_erase_mode_process (GeglOperation       *operation,
                                    void                *in_buf,
@@ -75,23 +88,26 @@ gimp_operation_erase_mode_process (GeglOperation       *operation,
                                    const GeglRectangle *roi,
                                    gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  GimpOperationPointLayerMode *point    = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+  gdouble                      opacity  = point->opacity;
+  gfloat                      *in       = in_buf;
+  gfloat                      *layer    = aux_buf;
+  gfloat                      *mask     = aux2_buf;
+  gfloat                      *out      = out_buf;
+  const gboolean               has_mask = mask != NULL;
 
   if (point->premultiplied)
     {
       while (samples--)
         {
-          gint b;
-          gfloat value = opacity;
-          if (mask)
+          gint    b;
+          gdouble value = opacity;
+
+          if (has_mask)
             value *= (*mask);
 
           out[ALPHA] = in[ALPHA] - in[ALPHA] * layer[ALPHA] * value;
+
           for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b] / in[ALPHA] * out[ALPHA];
@@ -101,31 +117,33 @@ gimp_operation_erase_mode_process (GeglOperation       *operation,
           layer += 4;
           out   += 4;
 
-          if (mask)
-            mask += 1;
+          if (has_mask)
+            mask ++;
         }
     }
   else
     {
       while (samples--)
         {
-          gint b;
-          gfloat value = opacity;
-          if (mask)
+          gint    b;
+          gdouble value = opacity;
+
+          if (has_mask)
             value *= (*mask);
 
           for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
+
           out[ALPHA] = in[ALPHA] - in[ALPHA] * layer[ALPHA] * value;
 
           in    += 4;
           layer += 4;
           out   += 4;
 
-          if (mask)
-            mask += 1;
+          if (has_mask)
+            mask ++;
         }
     }
 
diff --git a/app/operations/gimpoperationgrainextractmode.c b/app/operations/gimpoperationgrainextractmode.c
index c30a55f..1f1cf9f 100644
--- a/app/operations/gimpoperationgrainextractmode.c
+++ b/app/operations/gimpoperationgrainextractmode.c
@@ -89,52 +89,54 @@ gimp_operation_grain_extract_mode_process (GeglOperation       *operation,
                                            const GeglRectangle *roi,
                                            gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint b;
-      gfloat comp_alpha, new_alpha, ratio;
+      gfloat comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gfloat ratio = comp_alpha / new_alpha;
+          gint   b;
 
           for (b = RED; b < ALPHA; b++)
             {
               gfloat comp = in[b] - layer[b] + 0.5;
-              comp = CLAMP (comp, 0, 1);
+              comp = CLAMP (comp, 0.0, 1.0);
 
-              out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          out[ALPHA] = in[ALPHA];
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationgrainmergemode.c b/app/operations/gimpoperationgrainmergemode.c
index 5c707ba..b270190 100644
--- a/app/operations/gimpoperationgrainmergemode.c
+++ b/app/operations/gimpoperationgrainmergemode.c
@@ -89,52 +89,54 @@ gimp_operation_grain_merge_mode_process (GeglOperation       *operation,
                                          const GeglRectangle *roi,
                                          gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble         opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat         *in       = in_buf;
+  gfloat         *layer    = aux_buf;
+  gfloat         *mask     = aux2_buf;
+  gfloat         *out      = out_buf;
+  const gboolean  has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint b;
-      gfloat comp_alpha, new_alpha, ratio;
+      gfloat comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gfloat ratio = comp_alpha / new_alpha;
+          gint   b;
 
           for (b = RED; b < ALPHA; b++)
             {
               gfloat comp = in[b] + layer[b] - 0.5;
-              comp = CLAMP (comp, 0, 1);
+              comp = CLAMP (comp, 0.0, 1.0);
 
-              out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          out[ALPHA] = in[ALPHA];
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask ++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationhardlightmode.c b/app/operations/gimpoperationhardlightmode.c
index b682cb7..8ae8f9b 100644
--- a/app/operations/gimpoperationhardlightmode.c
+++ b/app/operations/gimpoperationhardlightmode.c
@@ -88,27 +88,27 @@ gimp_operation_hardlight_mode_process (GeglOperation       *operation,
                                        const GeglRectangle *roi,
                                        gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint b;
-      gfloat comp_alpha, new_alpha, ratio;
+      gfloat comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gfloat ratio = comp_alpha / new_alpha;
+          gint   b;
 
           for (b = RED; b < ALPHA; b++)
             {
@@ -116,34 +116,36 @@ gimp_operation_hardlight_mode_process (GeglOperation       *operation,
 
               if (layer[b] > 0.5)
                 {
-                  comp = (1 - in[b]) * (1 - (layer[b] - 0.5) * 2);
+                  comp = (1.0 - in[b]) * (1.0 - (layer[b] - 0.5) * 2.0);
                   comp = MIN (1 - comp, 1);
                 }
               else
                 {
-                  comp = in[b] * (layer[b] * 2);
-                  comp = MIN (comp, 1);
+                  comp = in[b] * (layer[b] * 2.0);
+                  comp = MIN (comp, 1.0);
                 }
 
-              out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          out[ALPHA] = in[ALPHA];
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask ++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationhuemode.c b/app/operations/gimpoperationhuemode.c
index aaae343..b468ca5 100644
--- a/app/operations/gimpoperationhuemode.c
+++ b/app/operations/gimpoperationhuemode.c
@@ -92,30 +92,30 @@ gimp_operation_hue_mode_process (GeglOperation       *operation,
                                  const GeglRectangle *roi,
                                  gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint    b;
       GimpHSV layer_hsv, out_hsv;
-      GimpRGB layer_rgb  = {layer[0], layer[1], layer[2]};
-      GimpRGB out_rgb    = {in[0], in[1], in[2]};
-      gfloat comp_alpha, new_alpha, ratio;
+      GimpRGB layer_rgb = {layer[0], layer[1], layer[2]};
+      GimpRGB out_rgb   = {in[0], in[1], in[2]};
+      gfloat  comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gint   b;
+          gfloat ratio = comp_alpha / new_alpha;
 
           gimp_rgb_to_hsv (&layer_rgb, &layer_hsv);
           gimp_rgb_to_hsv (&out_rgb, &out_hsv);
@@ -124,31 +124,38 @@ gimp_operation_hue_mode_process (GeglOperation       *operation,
            *  otherwise, black would be painted red (see bug #123296).
            */
           if (layer_hsv.s)
-            out_hsv.h = layer_hsv.h;
+            {
+              out_hsv.h = layer_hsv.h;
+            }
           gimp_hsv_to_rgb (&out_hsv, &out_rgb);
 
           out[0] = out_rgb.r;
           out[1] = out_rgb.g;
           out[2] = out_rgb.b;
-          out[3] = in[3];
 
           for (b = RED; b < ALPHA; b++)
-            out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+            {
+              out[b] = out[b] * ratio + in[b] * (1.0 - ratio);
+            }
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationlightenonlymode.c b/app/operations/gimpoperationlightenonlymode.c
index 9bd7343..b2cb2f3 100644
--- a/app/operations/gimpoperationlightenonlymode.c
+++ b/app/operations/gimpoperationlightenonlymode.c
@@ -28,6 +28,7 @@
 
 #include "gimpoperationlightenonlymode.h"
 
+
 static void     gimp_operation_lighten_only_mode_prepare (GeglOperation       *operation);
 static gboolean gimp_operation_lighten_only_mode_process (GeglOperation       *operation,
                                                           void                *in_buf,
@@ -87,51 +88,53 @@ gimp_operation_lighten_only_mode_process (GeglOperation       *operation,
                                           const GeglRectangle *result,
                                           gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint b;
-      gfloat comp_alpha, new_alpha, ratio;
+      gfloat comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio = comp_alpha / new_alpha;
+          gint   b;
+          gfloat ratio = comp_alpha / new_alpha;
 
           for (b = RED; b < ALPHA; b++)
             {
               gfloat comp = MAX (layer[b], in[b]);
 
-              out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          out[ALPHA] = in[ALPHA];
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationmultiplymode.c b/app/operations/gimpoperationmultiplymode.c
index 8d690c9..6c126fd 100644
--- a/app/operations/gimpoperationmultiplymode.c
+++ b/app/operations/gimpoperationmultiplymode.c
@@ -47,7 +47,7 @@ G_DEFINE_TYPE (GimpOperationMultiplyMode, gimp_operation_multiply_mode,
 static void
 gimp_operation_multiply_mode_class_init (GimpOperationMultiplyModeClass *klass)
 {
-  GeglOperationClass              *operation_class;
+  GeglOperationClass               *operation_class;
   GeglOperationPointComposer3Class *point_class;
 
   operation_class = GEGL_OPERATION_CLASS (klass);
@@ -58,8 +58,8 @@ gimp_operation_multiply_mode_class_init (GimpOperationMultiplyModeClass *klass)
                                  "description", "GIMP multiply mode operation",
                                  NULL);
 
-  point_class->process     = gimp_operation_multiply_mode_process;
   operation_class->prepare = gimp_operation_multiply_mode_prepare;
+  point_class->process     = gimp_operation_multiply_mode_process;
 }
 
 static void
@@ -88,87 +88,54 @@ gimp_operation_multiply_mode_process (GeglOperation       *operation,
                                       const GeglRectangle *roi,
                                       gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
-
-  if (mask)
+  gdouble         opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat         *in       = in_buf;
+  gfloat         *layer    = aux_buf;
+  gfloat         *mask     = aux2_buf;
+  gfloat         *out      = out_buf;
+  const gboolean  has_mask = mask != NULL;
+
+  while (samples--)
     {
-      while (samples--)
-        {
-          gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
-          gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat comp_alpha, new_alpha;
 
-          if (comp_alpha && new_alpha)
-            {
-              gfloat ratio = comp_alpha / new_alpha;
-              gint   b;
+      comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+      if (has_mask)
+        comp_alpha *= *mask;
 
-              for (b = RED; b < ALPHA; b++)
-                {
-                  gfloat comp = layer[b] * in[b];
-                  comp = CLAMP (comp, 0, 1);
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
-                  out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
-                }
+      if (comp_alpha && new_alpha)
+        {
+          gfloat ratio = comp_alpha / new_alpha;
+          gint   b;
 
-              out[ALPHA] = in[ALPHA];
-            }
-          else
+          for (b = RED; b < ALPHA; b++)
             {
-              gint b;
+              gfloat comp = layer[b] * in[b];
+              comp = CLAMP (comp, 0.0, 1.0);
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b];
-                }
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          in    += 4;
-          layer += 4;
-          mask  += 1;
-          out   += 4;
         }
-    }
-  else
-    {
-      while (samples--)
+      else
         {
-          gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-          gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+          gint b;
 
-          if (comp_alpha && new_alpha)
+          for (b = RED; b < ALPHA; b++)
             {
-              gfloat ratio = comp_alpha / new_alpha;
-              gint   b;
-
-              for (b = RED; b < ALPHA; b++)
-                {
-                  gfloat comp = layer[b] * in[b];
-                  comp = CLAMP (comp, 0, 1);
-
-                  out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
-                }
-
-              out[ALPHA] = in[ALPHA];
+              out[b] = in[b];
             }
-          else
-            {
-              gint b;
+        }
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b];
-                }
-            }
+      out[ALPHA] = in[ALPHA];
 
-          in    += 4;
-          layer += 4;
-          out   += 4;
-        }
+      in    += 4;
+      layer += 4;
+      out   += 4;
+
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationnormalmode.c b/app/operations/gimpoperationnormalmode.c
index 5321e7c..5bf7e47 100644
--- a/app/operations/gimpoperationnormalmode.c
+++ b/app/operations/gimpoperationnormalmode.c
@@ -63,7 +63,6 @@ gimp_operation_normal_mode_class_init (GimpOperationNormalModeClass *klass)
                                  "description", "GIMP normal mode operation",
                                  NULL);
 
-
   operation_class->process     = gimp_operation_normal_parent_process;
 
   point_class->process         = gimp_operation_normal_mode_process;
@@ -131,95 +130,79 @@ gimp_operation_normal_mode_process (GeglOperation       *operation,
                                     const GeglRectangle *roi,
                                     gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                      *in      = in_buf;
-  gfloat                      *aux     = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
-  gdouble                      opacity = point->opacity;
+  GimpOperationPointLayerMode *point    = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+  gdouble                      opacity  = point->opacity;
+  gfloat                      *in       = in_buf;
+  gfloat                      *aux      = aux_buf;
+  gfloat                      *mask     = aux2_buf;
+  gfloat                      *out      = out_buf;
+  const gboolean               has_mask = mask != NULL;
 
   if (point->premultiplied)
     {
-      if (mask)
+      while (samples--)
         {
-          while (samples--)
-            {
-              gfloat value     = opacity * (*mask);
-              gfloat aux_alpha = aux[ALPHA] * value;
-              gint   b;
-
-              for (b = RED; b < ALPHA; b++)
-                {
-                  out[b] = aux[b] * value + in[b] * (1.0f - aux_alpha);
-                }
+          gdouble value;
+          gfloat  aux_alpha;
+          gint    b;
 
-              out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];
+          value = opacity;
+          if (has_mask)
+            value *= *mask;
+          aux_alpha = aux[ALPHA] * value;
 
-              in   += 4;
-              aux  += 4;
-              mask += 1;
-              out  += 4;
-            }
-        }
-      else
-        {
-          while (samples--)
+          for (b = RED; b < ALPHA; b++)
             {
-              gfloat aux_alpha = aux[ALPHA] * opacity;
-              gint   b;
+              out[b] = aux[b] * value + in[b] * (1.0f - aux_alpha);
+            }
 
-              for (b = RED; b < ALPHA; b++)
-                {
-                  out[b] = aux[b] * opacity + in[b] * (1.0f - aux_alpha);
-                }
+          out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];
 
-              out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];
+          in   += 4;
+          aux  += 4;
+          out  += 4;
 
-              in   += 4;
-              aux  += 4;
-              out  += 4;
-            }
+          if (has_mask)
+            mask++;
         }
     }
   else
     {
-      if (mask)
+      while (samples--)
         {
-          while (samples--)
+          gfloat aux_alpha;
+
+          aux_alpha = aux[ALPHA] * opacity;
+          if (has_mask)
+            aux_alpha *= *mask;
+
+          out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];
+
+          if (out[ALPHA])
             {
-              gfloat value     = opacity * (*mask);
-              gfloat aux_alpha = aux[ALPHA] * value;
-              gint   b;
+              gint b;
 
-              out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];
               for (b = RED; b < ALPHA; b++)
                 {
-                  out[b] = (aux[b] * aux_alpha + in[b] * in[ALPHA] * (1.0 - aux_alpha)) / out[ALPHA];
+                  out[b] = (aux[b] * aux_alpha + in[b] * in[ALPHA] * (1.0f - aux_alpha)) / out[ALPHA];
                 }
-
-              in   += 4;
-              aux  += 4;
-              mask += 1;
-              out  += 4;
             }
-        }
-      else
-        {
-          while (samples--)
+          else
             {
-              gfloat aux_alpha = aux[ALPHA] * opacity;
-              gint   b;
+              gint b;
 
-              out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];
               for (b = RED; b < ALPHA; b++)
                 {
-                  out[b] = (aux[b] * aux_alpha + in[b] * in[ALPHA] * (1.0 - aux_alpha)) / out[ALPHA];
+                  out[b] = in[b];
                 }
-
-              in  += 4;
-              aux += 4;
-              out += 4;
             }
+
+          in   += 4;
+          aux  += 4;
+          out  += 4;
+
+          if (has_mask)
+            mask++;
         }
     }
 
diff --git a/app/operations/gimpoperationoverlaymode.c b/app/operations/gimpoperationoverlaymode.c
index 3174a60..611cf4e 100644
--- a/app/operations/gimpoperationoverlaymode.c
+++ b/app/operations/gimpoperationoverlaymode.c
@@ -88,85 +88,53 @@ gimp_operation_overlay_mode_process (GeglOperation       *operation,
                                      const GeglRectangle *roi,
                                      gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
-
-  if (mask)
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
+
+  while (samples--)
     {
-      while (samples--)
-        {
-          gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
-          gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat comp_alpha, new_alpha;
 
-          if (comp_alpha && new_alpha)
-            {
-              gint   b;
-              gfloat ratio = comp_alpha / new_alpha;
+      comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+      if (has_mask)
+        comp_alpha *= *mask;
 
-              for (b = RED; b < ALPHA; b++)
-                {
-                  gfloat comp = in[b] * (in[b] + (2 * layer[b]) * (1 - in[b]));
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
-                  out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
-                }
+      if (comp_alpha && new_alpha)
+        {
+          gint   b;
+          gfloat ratio = comp_alpha / new_alpha;
 
-              out[ALPHA] = in[ALPHA];
-            }
-          else
+          for (b = RED; b < ALPHA; b++)
             {
-              gint b;
+              gfloat comp = in[b] * (in[b] + (2.0 * layer[b]) * (1.0 - in[b]));
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b];
-                }
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          in    += 4;
-          layer += 4;
-          mask  += 1;
-          out   += 4;
         }
-    }
-  else
-    {
-      while (samples--)
+      else
         {
-          gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-          gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+          gint b;
 
-          if (comp_alpha && new_alpha)
+          for (b = RED; b < ALPHA; b++)
             {
-              gfloat ratio = comp_alpha / new_alpha;
-              gint   b;
-
-              for (b = RED; b < ALPHA; b++)
-                {
-                  gfloat comp = in[b] * (in[b] + (2 * layer[b]) * (1 - in[b]));
-
-                  out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
-                }
-
-              out[ALPHA] = in[ALPHA];
+              out[b] = in[b];
             }
-          else
-            {
-              gint b;
+        }
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b];
-                }
-            }
+      out[ALPHA] = in[ALPHA];
 
-          in    += 4;
-          layer += 4;
-          out   += 4;
-        }
+      in    += 4;
+      layer += 4;
+      out   += 4;
+
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationsaturationmode.c b/app/operations/gimpoperationsaturationmode.c
index f9cdfe6..369acdc 100644
--- a/app/operations/gimpoperationsaturationmode.c
+++ b/app/operations/gimpoperationsaturationmode.c
@@ -92,30 +92,30 @@ gimp_operation_saturation_mode_process (GeglOperation       *operation,
                                         const GeglRectangle *roi,
                                         gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint    b;
       GimpHSV layer_hsv, out_hsv;
-      GimpRGB layer_rgb  = {layer[0], layer[1], layer[2]};
-      GimpRGB out_rgb    = {in[0], in[1], in[2]};
-      gfloat comp_alpha, new_alpha, ratio;
+      GimpRGB layer_rgb = {layer[0], layer[1], layer[2]};
+      GimpRGB out_rgb   = {in[0], in[1], in[2]};
+      gfloat  comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gint   b;
+          gfloat ratio = comp_alpha / new_alpha;
 
           gimp_rgb_to_hsv (&layer_rgb, &layer_hsv);
           gimp_rgb_to_hsv (&out_rgb, &out_hsv);
@@ -126,25 +126,30 @@ gimp_operation_saturation_mode_process (GeglOperation       *operation,
           out[0] = out_rgb.r;
           out[1] = out_rgb.g;
           out[2] = out_rgb.b;
-          out[3] = in[3];
 
           for (b = RED; b < ALPHA; b++)
-            out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+            {
+              out[b] = out[b] * ratio + in[b] * (1.0 - ratio);
+            }
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationscreenmode.c b/app/operations/gimpoperationscreenmode.c
index 5cffcaa..54cf8d6 100644
--- a/app/operations/gimpoperationscreenmode.c
+++ b/app/operations/gimpoperationscreenmode.c
@@ -47,7 +47,7 @@ G_DEFINE_TYPE (GimpOperationScreenMode, gimp_operation_screen_mode,
 static void
 gimp_operation_screen_mode_class_init (GimpOperationScreenModeClass *klass)
 {
-  GeglOperationClass              *operation_class;
+  GeglOperationClass               *operation_class;
   GeglOperationPointComposer3Class *point_class;
 
   operation_class = GEGL_OPERATION_CLASS (klass);
@@ -58,8 +58,8 @@ gimp_operation_screen_mode_class_init (GimpOperationScreenModeClass *klass)
                                  "description", "GIMP screen mode operation",
                                  NULL);
 
-  point_class->process     = gimp_operation_screen_mode_process;
   operation_class->prepare = gimp_operation_screen_mode_prepare;
+  point_class->process     = gimp_operation_screen_mode_process;
 }
 
 static void
@@ -88,85 +88,53 @@ gimp_operation_screen_mode_process (GeglOperation       *operation,
                                     const GeglRectangle *roi,
                                     gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
-
-  if (mask)
+  gdouble         opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat         *in       = in_buf;
+  gfloat         *layer    = aux_buf;
+  gfloat         *mask     = aux2_buf;
+  gfloat         *out      = out_buf;
+  const gboolean  has_mask = mask != NULL;
+
+  while (samples--)
     {
-      while (samples--)
-        {
-          gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
-          gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      gfloat comp_alpha, new_alpha;
 
-          if (comp_alpha && new_alpha)
-            {
-              gfloat ratio = comp_alpha / new_alpha;
-              gint   b;
+      comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+      if (has_mask)
+        comp_alpha *= *mask;
 
-              for (b = RED; b < ALPHA; b++)
-                {
-                  gfloat comp = 1 - (1 - in[b]) * (1 - layer[b]);
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
-                  out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
-                }
+      if (comp_alpha && new_alpha)
+        {
+          gfloat ratio = comp_alpha / new_alpha;
+          gint   b;
 
-              out[ALPHA] = in[ALPHA];
-            }
-          else
+          for (b = RED; b < ALPHA; b++)
             {
-              gint b;
+              gfloat comp = 1.0 - (1.0 - in[b]) * (1.0 - layer[b]);
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b];
-                }
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          in    += 4;
-          layer += 4;
-          mask  += 1;
-          out   += 4;
         }
-    }
-  else
-    {
-      while (samples--)
+      else
         {
-          gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-          gfloat new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+          gint b;
 
-          if (comp_alpha && new_alpha)
+          for (b = RED; b < ALPHA; b++)
             {
-              gfloat ratio = comp_alpha / new_alpha;
-              gint   b;
-
-              for (b = RED; b < ALPHA; b++)
-                {
-                  gfloat comp = 1 - (1 - in[b]) * (1 - layer[b]);
-
-                  out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
-                }
-
-              out[ALPHA] = in[ALPHA];
+              out[b] = in[b];
             }
-          else
-            {
-              gint b;
+        }
 
-              for (b = RED; b <= ALPHA; b++)
-                {
-                  out[b] = in[b];
-                }
-            }
+      out[ALPHA] = in[ALPHA];
 
-          in    += 4;
-          layer += 4;
-          out   += 4;
-        }
+      in    += 4;
+      layer += 4;
+      out   += 4;
+
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationsoftlightmode.c b/app/operations/gimpoperationsoftlightmode.c
index d4d32bb..2ef2f91 100644
--- a/app/operations/gimpoperationsoftlightmode.c
+++ b/app/operations/gimpoperationsoftlightmode.c
@@ -88,53 +88,55 @@ gimp_operation_softlight_mode_process (GeglOperation       *operation,
                                        const GeglRectangle *roi,
                                        gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint b;
-      gfloat comp_alpha, new_alpha, ratio;
+      gfloat comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gfloat ratio = comp_alpha / new_alpha;
+          gint   b;
 
           for (b = RED; b < ALPHA; b++)
             {
               gfloat multiply = in[b] * layer[b];
-              gfloat screen = 1 - (1 - in[b]) * (1 - layer[b]);
-              gfloat comp = (1 - in[b]) * multiply + in[b] * screen;
+              gfloat screen = 1.0 - (1.0 - in[b]) * (1.0 - layer[b]);
+              gfloat comp = (1.0 - in[b]) * multiply + in[b] * screen;
 
-              out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          out[ALPHA] = in[ALPHA];
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask ++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationsubtractmode.c b/app/operations/gimpoperationsubtractmode.c
index a1de134..a11e214 100644
--- a/app/operations/gimpoperationsubtractmode.c
+++ b/app/operations/gimpoperationsubtractmode.c
@@ -88,53 +88,54 @@ gimp_operation_subtract_mode_process (GeglOperation       *operation,
                                       const GeglRectangle *roi,
                                       gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint b;
-      gfloat comp_alpha, new_alpha, ratio;
+      gfloat comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      if (mask)
-        comp_alpha *= (*mask);
-
-      new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio = comp_alpha / new_alpha;
+          gint   b;
+          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) + 0.0001;
+              out[b] = comp * ratio + in[b] * (1.0 - ratio);
             }
-
-          out[ALPHA] = in[ALPHA];
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;
diff --git a/app/operations/gimpoperationvaluemode.c b/app/operations/gimpoperationvaluemode.c
index c4eb389..8d5cb64 100644
--- a/app/operations/gimpoperationvaluemode.c
+++ b/app/operations/gimpoperationvaluemode.c
@@ -92,30 +92,30 @@ gimp_operation_value_mode_process (GeglOperation       *operation,
                                    const GeglRectangle *roi,
                                    gint                 level)
 {
-  GimpOperationPointLayerMode *point   = GIMP_OPERATION_POINT_LAYER_MODE (operation);
-  gfloat                       opacity = point->opacity;
-  gfloat                      *in      = in_buf;
-  gfloat                      *layer   = aux_buf;
-  gfloat                      *mask    = aux2_buf;
-  gfloat                      *out     = out_buf;
+  gdouble        opacity  = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity;
+  gfloat        *in       = in_buf;
+  gfloat        *layer    = aux_buf;
+  gfloat        *mask     = aux2_buf;
+  gfloat        *out      = out_buf;
+  const gboolean has_mask = mask != NULL;
 
   while (samples--)
     {
-      gint    b;
       GimpHSV layer_hsv, out_hsv;
-      GimpRGB layer_rgb  = {layer[0], layer[1], layer[2]};
-      GimpRGB out_rgb    = {in[0], in[1], in[2]};
-      gfloat comp_alpha, new_alpha, ratio;
+      GimpRGB layer_rgb = {layer[0], layer[1], layer[2]};
+      GimpRGB out_rgb   = {in[0], in[1], in[2]};
+      gfloat  comp_alpha, new_alpha;
 
       comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
-      if (mask)
-        comp_alpha *= (*mask);
+      if (has_mask)
+        comp_alpha *= *mask;
 
-      new_alpha  = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+      new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha;
 
       if (comp_alpha && new_alpha)
         {
-          ratio      = comp_alpha / new_alpha;
+          gint   b;
+          gfloat ratio = comp_alpha / new_alpha;
 
           gimp_rgb_to_hsv (&layer_rgb, &layer_hsv);
           gimp_rgb_to_hsv (&out_rgb, &out_hsv);
@@ -126,25 +126,30 @@ gimp_operation_value_mode_process (GeglOperation       *operation,
           out[0] = out_rgb.r;
           out[1] = out_rgb.g;
           out[2] = out_rgb.b;
-          out[3] = in[3];
 
           for (b = RED; b < ALPHA; b++)
-            out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+            {
+              out[b] = out[b] * ratio + in[b] * (1.0 - ratio);
+            }
         }
       else
         {
-          for (b = RED; b <= ALPHA; b++)
+          gint b;
+
+          for (b = RED; b < ALPHA; b++)
             {
               out[b] = in[b];
             }
         }
 
+      out[ALPHA] = in[ALPHA];
+
       in    += 4;
       layer += 4;
       out   += 4;
 
-      if (mask)
-        mask += 1;
+      if (has_mask)
+        mask++;
     }
 
   return TRUE;



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