[gimp/soc-2010-cage-2] GimpOperationCageTransform: add code to compute the exact source point to handle aliasing.



commit e94d90f4a7e40c1f946f32f25a556599f60825dd
Author: Michael Muré <batolettre gmail com>
Date:   Sun Aug 8 01:34:53 2010 +0200

    GimpOperationCageTransform: add code to compute the exact source point to handle aliasing.

 app/gegl/gimpoperationcagetransform.c |   44 +++++++++++++++++++++++++-------
 app/gegl/gimpoperationcagetransform.h |    1 +
 2 files changed, 35 insertions(+), 10 deletions(-)
---
diff --git a/app/gegl/gimpoperationcagetransform.c b/app/gegl/gimpoperationcagetransform.c
index 7609270..bd5b915 100644
--- a/app/gegl/gimpoperationcagetransform.c
+++ b/app/gegl/gimpoperationcagetransform.c
@@ -101,7 +101,7 @@ gimp_operation_cage_transform_class_init (GimpOperationCageTransformClass *klass
 static void
 gimp_operation_cage_transform_init (GimpOperationCageTransform *self)
 {
-  
+  self->format_coords = babl_format_n(babl_type("float"), 2);
 }
 
 static void
@@ -229,7 +229,6 @@ gimp_operation_cage_transform_interpolate_source_coords_recurs  (GimpOperationCa
 {
   gint xmin, xmax, ymin, ymax;
   GeglRectangle rect = {0, 0, 1, 1};
-  Babl *format = babl_format_n(babl_type("float"), 2);
   gfloat *coords;  
   
   coords = g_malloc( 2 * sizeof (gfloat));
@@ -266,23 +265,48 @@ gimp_operation_cage_transform_interpolate_source_coords_recurs  (GimpOperationCa
   if (xmin == xmax || ymin == ymax)
     return;
   
-  /* test if there is only one pixel left in the triangle */
+  /* test if the triangle is small enough.
+   * if yes, we compute the coefficient of the barycenter for the pixel (x,y) and see if a pixel is inside (ie the 3 coef have the same sign).
+   */
   if (xmax - xmin == 1 && ymax - ymin == 1)
   {
+    gfloat a, b, c, denom, x, y;
+    
     rect.x = xmax;
     rect.y = ymax;
     
-    coords[0] = p1_s.x;
-    coords[1] = p1_s.y;
-    gegl_buffer_set(out_buf,
-                    &rect,
-                    format,
-                    coords,
-                    GEGL_AUTO_ROWSTRIDE);
+    x = (gfloat) xmax;
+    y = (gfloat) ymax;
+    
+    denom = (p2_d.x - p1_d.x) * p3_d.y + (p1_d.x - p3_d.x) * p2_d.y + (p3_d.x - p2_d.x) * p1_d.y;
+    a = ((p2_d.x - x) * p3_d.y + (x - p3_d.x) * p2_d.y + (p3_d.x - p2_d.x) * y) / denom;
+    b = - ((p1_d.x - x) * p3_d.y + (x - p3_d.x) * p1_d.y + (p3_d.x - p1_d.x) * y) / denom;
+    c = 1.0 - a - b;
+    
+    /* if a pixel is inside, we compute his source coordinate and set it in the output buffer */
+    if ((a > 0 && b > 0 && c > 0) || (a < 0 && b < 0 && c < 0))
+    {
+      coords[0] = (a * p1_s.x + b * p2_s.x + c * p3_s.x);
+      coords[1] = (a * p1_s.y + b * p2_s.y + c * p3_s.y);
+      
+      gegl_buffer_set(out_buf,
+                      &rect,
+                      oct->format_coords,
+                      coords,
+                      GEGL_AUTO_ROWSTRIDE);
+    }
   }
   else
   {
     /* we cut the triangle in 4 sub-triangle and treat it recursively */
+    /*
+     *       /\
+     *      /__\
+     *     /\  /\
+     *    /__\/__\
+     * 
+     */
+    
     GimpCoords pm1_d, pm2_d, pm3_d;
     GimpCoords pm1_s, pm2_s, pm3_s;
     
diff --git a/app/gegl/gimpoperationcagetransform.h b/app/gegl/gimpoperationcagetransform.h
index 864323c..f5c00bb 100644
--- a/app/gegl/gimpoperationcagetransform.h
+++ b/app/gegl/gimpoperationcagetransform.h
@@ -44,6 +44,7 @@ struct _GimpOperationCageTransform
   GeglOperationFilter  parent_instance;
   
   GimpCageConfig       *config;
+  Babl                 *format_coords;
 };
 
 struct _GimpOperationCageTransformClass



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