gimp r27502 - in trunk: . app/gegl app/paint-funcs



Author: martinn
Date: Fri Oct 31 21:02:26 2008
New Revision: 27502
URL: http://svn.gnome.org/viewvc/gimp?rev=27502&view=rev

Log:
* app/gegl/gimpoperationpointlayermode.c
(gimp_operation_point_layer_mode_process): Implemented Erase, Anti
Erase, Color Erase and Replace. These are not normal layer modes
and handle alpha in their own way. In addition to this, the
behavior of Replace doesn't map very well to GEGL which uses
infinite sized "layers".

Completely works the same:
 o Erase
 o Anti Erase
 o Color Erase

Works different but similar:
 o Replace

* app/paint-funcs/paint-funcs.[ch]: Expose
paint_funcs_color_erase_helper() so it can be used in the
GimpOperationPointLayerMode implementation. Once the migration is
complete this function can be moved entirely to the op and be
tailored to work on premultiplied data.


Modified:
   trunk/ChangeLog
   trunk/app/gegl/gimpoperationpointlayermode.c
   trunk/app/paint-funcs/paint-funcs.c
   trunk/app/paint-funcs/paint-funcs.h

Modified: trunk/app/gegl/gimpoperationpointlayermode.c
==============================================================================
--- trunk/app/gegl/gimpoperationpointlayermode.c	(original)
+++ trunk/app/gegl/gimpoperationpointlayermode.c	Fri Oct 31 21:02:26 2008
@@ -28,6 +28,8 @@
 
 #include "gegl-types.h"
 
+#include "paint-funcs/paint-funcs.h"
+
 #include "gimpoperationpointlayermode.h"
 
 
@@ -270,6 +272,32 @@
   new[B] = newRGB.b;
 }
 
+static void
+gimp_operation_point_layer_mode_get_color_erase_color (const gfloat *in,
+                                                       const gfloat *lay,
+                                                       gfloat       *out)
+{
+  GimpRGB inRGB;
+  GimpRGB layRGB;
+
+  if (inA <= 0.0)
+    gimp_rgba_set (&inRGB, 0.0, 0.0, 0.0, inA);
+  else
+    gimp_rgba_set (&inRGB, in[R] / inA, in[G] / inA, in[B] / inA, inA);
+
+  if (layA <= 0.0)
+    gimp_rgba_set (&layRGB, 0.0, 0.0, 0.0, layA);
+  else
+    gimp_rgba_set (&layRGB, lay[R] / layA, lay[G] / layA, lay[B] / layA, layA);
+
+  paint_funcs_color_erase_helper (&inRGB, &layRGB);
+
+  out[A] = inRGB.a;
+  out[R] = inRGB.r * out[A];
+  out[G] = inRGB.g * out[A];
+  out[B] = inRGB.b * out[A];
+}
+
 static gboolean
 gimp_operation_point_layer_mode_process (GeglOperation       *operation,
                                          void                *in_buf,
@@ -296,6 +324,77 @@
     {
       switch (blend_mode)
         {
+        case GIMP_ERASE_MODE:
+        case GIMP_ANTI_ERASE_MODE:
+        case GIMP_COLOR_ERASE_MODE:
+        case GIMP_REPLACE_MODE:
+        case GIMP_DISSOLVE_MODE:
+          /* These modes handle alpha themselves */
+          break;
+
+        default:
+          /* Porter-Duff model for the rest */
+          outA = layA + inA - layA * inA;
+        }
+
+      switch (blend_mode)
+        {
+        case GIMP_ERASE_MODE:
+          /* Eraser mode */
+          outA = inA - inA * layA;
+          if (inA <= 0.0)
+            EACH_CHANNEL (
+            outC = 0.0)
+          else
+            EACH_CHANNEL (
+            outC = (inC / inA) * outA);
+          break;
+
+        case GIMP_ANTI_ERASE_MODE:
+          /* Eraser mode */
+          outA = inA + (1 - inA) * layA;
+          if (inA <= 0.0)
+            EACH_CHANNEL (
+            outC = 0.0)
+          else
+            EACH_CHANNEL (
+            outC = inC / inA * outA);
+          break;
+
+        case GIMP_COLOR_ERASE_MODE:
+          /* Paint mode */
+          gimp_operation_point_layer_mode_get_color_erase_color (in, lay, out);
+          break;
+
+        case GIMP_REPLACE_MODE:
+          /* Filter fade mode */
+          outA = layA;
+          EACH_CHANNEL(
+          outC = layC);
+          break;
+
+        case GIMP_DISSOLVE_MODE:
+          /* We need a deterministic result from Dissolve so let the
+           * seed depend on the pixel position (modulo 1024)
+           */
+          g_rand_set_seed (rand,
+                           ((roi->x + sample - (sample / roi->width) * roi->width) % 1024) *
+                           ((roi->y + sample / roi->width)                         % 1024));
+
+          if (layA * G_MAXUINT32 >= g_rand_int (rand))
+            {
+              outA = 1.0;
+              EACH_CHANNEL (
+              outC = layC / layA);
+            }
+          else
+            {
+              outA = inA;
+              EACH_CHANNEL (
+              outC = inC);
+            }
+          break;
+
         case GIMP_NORMAL_MODE:
           /* Porter-Duff A over B */
           EACH_CHANNEL (
@@ -497,47 +596,11 @@
           outC = newC * layA * inA + layC * (1 - inA) + inC * (1 - layA));
           break;
 
-        case GIMP_ERASE_MODE:
-        case GIMP_ANTI_ERASE_MODE:
-        case GIMP_COLOR_ERASE_MODE:
-        case GIMP_REPLACE_MODE:
-          /* Icky eraser and paint modes */
-          break;
-
-        case GIMP_DISSOLVE_MODE:
-          /* We need a deterministic result from Dissolve so let the
-           * seed depend on the pixel position (modulo 1024)
-           */
-          g_rand_set_seed (rand,
-                           ((roi->x + sample - (sample / roi->width) * roi->width) % 1024) *
-                           ((roi->y + sample / roi->width)                         % 1024));
-
-          if (layA * G_MAXUINT32 >= g_rand_int (rand))
-            {
-              EACH_CHANNEL(
-              outC = layC / layA);
-
-              /* Use general outA calculation */
-              layA = 1.0;
-            }
-          else
-            {
-              EACH_CHANNEL(
-              outC = inC);
-
-              /* Use general outA calculation */
-              layA = 0.0;
-            }
-          break;
-
         default:
           g_error ("Unknown layer mode");
           break;
         }
 
-      /* Alpha is treated the same */
-      outA = layA + inA - layA * inA;
-
       in  += 4;
       lay += 4;
       out += 4;

Modified: trunk/app/paint-funcs/paint-funcs.c
==============================================================================
--- trunk/app/paint-funcs/paint-funcs.c	(original)
+++ trunk/app/paint-funcs/paint-funcs.c	Fri Oct 31 21:02:26 2008
@@ -1599,9 +1599,9 @@
 }
 
 
-static inline void
-color_erase_helper (GimpRGB       *src,
-                    const GimpRGB *color)
+void
+paint_funcs_color_erase_helper (GimpRGB       *src,
+                                const GimpRGB *color)
 {
   GimpRGB alpha;
 
@@ -1692,7 +1692,7 @@
           gimp_rgba_set_uchar (&bgcolor,
                                src2[0], src2[0], src2[0], src2_alpha);
 
-          color_erase_helper (&color, &bgcolor);
+          paint_funcs_color_erase_helper (&color, &bgcolor);
 
           gimp_rgba_get_uchar (&color, dest, NULL, NULL, dest + 1);
           break;
@@ -1706,7 +1706,7 @@
           gimp_rgba_set_uchar (&bgcolor,
                                src2[0], src2[1], src2[2], src2_alpha);
 
-          color_erase_helper (&color, &bgcolor);
+          paint_funcs_color_erase_helper (&color, &bgcolor);
 
           gimp_rgba_get_uchar (&color, dest, dest + 1, dest + 2, dest + 3);
           break;

Modified: trunk/app/paint-funcs/paint-funcs.h
==============================================================================
--- trunk/app/paint-funcs/paint-funcs.h	(original)
+++ trunk/app/paint-funcs/paint-funcs.h	Fri Oct 31 21:02:26 2008
@@ -312,6 +312,10 @@
                                                    guint         length,
                                                    guint         bytes);
 
+void  paint_funcs_color_erase_helper      (GimpRGB       *src,
+                                           const GimpRGB *color);
+
+
 /*  extract information from intensity pixels based on
  *  a mask.
  */



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