[gegl] operations: illusion: change pixels access mechanism



commit c5f2167ba32d29cb0d6cdc18feb7794fc6f235af
Author: Thomas Manni <thomas manni free fr>
Date:   Mon Dec 8 20:05:58 2014 +0100

    operations: illusion: change pixels access mechanism
    
    Remove linear buffers and use GeglSampler for input buffer and GeglIterator for output buffer.

 operations/common/illusion.c |  151 ++++++++++++++++++++++-------------------
 1 files changed, 81 insertions(+), 70 deletions(-)
---
diff --git a/operations/common/illusion.c b/operations/common/illusion.c
index ff455e7..624bde5 100644
--- a/operations/common/illusion.c
+++ b/operations/common/illusion.c
@@ -94,19 +94,20 @@ process (GeglOperation       *operation,
          gint                 level)
 {
   GeglProperties     *o = GEGL_PROPERTIES (operation);
-
-  gfloat   *src;
-  gfloat   *dst;
-  gint     x, y, xx, yy, b;
-  gint     width, height, components;
-  gdouble  radius, cx, cy, angle;
-  gdouble  center_x;
-  gdouble  center_y;
-  gdouble  scale;
-  gdouble  offset;
-  glong    idx1, idx2;
-  gboolean has_alpha;
-  gfloat   alpha, alpha1, alpha2;
+  GeglBufferIterator *iter;
+  GeglSampler        *sampler;
+
+  gint         x, y, xx, yy, b;
+  gint         width, height, components;
+  gdouble      radius, cx, cy, angle;
+  gdouble      center_x;
+  gdouble      center_y;
+  gdouble      scale;
+  gdouble      offset;
+  gboolean     has_alpha;
+  gfloat       alpha, alpha1, alpha2;
+  gfloat      *in_pixel1;
+  gfloat      *in_pixel2;
 
   const Babl *format = gegl_operation_get_format (operation, "output");
   has_alpha  = babl_format_has_alpha (format);
@@ -116,71 +117,81 @@ process (GeglOperation       *operation,
   else
     components = 3;
 
-  width = result->width;
-  height = result->height;
+  in_pixel1 = g_new (float, components);
+  in_pixel2 = g_new (float, components);
 
-  src = g_new0 (gfloat, width * height * components);
-  dst = g_new0 (gfloat, width * height * components);
+  iter = gegl_buffer_iterator_new (output, result, level, format,
+                                   GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
 
-  gegl_buffer_get (input, result, 1.0, format, src, GEGL_AUTO_ROWSTRIDE,
-                   GEGL_ABYSS_CLAMP);
+  sampler = gegl_buffer_sampler_new_at_level (input, format,
+                                              GEGL_SAMPLER_NEAREST, level);
+
+  width = result->width;
+  height = result->height;
 
   center_x = width / 2.0;
   center_y = height / 2.0;
   scale = sqrt (width * width + height * height) / 2;
   offset = (gint) (scale / 2);
 
-  for (y = 0; y < height; y++)
-    for (x = 0; x < width; x++)
-      {
-        cy = ((gdouble) y - center_y) / scale;
-        cx = ((gdouble) x - center_x) / scale;
-
-        angle = floor (atan2 (cy, cx) * o->division / G_PI_2) *
-                      G_PI_2 / o->division + (G_PI / o->division);
-        radius = sqrt ((gdouble) (cx * cx + cy * cy));
-
-        if (o->illusion_type == GEGL_ILLUSION_TYPE_1)
-          {
-            xx = x - offset * cos (angle);
-            yy = y - offset * sin (angle);
-          }
-        else                          /* GEGL_ILLUSION_TYPE_2 */
-          {
-            xx = x - offset * sin (angle);
-            yy = y - offset * cos (angle);
-          }
-
-        xx = CLAMP (xx, 0, width - 1);
-        yy = CLAMP (yy, 0, height - 1);
-
-        idx1 = (y * width + x) * components;
-        idx2 = (yy * width + xx) * components;
-
-        if (has_alpha)
-          {
-            alpha1 = src[idx1 + 3];
-            alpha2 = src[idx2 + 3];
-            alpha  = (1 - radius) * alpha1 + radius * alpha2;
-
-            if ((dst[idx1 + 3] = (alpha / 2)))
-             {
-               for (b = 0; b < 3; b++)
-                 dst[idx1 + b] = ((1 - radius) * src[idx1 + b] * alpha1 +
-                                radius * src[idx2 + b] * alpha2) / alpha;
-             }
-          }
-        else
-          {
-            for (b = 0; b < 3; b++)
-              dst[idx1 + b] = (1 - radius) * src[idx1 + b] + radius * src[idx2 + b];
-          }
-        }
-
-  gegl_buffer_set (output, result, level, format, dst, GEGL_AUTO_ROWSTRIDE);
-
-  g_free (src);
-  g_free (dst);
+  while (gegl_buffer_iterator_next (iter))
+    {
+       gfloat  *out_pixel = iter->data[0];
+
+       for (y = iter->roi[0].y; y < iter->roi[0].y + iter->roi[0].height; ++y)
+         for (x = iter->roi[0].x; x < iter->roi[0].x + iter->roi[0].width; ++x)
+           {
+              cy = ((gdouble) y - center_y) / scale;
+              cx = ((gdouble) x - center_x) / scale;
+
+              angle = floor (atan2 (cy, cx) * o->division / G_PI_2) *
+                             G_PI_2 / o->division + (G_PI / o->division);
+              radius = sqrt ((gdouble) (cx * cx + cy * cy));
+
+              if (o->illusion_type == GEGL_ILLUSION_TYPE_1)
+                {
+                   xx = x - offset * cos (angle);
+                   yy = y - offset * sin (angle);
+                }
+              else                          /* GEGL_ILLUSION_TYPE_2 */
+                {
+                   xx = x - offset * sin (angle);
+                   yy = y - offset * cos (angle);
+                }
+
+                gegl_sampler_get (sampler, x, y, NULL,
+                                  in_pixel1, GEGL_ABYSS_CLAMP);
+
+                gegl_sampler_get (sampler, xx, yy, NULL,
+                                  in_pixel2, GEGL_ABYSS_CLAMP);
+
+                if (has_alpha)
+                  {
+                     alpha1 = in_pixel1[3];
+                     alpha2 = in_pixel2[3];
+                     alpha  = (1 - radius) * alpha1 + radius * alpha2;
+
+                     if ((out_pixel[3] = (alpha / 2)))
+                       {
+                         for (b = 0; b < 3; b++)
+                           out_pixel[b] = ((1 - radius) * in_pixel1[b] * alpha1 +
+                                           radius * in_pixel2[b] * alpha2) / alpha;
+                       }
+                  }
+                else
+                 {
+                   for (b = 0; b < 3; b++)
+                     out_pixel[b] = (1 - radius) * in_pixel1[b] + radius * in_pixel2[b];
+                 }
+
+                 out_pixel += components;
+           }
+    }
+
+  g_free (in_pixel1);
+  g_free (in_pixel2);
+
+  g_object_unref (sampler);
 
   return  TRUE;
 }


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