[gegl] transform: don't sample past-the-horizon points



commit dbac6fcfa29019d50dc1a65a0bcb1da8e83fc0ee
Author: Ell <ell_se yahoo com>
Date:   Sun Jan 21 14:02:42 2018 -0500

    transform: don't sample past-the-horizon points
    
    When applying a perspective transform, don't sample past-the-
    horizon output points, which correspond to behind-the-camera input
    points, and should be clipped.
    
    Currently, we test each point individually, which is suboptimal.
    Ideally, we should precalculate the regions that are inside the
    transformed polygon, and only rasterize those.  Either way, the
    output should now be the same.

 operations/transform/transform-core.c |   70 ++++++++++++++++++++-------------
 1 files changed, 42 insertions(+), 28 deletions(-)
---
diff --git a/operations/transform/transform-core.c b/operations/transform/transform-core.c
index f74969f..0a66d2d 100644
--- a/operations/transform/transform-core.c
+++ b/operations/transform/transform-core.c
@@ -1186,25 +1186,32 @@ transform_generic (GeglOperation       *operation,
 
         gint x = roi->width;
         do {
-          gdouble w_recip = (gdouble) 1.0 / w_float;
-          gdouble u = u_float * w_recip;
-          gdouble v = v_float * w_recip;
-
-          GeglMatrix2 inverse_jacobian;
-          inverse_jacobian.coeff [0][0] =
-            (inverse.coeff [0][0] - inverse.coeff [2][0] * u) * w_recip;
-          inverse_jacobian.coeff [0][1] =
-            (inverse.coeff [0][1] - inverse.coeff [2][1] * u) * w_recip;
-          inverse_jacobian.coeff [1][0] =
-            (inverse.coeff [1][0] - inverse.coeff [2][0] * v) * w_recip;
-          inverse_jacobian.coeff [1][1] =
-            (inverse.coeff [1][1] - inverse.coeff [2][1] * v) * w_recip;
-
-          sampler_get_fun (sampler,
-                           u, v,
-                           &inverse_jacobian,
-                           dest_ptr,
-                           GEGL_ABYSS_NONE);
+          if (w_float >= GEGL_TRANSFORM_CORE_EPSILON)
+            {
+              gdouble w_recip = (gdouble) 1.0 / w_float;
+              gdouble u = u_float * w_recip;
+              gdouble v = v_float * w_recip;
+
+              GeglMatrix2 inverse_jacobian;
+              inverse_jacobian.coeff [0][0] =
+                (inverse.coeff [0][0] - inverse.coeff [2][0] * u) * w_recip;
+              inverse_jacobian.coeff [0][1] =
+                (inverse.coeff [0][1] - inverse.coeff [2][1] * u) * w_recip;
+              inverse_jacobian.coeff [1][0] =
+                (inverse.coeff [1][0] - inverse.coeff [2][0] * v) * w_recip;
+              inverse_jacobian.coeff [1][1] =
+                (inverse.coeff [1][1] - inverse.coeff [2][1] * v) * w_recip;
+
+              sampler_get_fun (sampler,
+                               u, v,
+                               &inverse_jacobian,
+                               dest_ptr,
+                               GEGL_ABYSS_NONE);
+            }
+          else
+            {
+              memset (dest_ptr, 0, 4 * sizeof (gfloat));
+            }
 
           dest_ptr += flip_x * (gint) 4;
           u_float += flip_x * inverse.coeff [0][0];
@@ -1373,15 +1380,22 @@ transform_nearest (GeglOperation       *operation,
 
         gint x = roi->width;
         do {
-          gdouble w_recip = (gdouble) 1.0 / w_float;
-          gdouble u = u_float * w_recip;
-          gdouble v = v_float * w_recip;
-
-          sampler_get_fun (sampler,
-                           u, v,
-                           NULL,
-                           dest_ptr,
-                           GEGL_ABYSS_NONE);
+          if (w_float >= GEGL_TRANSFORM_CORE_EPSILON)
+            {
+              gdouble w_recip = (gdouble) 1.0 / w_float;
+              gdouble u = u_float * w_recip;
+              gdouble v = v_float * w_recip;
+
+              sampler_get_fun (sampler,
+                               u, v,
+                               NULL,
+                               dest_ptr,
+                               GEGL_ABYSS_NONE);
+            }
+          else
+            {
+              memset (dest_ptr, 0, px_size);
+            }
 
           dest_ptr += flip_x * px_size;
           u_float += flip_x * inverse.coeff [0][0];


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