[gegl] replace the ripple op from Sasu Robert by a cleaner version



commit fb0fff2ed554e0a23f5821b5fd503cb0711c0168
Author: Michael Murà <batolettre gmail com>
Date:   Sat Sep 3 16:27:51 2011 +0200

    replace the ripple op from Sasu Robert by a cleaner version

 operations/common/ripple.c   |  142 -------------
 operations/workshop/ripple.c |  452 ++++++------------------------------------
 2 files changed, 56 insertions(+), 538 deletions(-)
---
diff --git a/operations/workshop/ripple.c b/operations/workshop/ripple.c
index 4413e2d..86ea00f 100644
--- a/operations/workshop/ripple.c
+++ b/operations/workshop/ripple.c
@@ -13,8 +13,10 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
  *
- * Copyright (C) 1997 Brian Degenhardt <bdegenha ucsd edu>
- * Copyright (C) 2011 Robert Sasu <sasu robert gmail com>
+ * Copyright 2011 Michael Murà <batolettre gmail com>
+ * Copyright 2011 Robert Sasu <sasu robert gmail com>
+ * Copyright 2011 Hans Lo <hansshulo gmail com>
+ * Copyright 1997 Brian Degenhardt <bdegenha ucsd edu>
  */
 
 #include "config.h"
@@ -22,28 +24,17 @@
 
 #ifdef GEGL_CHANT_PROPERTIES
 
-gegl_chant_boolean (antialias,   _("Antialiasing"), FALSE,
-                    _("Antialiasing"))
-gegl_chant_boolean (tile, _("Retain tilebility"), FALSE,
-                    _("Retain tilability"))
-gegl_chant_string (orientation, _("Orientation"), "horizontal",
-                   _("Type of orientation to choose."
-                     "Choices are horizontal, vertical."
-                     "Default is horizontal"))
-gegl_chant_string (wave, _("Wave type"), "sine",
-                   _("Type of wave to choose."
-                     "Choices are sine, sawtooth."
-                     "Default is sine"))
-gegl_chant_string (background, _("Edges"), "smear",
-                   _("Type of edges to choose."
-                     "Choices are wrap, smear, blank."
-                     "Default is smear"))
-gegl_chant_int (amplitude, _("Amplitude"), 0, 200, 50,
-                _("Amplitude of ripple"))
-gegl_chant_int (period, _("Period"), 0, 200, 50,
-                _("Period of ripple"))
-gegl_chant_int (phi, _("Phase Shift"), 0, 360, 0,
-                _("As proportion of pi"))
+gegl_chant_double (amplitude, _("Amplitude"), 0.0, 1000.0, 25.0,
+                   _("Amplitude of the ripple"))
+
+gegl_chant_double (period, _("Period"), 0.0, 1000.0, 200.0,
+                   _("Period of the ripple"))
+
+gegl_chant_double (phi, _("Phase shift"), -1.0, 1.0, 0.0,
+                   _("Phase shift"))
+
+gegl_chant_double (angle, _("Angle"), -180.0, 180.0, 0.0,
+                   _("Angle in degree"))
 
 #else
 
@@ -54,37 +45,6 @@ gegl_chant_int (phi, _("Phase Shift"), 0, 360, 0,
 #include <stdio.h>
 #include <math.h>
 
-#define SCALE_WIDTH     200
-#define TILE_CACHE_SIZE  16
-
-typedef enum
-{
-  BACKGROUND_TYPE_WRAP,
-  BACKGROUND_TYPE_SMEAR,
-  BACKGROUND_TYPE_BLANK
-} BackgroundType;
-
-typedef enum
-  {
-    WAVE_TYPE_SINE,
-    WAVE_TYPE_SAWTOOTH,
-  } WaveType;
-
-typedef enum
-  {
-    ORIENTATION_TYPE_VERTICAL,
-    ORIENTATION_TYPE_HORIZONTAL
-  } OrientationType;
-
-typedef struct
-{
-  OrientationType orie_t;
-  WaveType        wave_t;
-  BackgroundType  back_t;
-  gint            per;
-} RippleContext;
-
-
 static void prepare (GeglOperation *operation)
 {
   GeglChantO              *o;
@@ -93,8 +53,10 @@ static void prepare (GeglOperation *operation)
   op_area = GEGL_OPERATION_AREA_FILTER (operation);
   o       = GEGL_CHANT_PROPERTIES (operation);
 
-  op_area->left   = op_area->bottom =
-    op_area->right  = op_area->top = o->amplitude + 2;
+  op_area->left   = o->amplitude;
+  op_area->right  = o->amplitude;
+  op_area->top    = o->amplitude;
+  op_area->bottom = o->amplitude;
 
   gegl_operation_set_format (operation, "input",
                              babl_format ("RGBA float"));
@@ -102,363 +64,64 @@ static void prepare (GeglOperation *operation)
                              babl_format ("RGBA float"));
 }
 
-static void
-average_two_pixels (gfloat  *dest,
-                    gfloat  *temp1,
-                    gfloat  *temp2,
-                    gdouble  rem)
+static gboolean
+process (GeglOperation       *operation,
+         GeglBuffer          *input,
+         GeglBuffer          *output,
+         const GeglRectangle *result)
 {
-  gfloat x0, x1;
-  gfloat alpha;
-  gint   i;
-
-  x0 = temp1[3] * (1.0 - rem);
-  x1 = temp2[3] * rem;
+  GeglChantO *o                    = GEGL_CHANT_PROPERTIES (operation);
 
-  alpha = x0 + x1;
+  gint x = result->x; /* initial x                   */
+  gint y = result->y; /*           and y coordinates */
 
-  for (i=0;i<3;i++)
-    dest[i] = (x0 * temp1[i] + x1 * temp2[i]) / alpha;
+  gfloat *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof(gfloat));
 
-  dest[3] = alpha;
-}
+  gfloat *out_pixel = dst_buf;
 
+  GeglSamplerType  sampler_type = gegl_sampler_type_from_string ("cubic");
+  GeglSampler     *sampler = gegl_buffer_sampler_new (input,
+                                                      babl_format ("RGBA float"),
+                                                      sampler_type);
 
-static gdouble
-displace_amount (gint        location,
-                 GeglChantO *o,
-                 WaveType    wave_t)
-{
-  const gdouble phi = o->phi / 360.0;
-  gdouble       lambda;
+  gint n_pixels = result->width * result->height;
 
-  switch (wave_t)
+  while (n_pixels--)
     {
-    case WAVE_TYPE_SINE:
-      return (o->amplitude *
-              sin (2 * G_PI * (location / (gdouble) o->period - phi)));
-
-    case WAVE_TYPE_SAWTOOTH:
-      lambda = location % o->period - phi * o->period;
-      if (lambda < 0)
-        lambda += o->period;
-      return (o->amplitude * (fabs (((lambda / o->period) * 4) - 2) - 1));
-    }
+      gdouble angle_rad = o->angle / 180.0 * G_PI;
 
-  return 0.0;
-}
+      gdouble nx = x * cos (angle_rad) + y * sin (angle_rad);
 
-static void
-ripple_horizontal (gfloat              *src_buf,
-                   gfloat              *dst_buf,
-                   const GeglRectangle *result,
-                   const GeglRectangle *extended,
-                   const GeglRectangle *image,
-                   gint                 y,
-                   RippleContext        rip,
-                   GeglChantO          *o,
-                   GeglBuffer          *input)
-{
-  gint  x;
-  gint  src_offset, dst_offset;
-  Babl *format = babl_format ("RGBA float");
+      gdouble shift = o->amplitude * sin (2.0 * G_PI * nx / o->period + 2.0 * G_PI * o->phi);
 
-  dst_offset = (y - result->y) * result->width * 4;
+      gdouble coordsx = x + shift * sin (angle_rad);
+      gdouble coordsy = y + shift * cos (angle_rad);
 
-  for (x = result->x; x < result->x + result->width; x++)
-    {
-      gdouble shift = x + displace_amount(y, o, rip.wave_t);
-      gint    xi    = floor (shift);
-      gint    xi_a  = xi + 1;
-      gdouble rem   = shift - xi;
-      gint    i;
-      gfloat  dest[4];
-
-      if (rip.back_t == BACKGROUND_TYPE_WRAP)
-        {
-          shift = fmod (shift, image->width);
-          while (shift < 0.0)
-            shift += image->width;
+      gegl_sampler_get (sampler,
+                        coordsx,
+                        coordsy,
+                        NULL,
+                        out_pixel);
 
-          xi = (xi % image->width);
-          while (xi < 0)
-            xi += image->width;
-
-          xi_a = (xi+1) % image->width;
-        }
-      else if (rip.back_t == BACKGROUND_TYPE_SMEAR)
-        {
-          shift = CLAMP (shift, 0, image->width - 1);
-          xi    = CLAMP (xi, 0 ,image->width - 1);
-          xi_a  = CLAMP (xi_a, 0, image->width - 1);
-        }
+      out_pixel += 4;
 
-      if (o->antialias)
+      /* update x and y coordinates */
+      x++;
+      if (x>=result->x + result->width)
         {
-          gfloat temp1[4], temp2[4];
-          if (xi >= 0 && xi < image->width)
-            {
-              if (xi >= extended->x && xi < extended->x + extended->width)
-                {
-                  src_offset = (y - extended->y) * extended->width * 4 +
-                    (xi - extended->x) * 4;
-                  for (i=0;i<4;i++)
-                    temp1[i] = src_buf[src_offset++];
-                }
-              else gegl_buffer_sample (input, xi, y, NULL, temp1, format,
-                                       GEGL_INTERPOLATION_NEAREST);
-            }
-          else temp1[0] = temp1[1] = temp2[2] = temp1[3] = 0.0;
-
-          if (xi_a >= 0 && xi_a < image->width)
-            {
-              if (xi_a >= extended->x && xi_a < extended->x + extended->width)
-                {
-                  src_offset = (y - extended->y) * extended->width * 4 +
-                    (xi_a - extended->x) * 4;
-                  for (i=0;i<4;i++)
-                    temp2[i] = src_buf[src_offset++];
-                }
-              else gegl_buffer_sample (input, xi_a, y, NULL, temp2, format,
-                                       GEGL_INTERPOLATION_NEAREST);
-            }
-          else temp2[0] = temp2[1] = temp2[2] = temp2[3] = 0.0;
-
-          average_two_pixels (dest, temp1, temp2, rem);
+          x=result->x;
+          y++;
         }
-      else
-        {
-          if (xi >= 0 && xi < image->width)
-            {
-              if (xi >= extended->x && xi < extended->x + extended->width)
-                {
-                  src_offset = (y - extended->y) * extended->width * 4 +
-                    (xi - extended->x) * 4;
-                  for (i=0;i<4;i++)
-                    dest[i] = src_buf[src_offset++];
-                }
-              else gegl_buffer_sample (input, xi, y, NULL, dest, format,
-                                       GEGL_INTERPOLATION_NEAREST);
-            }
-          else dest[0] = dest[1] = dest[2] = dest[3] = 0.0;
-        }
-
-      for (i=0;i<4;i++)
-        dst_buf[dst_offset++] = dest[i];
-
     }
-}
 
-static void
-ripple_vertical   (gfloat              *src_buf,
-                   gfloat              *dst_buf,
-                   const GeglRectangle *result,
-                   const GeglRectangle *extended,
-                   const GeglRectangle *image,
-                   gint                 y,
-                   RippleContext        rip,
-                   GeglChantO          *o,
-                   GeglBuffer          *input)
-{
-  gint x;
-  gint src_offset, dst_offset;
-  Babl *format = babl_format ("RGBA float");
-  dst_offset = (y - result->y) * result->width * 4;
+  gegl_buffer_set (output, result, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
+  g_slice_free1 (result->width * result->height * 4 * sizeof(gfloat), dst_buf);
 
-  for (x = result->x; x < result->x + result->width; x++)
-    {
-      gdouble shift = y + displace_amount(x, o, rip.wave_t);
-      gint    xi    = floor (shift);
-      gint    xi_a  = xi + 1;
-      gdouble rem   = shift - xi;
-      gint    i;
-      gfloat  dest[4];
-
-      if (rip.back_t == BACKGROUND_TYPE_WRAP)
-        {
-          shift = fmod (shift, image->height);
-          while (shift < 0.0)
-            shift += image->height;
-
-          xi = (xi % image->height);
-          while (xi < 0)
-            xi += image->height;
-
-          xi_a = (xi+1) % image->height;
-        }
-      else if (rip.back_t == BACKGROUND_TYPE_SMEAR)
-        {
-          shift = CLAMP (shift, 0, image->height - 1);
-          xi    = CLAMP (xi, 0 ,image->height - 1);
-          xi_a  = CLAMP (xi_a, 0, image->height - 1);
-        }
-
-      if (o->antialias)
-        {
-          gfloat temp1[4], temp2[4];
-          if (xi >= 0 && xi < image->width)
-            {
-              if (xi >= extended->y && xi < extended->y + extended->height)
-                {
-                  src_offset = (xi - extended->y) * extended->width * 4 +
-                    (x - extended->x) * 4;
-                  for (i=0;i<4;i++)
-                    temp1[i] = src_buf[src_offset++];
-                }
-              else gegl_buffer_sample (input, x, xi, NULL, temp1, format,
-                                       GEGL_INTERPOLATION_NEAREST);
-            }
-          else temp1[0] = temp1[1] = temp2[2] = temp1[3] = 0.0;
-
-          if (xi_a >= 0 && xi_a < image->width)
-            {
-              if (xi_a >= extended->y && xi_a < extended->y + extended->height)
-                {
-                  src_offset = (xi_a - extended->y) * extended->width * 4 +
-                    (x - extended->x) * 4;
-                  for (i=0;i<4;i++)
-                    temp2[i] = src_buf[src_offset++];
-                }
-              else gegl_buffer_sample (input, x, xi_a, NULL, temp2, format,
-                                       GEGL_INTERPOLATION_NEAREST);
-            }
-          else temp2[0] = temp2[1] = temp2[2] = temp2[3] = 0.0;
-
-          average_two_pixels (dest, temp1, temp2, rem);
-        }
-      else
-        {
-          if (xi >= 0 && xi < image->width)
-            {
-              if (xi >= extended->y && xi < extended->y + extended->height)
-                {
-                  src_offset = (xi - extended->y) * extended->width * 4 +
-                    (x - extended->x) * 4;
-                  for (i=0;i<4;i++)
-                    dest[i] = src_buf[src_offset++];
-                }
-              else gegl_buffer_sample (input, x, xi, NULL, dest, format,
-                                       GEGL_INTERPOLATION_NEAREST);
-            }
-          else dest[0] = dest[1] = dest[2] = dest[3] = 0.0;
-        }
-
-      for (i=0;i<4;i++)
-        dst_buf[dst_offset++] = dest[i];
-
-    }
-}
-
-static GeglRectangle
-get_effective_area (GeglOperation *operation)
-{
-  GeglRectangle  result = {0,0,0,0};
-  GeglRectangle *in_rect = gegl_operation_source_get_bounding_box (operation, "input");
-
-  gegl_rectangle_copy(&result, in_rect);
-
-  return result;
-}
-
-static gboolean
-process (GeglOperation       *operation,
-         GeglBuffer          *input,
-         GeglBuffer          *output,
-         const GeglRectangle *result)
-{
-  GeglChantO              *o            = GEGL_CHANT_PROPERTIES (operation);
-  GeglOperationAreaFilter *op_area      = GEGL_OPERATION_AREA_FILTER (operation);
-  GeglRectangle            boundary     = get_effective_area (operation);
-  GeglRectangle            extended;
-  Babl                    *format       = babl_format ("RGBA float");
-  RippleContext            rip;
-
-  gfloat *dst_buf, *src_buf;
-  gint    y;
-
-  extended.x      = CLAMP (result->x - op_area->left, boundary.x, boundary.x +
-                           boundary.width);
-  extended.width  = CLAMP (result->width + op_area->left + op_area->right, 0,
-                           boundary.width);
-  extended.y      = CLAMP (result->y - op_area->top, boundary.y, boundary.y +
-                           boundary.width);
-  extended.height = CLAMP (result->height + op_area->top + op_area->bottom, 0,
-                           boundary.height);
-
-  dst_buf = g_new0 (gfloat, result->width * result->height * 4);
-  src_buf = g_new0 (gfloat, extended.width * extended.height * 4);
-
-  rip.per = o->period;
-
-  rip.wave_t = WAVE_TYPE_SINE;
-  if (!strcmp (o->wave, "sine"))
-    rip.wave_t = WAVE_TYPE_SINE;
-  else if (!strcmp(o->wave, "sawtooth"))
-    rip.wave_t = WAVE_TYPE_SAWTOOTH;
-
-  rip.back_t = BACKGROUND_TYPE_WRAP;
-  if (!strcmp (o->background, "wrap"))
-    rip.back_t = BACKGROUND_TYPE_WRAP;
-  else if (!strcmp (o->background, "smear"))
-    rip.back_t = BACKGROUND_TYPE_SMEAR;
-  else if (!strcmp (o->background, "blank"))
-    rip.back_t = BACKGROUND_TYPE_BLANK;
-
-  rip.orie_t = ORIENTATION_TYPE_HORIZONTAL;
-  if (!strcmp (o->orientation, "horizontal"))
-    rip.orie_t = ORIENTATION_TYPE_HORIZONTAL;
-  else if (!strcmp(o->orientation, "vertical"))
-    rip.orie_t = ORIENTATION_TYPE_VERTICAL;
-
-  if (o->tile)
-    {
-      rip.back_t = BACKGROUND_TYPE_WRAP;
-      rip.per    = (boundary.width / (boundary.width / rip.per) *
-                    (rip.orie_t == ORIENTATION_TYPE_HORIZONTAL) +
-                    boundary.height / (boundary.height / rip.per) *
-                    (rip.orie_t == ORIENTATION_TYPE_VERTICAL));
-    }
-
-
-  gegl_buffer_get (input, 1.0, &extended, format,
-                   src_buf, GEGL_AUTO_ROWSTRIDE);
-
-  for (y = result->y; y < result->y + result->height; y++)
-    if (rip.orie_t == ORIENTATION_TYPE_HORIZONTAL)
-      ripple_horizontal (src_buf, dst_buf, result, &extended, &boundary, y,
-                         rip, o, input);
-    else if (rip.orie_t == ORIENTATION_TYPE_VERTICAL)
-      ripple_vertical   (src_buf, dst_buf, result, &extended, &boundary, y,
-                         rip, o, input);
-
-  gegl_buffer_set (output, result, format, dst_buf, GEGL_AUTO_ROWSTRIDE);
-
-  g_free (dst_buf);
-  g_free (src_buf);
+  g_object_unref (sampler);
 
   return  TRUE;
 }
 
-static GeglRectangle
-get_bounding_box (GeglOperation *operation)
-{
-  GeglRectangle  result = {0,0,0,0};
-  GeglRectangle *in_rect;
-
-  in_rect = gegl_operation_source_get_bounding_box (operation, "input");
-  if (!in_rect)
-    return result;
-
-  return *in_rect;
-}
-
-static GeglRectangle
-get_required_for_output (GeglOperation       *operation,
-                         const gchar         *input_pad,
-                         const GeglRectangle *roi)
-{
-  return get_bounding_box (operation);
-}
 
 static void
 gegl_chant_class_init (GeglChantClass *klass)
@@ -471,13 +134,10 @@ gegl_chant_class_init (GeglChantClass *klass)
 
   filter_class->process    = process;
   operation_class->prepare = prepare;
-  operation_class->get_bounding_box        = get_bounding_box;
-  operation_class->get_required_for_output = get_required_for_output;
-
 
-  operation_class->categories  = "distorts";
+  operation_class->categories  = "distort";
   operation_class->name        = "gegl:ripple";
-  operation_class->description = _("Performs ripple on the image.");
+  operation_class->description = _("Transform the buffer with a ripple pattern");
 }
 
 #endif



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