[gegl/samplers-api-rework] buffer: add gegl_buffer_sampler_new



commit dbf634b5fd180a9e42550fd09556068881b1b668
Author: Ãyvind KolÃs <pippin gimp org>
Date:   Sun Jul 3 16:50:53 2011 +0100

    buffer: add gegl_buffer_sampler_new
    
    Always associating a sampler with a buffer allows for a tighter smaller public
    API for efficient access to samplers.

 gegl/buffer/gegl-buffer.h           |   20 +++++++++++++++++---
 gegl/buffer/gegl-sampler.c          |   10 ++++++++--
 operations/affine/affine.c          |   35 ++++++++++++++---------------------
 operations/workshop/fractal-trace.c |   10 +++++-----
 operations/workshop/whirl-pinch.c   |   29 +++++++++++++++++++----------
 5 files changed, 63 insertions(+), 41 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer.h b/gegl/buffer/gegl-buffer.h
index 14423a1..8bb6606 100644
--- a/gegl/buffer/gegl-buffer.h
+++ b/gegl/buffer/gegl-buffer.h
@@ -358,6 +358,8 @@ void gegl_buffer_sample (GeglBuffer       *buffer,
  */
 void            gegl_buffer_sample_cleanup    (GeglBuffer *buffer);
 
+
+
 /**
  * gegl_interpolation_from_string:
  * @string: the string to look up
@@ -368,13 +370,25 @@ void            gegl_buffer_sample_cleanup    (GeglBuffer *buffer);
 GeglInterpolation gegl_interpolation_from_string (const gchar *string);
 
 /**
- * gegl_sampler_from_interpolation:
- * @string: the string to look up
+ * gegl_buffer_sample_new:
+ * @buffer: buffer to create a new sampler for
+ * @format: format we want data back in
+ * @interpolation: resampling method to create a sampler for.
  *
  * Looks up the GeglInterpolation corresponding to a string, if no matching
  * interpolation is found returns GEGL_INTERPOLATION_NEAREST.
  */
-GeglSampler *gegl_sampler_from_interpolation (GeglInterpolation interpolation);
+GeglSampler *
+gegl_buffer_sampler_new (GeglBuffer       *buffer,
+                         Babl             *format,
+                         GeglInterpolation interpolation);
+void  gegl_sampler_set_scale   (GeglSampler *self,
+                                GeglMatrix2 *scale);
+void  gegl_sampler_get         (GeglSampler *self,
+                                gdouble      x,
+                                gdouble      y,
+                                void        *output);
+
 
 /**
  * gegl_buffer_linear_new:
diff --git a/gegl/buffer/gegl-sampler.c b/gegl/buffer/gegl-sampler.c
index e41de0d..7ead674 100644
--- a/gegl/buffer/gegl-sampler.c
+++ b/gegl/buffer/gegl-sampler.c
@@ -597,21 +597,27 @@ gegl_sampler_type_from_interpolation (GeglInterpolation interpolation)
 }
 
 GeglSampler *
-gegl_sampler_from_interpolation (GeglInterpolation interpolation)
+gegl_buffer_sampler_new (GeglBuffer       *buffer,
+                         Babl             *format,
+                         GeglInterpolation interpolation)
 {
-  Babl                 *format = babl_format ("RaGaBaA float");
   GeglSampler          *sampler;
   GType                 desired_type;
+  if (format == NULL)
+    format = babl_format ("RaGaBaA float");
   desired_type = gegl_sampler_type_from_interpolation (interpolation);
   if (interpolation == GEGL_INTERPOLATION_LANCZOS)
       sampler = g_object_new (desired_type,
                               "format", format,
+                              "buffer", buffer,
                               "lanczos_width",  4,
                               NULL);
   else
       sampler = g_object_new (desired_type,
+                              "buffer", buffer,
                               "format", format,
                               NULL);
+  gegl_sampler_prepare (sampler);
   return sampler;
 }
 
diff --git a/operations/affine/affine.c b/operations/affine/affine.c
index 015706f..a9fda6a 100644
--- a/operations/affine/affine.c
+++ b/operations/affine/affine.c
@@ -139,14 +139,6 @@ op_affine_get_type (void)
   return g_define_type_id;
 }
 
-/* ************************* */
-static GeglSampler *
-op_affine_sampler (OpAffine *self)
-{
-  return gegl_sampler_from_interpolation (gegl_interpolation_from_string (self->filter));
-}
-/* XXX: keep a pool of samplers */
-
 #if 0
 static void
 op_affine_sampler_init (OpAffine *self)
@@ -453,7 +445,8 @@ gegl_affine_get_bounding_box (GeglOperation *op)
   GeglRectangle  context_rect;
   GeglSampler   *sampler;
 
-  sampler = op_affine_sampler (OP_AFFINE (op));
+  sampler = gegl_buffer_sampler_new (NULL, babl_format("RaGaBaA float"),
+      gegl_interpolation_from_string (affine->filter));
   context_rect = sampler->context_rect[0];
   g_object_unref (sampler);
 
@@ -539,7 +532,8 @@ gegl_affine_get_required_for_output (GeglOperation       *op,
   gint           i;
 
   requested_rect = *region;
-  sampler = op_affine_sampler (OP_AFFINE (op));
+  sampler = gegl_buffer_sampler_new (NULL, babl_format("RaGaBaA float"),
+      gegl_interpolation_from_string (affine->filter));
   context_rect = sampler->context_rect[0];
   g_object_unref (sampler);
 
@@ -590,7 +584,8 @@ gegl_affine_get_invalidated_by_change (GeglOperation       *op,
   gint               i;
   GeglRectangle      region = *input_region;
 
-  sampler = op_affine_sampler (OP_AFFINE (op));
+  sampler = gegl_buffer_sampler_new (NULL, babl_format("RaGaBaA float"),
+      gegl_interpolation_from_string (affine->filter));
   context_rect = sampler->context_rect[0];
   g_object_unref (sampler);
 
@@ -828,11 +823,6 @@ gegl_affine_fast_reflect_y (GeglBuffer              *dest,
   g_free (buf);
 }
 
-void  gegl_sampler_prepare     (GeglSampler *self);
-  /*XXX: Eeeek, obsessive avoidance of public headers, the API needed to
-   *     satisfy this use case should probably be provided.
-   */
-
 static gboolean
 gegl_affine_process (GeglOperation        *operation,
                      GeglOperationContext *context,
@@ -900,7 +890,9 @@ gegl_affine_process (GeglOperation        *operation,
       src_rect = gegl_operation_get_required_for_output (operation, "output", result);
       src_rect.y += 1;
 
-      sampler = op_affine_sampler (OP_AFFINE (operation));
+      sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
+          gegl_interpolation_from_string (affine->filter));
+
       src_rect.width -= sampler->context_rect[0].width;
       src_rect.height -= sampler->context_rect[0].height;
 
@@ -926,7 +918,9 @@ gegl_affine_process (GeglOperation        *operation,
       src_rect = gegl_operation_get_required_for_output (operation, "output", result);
       src_rect.x += 1;
 
-      sampler = op_affine_sampler (OP_AFFINE (operation));
+      sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
+          gegl_interpolation_from_string (affine->filter));
+
       src_rect.width -= sampler->context_rect[0].width;
       src_rect.height -= sampler->context_rect[0].height;
 
@@ -943,9 +937,8 @@ gegl_affine_process (GeglOperation        *operation,
       input  = gegl_operation_context_get_source (context, "input");
       output = gegl_operation_context_get_target (context, "output");
 
-      sampler = op_affine_sampler (affine);
-      g_object_set(sampler, "buffer", input, NULL);
-      gegl_sampler_prepare (sampler);
+      sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
+          gegl_interpolation_from_string (affine->filter));
       affine_generic (output, input, &matrix, sampler);
       g_object_unref(sampler->buffer);
       sampler->buffer = NULL;
diff --git a/operations/workshop/fractal-trace.c b/operations/workshop/fractal-trace.c
index d5cdc20..1bde0ae 100644
--- a/operations/workshop/fractal-trace.c
+++ b/operations/workshop/fractal-trace.c
@@ -162,7 +162,7 @@ fractaltrace (GeglBuffer          *input,
            ud = (rx - o->X1) / scale_x + picture->x;\
            vd = (ry - o->Y1) / scale_y + picture->y;\
          }
-      gegl_compute_inverse_jacobian (scale, x, y);
+      gegl_sampler_compute_scale (scale, x, y);
       gegl_unmap(x,y,px,py);
 #undef gegl_unmap
           break;
@@ -173,8 +173,8 @@ fractaltrace (GeglBuffer          *input,
 
       if (0 <= px && px < picture->width && 0 <= py && py < picture->height)
         {
-          gegl_buffer_sample2 (input, px, py, &scale, dest, format,
-                               GEGL_INTERPOLATION_LOHALO);
+          gegl_buffer_sample (input, px, py, &scale, dest, format,
+                              GEGL_INTERPOLATION_LOHALO);
         }
       else
         {
@@ -206,8 +206,8 @@ fractaltrace (GeglBuffer          *input,
                     py = picture->height - 1.0;
                 }
 
-              gegl_buffer_sample2 (input, px, py, &scale, dest, format,
-                                   GEGL_INTERPOLATION_LOHALO);
+              gegl_buffer_sample (input, px, py, &scale, dest, format,
+                                  GEGL_INTERPOLATION_LOHALO);
               break;
 
             case BACKGROUND_TYPE_TRANSPARENT:
diff --git a/operations/workshop/whirl-pinch.c b/operations/workshop/whirl-pinch.c
index b833e1f..cce8519 100644
--- a/operations/workshop/whirl-pinch.c
+++ b/operations/workshop/whirl-pinch.c
@@ -131,6 +131,7 @@ apply_whirl_pinch (gdouble whirl, gdouble pinch, gdouble radius,
   gint row, col;
   gdouble scale_x, scale_y;
   gdouble cx, cy;
+  GeglSampler *sampler;
 
   /* Get buffer in which to place dst pixels. */
   dst_buf = g_new0 (gfloat, roi->width * roi->height * 4);
@@ -139,28 +140,36 @@ apply_whirl_pinch (gdouble whirl, gdouble pinch, gdouble radius,
 
   scale_x = 1.0;
   scale_y = roi->width / (gdouble) roi->height;
+  sampler = gegl_buffer_sampler_new (src, babl_format ("RaGaBaA float"),
+                                     GEGL_INTERPOLATION_LOHALO);
 
   for (row = 0; row < roi->height; row++) {
     for (col = 0; col < roi->width; col++) {
-        calc_undistorted_coords (roi->x + col, roi->y + row,
-                                 cen_x, cen_y,
-                                 scale_x, scale_y,
-                                 whirl, pinch, radius,
-                                 &cx, &cy);
-
-        gegl_buffer_sample (src, cx, cy, NULL, &dst_buf[(row * roi->width + col) * 4], format,  GEGL_INTERPOLATION_LINEAR);
+        GeglMatrix2 scale;
+#define gegl_unmap(u,v,du,dv) \
+        { \
+          calc_undistorted_coords (u, v,\
+                                   cen_x, cen_y,\
+                                   scale_x, scale_y,\
+                                   whirl, pinch, radius,\
+                                   &cx, &cy);\
+          du=cx;dv=cy;\
+        }
+        gegl_sampler_compute_scale (scale, roi->x + col, roi->y + row);
+        gegl_unmap (roi->x + col, roi->y + row, cx, cy);
+
+        gegl_sampler_set_scale (sampler, &scale);
+        gegl_sampler_get (sampler, cx, cy, &dst_buf[(row * roi->width + col) * 4]);
     } /* for */
   } /* for */
 
-  gegl_buffer_sample_cleanup (src);
-
   /* Store dst pixels. */
   gegl_buffer_set (dst, roi, format, dst_buf, GEGL_AUTO_ROWSTRIDE);
 
   gegl_buffer_flush(dst);
 
   g_free (dst_buf);
-
+  g_object_unref (sampler);
 }
 
 /*****************************************************************************/



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