gegl r2489 - in trunk: . gegl/buffer



Author: ok
Date: Fri Jun 20 00:45:08 2008
New Revision: 2489
URL: http://svn.gnome.org/viewvc/gegl?rev=2489&view=rev

Log:
* gegl/buffer/gegl-sampler.[ch]: (gegl_sampler_get_ptr): added a
function used to prime a linear buffer with all needed samples for
interpolation.
For all the interpolators, removed unneded alpha multiplications
(we're interpolating on premultiplied pixels), also moved linear and
cubic to skip unneeded function calls in innerloop.
* gegl/buffer/gegl-sampler-cubic.c:
* gegl/buffer/gegl-sampler-lanczos.c:
* gegl/buffer/gegl-sampler-linear.c:
* gegl/buffer/gegl-sampler-nearest.c:


Modified:
   trunk/ChangeLog
   trunk/gegl/buffer/gegl-sampler-cubic.c
   trunk/gegl/buffer/gegl-sampler-lanczos.c
   trunk/gegl/buffer/gegl-sampler-linear.c
   trunk/gegl/buffer/gegl-sampler-nearest.c
   trunk/gegl/buffer/gegl-sampler.c
   trunk/gegl/buffer/gegl-sampler.h

Modified: trunk/gegl/buffer/gegl-sampler-cubic.c
==============================================================================
--- trunk/gegl/buffer/gegl-sampler-cubic.c	(original)
+++ trunk/gegl/buffer/gegl-sampler-cubic.c	Fri Jun 20 00:45:08 2008
@@ -123,12 +123,13 @@
 {
   GeglSamplerCubic *cubic = (GeglSamplerCubic*)(self);
   GeglRectangle     context_rect;
+  const gint        offsets[16]={-4-64*4, 4, 4, 4,
+                                (64-3)*4, 4, 4, 4,
+                                (64-3)*4, 4, 4, 4,
+                                (64-3)*4, 4, 4, 4};
   gfloat           *sampler_bptr;
   gfloat            factor;
-  gdouble           arecip;
-  gdouble           newval[4];
-  gfloat            abyss = 0.;
-  gfloat            dst[4];
+  gfloat            newval[4];
   gint              u,v;
   gint              dx,dy;
   gint              i;
@@ -137,40 +138,22 @@
   dx = (gint) x;
   dy = (gint) y;
   newval[0] = newval[1] = newval[2] = newval[3] = 0.;
-  for (v=dy+context_rect.y ; v < dy+context_rect.y+context_rect.height ; v++)
-    for (u=dx+context_rect.x ; u < dx+context_rect.x+context_rect.width  ; u++)
+  sampler_bptr = gegl_sampler_get_ptr (self, dx, dy);
+  for (v=dy+context_rect.y, i=0; v < dy+context_rect.y+context_rect.height ; v++)
+    for (u=dx+context_rect.x ; u < dx+context_rect.x+context_rect.width  ; u++, i++)
       {
-        sampler_bptr = gegl_sampler_get_from_buffer (self, u, v);
+        /*sampler_bptr = gegl_sampler_get_from_buffer (self, u, v);*/
+        sampler_bptr += offsets[i];
         factor     = cubicKernel (y - v, cubic->b, cubic->c) *
                      cubicKernel (x - u, cubic->b, cubic->c);
-        newval[0] += factor * sampler_bptr[0] * sampler_bptr[3];
-        newval[1] += factor * sampler_bptr[1] * sampler_bptr[3];
-        newval[2] += factor * sampler_bptr[2] * sampler_bptr[3];
+        newval[0] += factor * sampler_bptr[0];
+        newval[1] += factor * sampler_bptr[1];
+        newval[2] += factor * sampler_bptr[2];
         newval[3] += factor * sampler_bptr[3];
       }
-  if (newval[3] <= abyss)
-    {
-      arecip    = abyss;
-      newval[3] = abyss;
-    }
-  else if (newval[3] > G_MAXDOUBLE)
-    {
-      arecip    = 1.0 / newval[3];
-      newval[3] = G_MAXDOUBLE;
-    }
-  else
-    {
-      arecip = 1.0 / newval[3];
-    }
-
-  for ( i=0 ;  i < 3 ; i++ )
-    newval[i] *= arecip;
-  for ( i=0 ;  i < 4 ; i++ )
-    dst[i] = CLAMP (newval[i], 0, G_MAXDOUBLE);
-
 
   babl_process (babl_fish (self->interpolate_format, self->format),
-                dst, output, 1);
+                newval, output, 1);
 
 }
 
@@ -230,7 +213,9 @@
              gfloat c)
  {
   gfloat weight, x2, x3;
-  gfloat ax = (gfloat) fabs (x);
+  gfloat ax = x;
+  if (ax < 0.0)
+    ax *= -1.0;
 
   if (ax > 2) return 0;
 
@@ -247,6 +232,6 @@
              (-12 * b - 48 * c) * ax +
              (8 * b + 24 * c);
 
-  return weight * (1.0 / 6.0);
+  return weight / 6.0;
 }
 

Modified: trunk/gegl/buffer/gegl-sampler-lanczos.c
==============================================================================
--- trunk/gegl/buffer/gegl-sampler-lanczos.c	(original)
+++ trunk/gegl/buffer/gegl-sampler-lanczos.c	Fri Jun 20 00:45:08 2008
@@ -146,10 +146,8 @@
   GeglSamplerLanczos      *lanczos      = GEGL_SAMPLER_LANCZOS (self);
   GeglRectangle            context_rect = self->context_rect;
   gfloat                  *sampler_bptr;
-  gdouble                  x_sum, y_sum, arecip;
-  gdouble                  newval[4];
-
-  gfloat                   dst[4];
+  gdouble                  x_sum, y_sum;
+  gfloat                   newval[4] = {0.0, 0.0, 0.0, 0.0};
   gint                     i, j;
   gint                     spp    = lanczos->lanczos_spp;
   gint                     width  = lanczos->lanczos_width;
@@ -157,7 +155,7 @@
   gint                     dx,dy;
   gint                     u,v;
 
-  gdouble                  x_kernel[width2], /* 1-D kernels of Lanczos window coeffs */
+  gfloat                   x_kernel[width2], /* 1-D kernels of Lanczos window coeffs */
                            y_kernel[width2];
 
   self->interpolate_format = babl_format ("RaGaBaA float");
@@ -178,8 +176,6 @@
       x_kernel[i] /= x_sum;
       y_kernel[i] /= y_sum;
     }
-  arecip    = 0.0;
-  newval[0] = newval[1] = newval[2] = newval[3] = 0.0;
 
   dx = (gint) x;
   dy = (gint) y;
@@ -187,32 +183,14 @@
     for (u=dx+context_rect.x, i = 0; u < dx+context_rect.x+context_rect.width; i++, u++)
       {
          sampler_bptr = gegl_sampler_get_from_buffer (self, u, v);
-         newval[0] += y_kernel[j] * x_kernel[i] * sampler_bptr[0] * sampler_bptr[3];
-         newval[1] += y_kernel[j] * x_kernel[i] * sampler_bptr[1] * sampler_bptr[3];
-         newval[2] += y_kernel[j] * x_kernel[i] * sampler_bptr[2] * sampler_bptr[3];
+         newval[0] += y_kernel[j] * x_kernel[i] * sampler_bptr[0];
+         newval[1] += y_kernel[j] * x_kernel[i] * sampler_bptr[1];
+         newval[2] += y_kernel[j] * x_kernel[i] * sampler_bptr[2];
          newval[3] += y_kernel[j] * x_kernel[i] * sampler_bptr[3];
       }
-  if (newval[3] <= 0.0)
-    {
-      arecip    = 0.0;
-      newval[3] = 0;
-    }
-  else if (newval[3] > G_MAXDOUBLE)
-    {
-      arecip    = 1.0 / newval[3];
-      newval[3] = G_MAXDOUBLE;
-    }
-  else
-    {
-      arecip = 1.0 / newval[3];
-    }
-  for ( i=0 ;  i < 3 ; i++ )
-    newval[i] *= arecip;
-  for ( i=0 ;  i < 4 ; i++ )
-    dst[i] = CLAMP (newval[i], 0, G_MAXDOUBLE);
 
   babl_process (babl_fish (self->interpolate_format, self->format),
-                dst, output, 1);
+                newval, output, 1);
 }
 
 static void

Modified: trunk/gegl/buffer/gegl-sampler-linear.c
==============================================================================
--- trunk/gegl/buffer/gegl-sampler-linear.c	(original)
+++ trunk/gegl/buffer/gegl-sampler-linear.c	Fri Jun 20 00:45:08 2008
@@ -75,13 +75,12 @@
 {
   GeglRectangle      context_rect = self->context_rect;
   gfloat            *sampler_bptr;
-  gfloat             abyss = 0.;
-  gfloat             dst[4];
-  gdouble            arecip;
-  gdouble            newval[4];
-  gdouble            q[4];
-  gdouble            dx,dy;
-  gdouble            uf, vf;
+  const gint         offsets[4]={0,        4,
+                                 (64-1)*4, 4};
+  gfloat             newval[4] = {0.0, 0.0, 0.0, 0.0};
+  gfloat             q[4];
+  gfloat             dx,dy;
+  gfloat             uf, vf;
   gint               u,v;
   gint               i;
 
@@ -95,38 +94,22 @@
   q[3] = uf * vf;
   dx = (gint) x;
   dy = (gint) y;
-  newval[0] = newval[1] = newval[2] = newval[3] = 0.;
+
+  sampler_bptr = gegl_sampler_get_ptr (self, dx, dy);
+
+  /* FIXME: unroll this loop */
   for (i=0, v=dy+context_rect.y; v < dy+context_rect.height ; v++)
     for (u=dx+context_rect.x; u < dx+context_rect.width  ; u++, i++)
       {
-        sampler_bptr = gegl_sampler_get_from_buffer (self, u, v);
-        newval[0] += q[i] * sampler_bptr[0] * sampler_bptr[3];
-        newval[1] += q[i] * sampler_bptr[1] * sampler_bptr[3];
-        newval[2] += q[i] * sampler_bptr[2] * sampler_bptr[3];
+        sampler_bptr += offsets[i];
+        newval[0] += q[i] * sampler_bptr[0];
+        newval[1] += q[i] * sampler_bptr[1];
+        newval[2] += q[i] * sampler_bptr[2];
         newval[3] += q[i] * sampler_bptr[3];
       }
 
-  if (newval[3] <= abyss)
-    {
-      arecip    = abyss;
-      newval[3] = abyss;
-    }
-  else if (newval[3] > G_MAXDOUBLE)
-    {
-      arecip    = 1.0 / newval[3];
-      newval[3] = G_MAXDOUBLE;
-    }
-  else
-    {
-      arecip = 1.0 / newval[3];
-    }
-  for ( i=0 ;  i < 3 ; i++ )
-    newval[i] *= arecip;
-  for ( i=0 ;  i < 4 ; i++ )
-    dst[i] = CLAMP (newval[i], 0, G_MAXDOUBLE);
-
   babl_process (babl_fish (self->interpolate_format, self->format),
-                dst, output, 1);
+                newval, output, 1);
 }
 
 

Modified: trunk/gegl/buffer/gegl-sampler-nearest.c
==============================================================================
--- trunk/gegl/buffer/gegl-sampler-nearest.c	(original)
+++ trunk/gegl/buffer/gegl-sampler-nearest.c	Fri Jun 20 00:45:08 2008
@@ -59,7 +59,7 @@
 gegl_sampler_nearest_init (GeglSamplerNearest *self)
 {
    GEGL_SAMPLER (self)->context_rect = (GeglRectangle){0,0,1,1};
-   GEGL_SAMPLER (self)->interpolate_format = babl_format ("RaGaBaA float");
+   GEGL_SAMPLER (self)->interpolate_format = babl_format ("RGBA float");
 }
 
 void

Modified: trunk/gegl/buffer/gegl-sampler.c
==============================================================================
--- trunk/gegl/buffer/gegl-sampler.c	(original)
+++ trunk/gegl/buffer/gegl-sampler.c	Fri Jun 20 00:45:08 2008
@@ -185,6 +185,70 @@
   G_OBJECT_CLASS (gegl_sampler_parent_class)->dispose (gobject);
 }
 
+
+/* gets a pointer to the center pixel, within a buffer that has
+ * a rowstride of 64px * 16bpp
+ */
+gfloat *
+gegl_sampler_get_ptr (GeglSampler         *sampler,
+                      gint                 x,
+                      gint                 y)
+{
+   guchar        *buffer_ptr;
+   gint           dx;
+   gint           dy;
+   gint           bpp;
+   gint           sof;
+
+
+   bpp = sampler->interpolate_format->format.bytes_per_pixel;
+
+   if (sampler->sampler_buffer == NULL ||
+       x + sampler->context_rect.x < sampler->sampler_rectangle.x ||
+       y + sampler->context_rect.y < sampler->sampler_rectangle.y ||
+       x + sampler->context_rect.x + sampler->context_rect.width >= sampler->sampler_rectangle.x + sampler->sampler_rectangle.width ||
+       y + sampler->context_rect.y + sampler->context_rect.height >= sampler->sampler_rectangle.y + sampler->sampler_rectangle.height)
+     {
+       GeglRectangle  fetch_rectangle/* = sampler->context_rect*/;
+
+       fetch_rectangle.x = x + sampler->context_rect.x;
+       fetch_rectangle.y = y + sampler->context_rect.y;
+
+       /* we override the fetch rectangle needed by the sampler, hoping that
+        * the extra pixels we fetch comes in useful in subsequent requests,
+        * we assume that it is more likely that further access is to the right
+        * or down of our currently requested position.
+        */
+       fetch_rectangle.x -= 8;
+       fetch_rectangle.y -= 8;
+       fetch_rectangle.width = 64;
+       fetch_rectangle.height = 64;
+
+
+       if (sampler->sampler_buffer == NULL )
+         { /* we always request the same amount of pixels (64kb worth) */
+           sampler->sampler_buffer = g_malloc0 (fetch_rectangle.width *
+                                                fetch_rectangle.height *
+                                                bpp);
+         }
+
+       gegl_buffer_get (sampler->buffer,
+                        1.0,
+                        &fetch_rectangle,
+                        sampler->interpolate_format,
+                        sampler->sampler_buffer,
+                        GEGL_AUTO_ROWSTRIDE);
+
+       sampler->sampler_rectangle = fetch_rectangle;
+     }
+
+   dx = x - sampler->sampler_rectangle.x;
+   dy = y - sampler->sampler_rectangle.y;
+   buffer_ptr = (guchar *)sampler->sampler_buffer;
+   sof = ( dx +  (dy * sampler->sampler_rectangle.width)) * bpp;
+   return (gfloat*)(buffer_ptr+sof);
+}
+
 #include <math.h>
 
 gfloat *

Modified: trunk/gegl/buffer/gegl-sampler.h
==============================================================================
--- trunk/gegl/buffer/gegl-sampler.h	(original)
+++ trunk/gegl/buffer/gegl-sampler.h	Fri Jun 20 00:45:08 2008
@@ -78,6 +78,10 @@
                                        gint         x,
                                        gint         y);
 
+gfloat *
+gegl_sampler_get_ptr (GeglSampler         *sampler,
+                      gint                 x,
+                      gint                 y);
 GType gegl_sampler_type_from_interpolation (GeglInterpolation interpolation);
 
 G_END_DECLS



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