Commit dbac6fcf authored by Ell's avatar Ell

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.
parent b429cd48
......@@ -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];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment