[gegl] transform-core: If there is a vanishing or negative denominator within a buffer tile, fill with tran
- From: Nicolas Robidoux <nrobidoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] transform-core: If there is a vanishing or negative denominator within a buffer tile, fill with tran
- Date: Mon, 17 Dec 2012 04:40:17 +0000 (UTC)
commit 50b0d57db9a257d75b9d7be0b1f296b360901713
Author: Nicolas Robidoux <nrobidoux git gnome org>
Date: Sun Dec 16 23:40:11 2012 -0500
transform-core: If there is a vanishing or negative denominator within a buffer tile, fill with transparent black
gegl/gegl-matrix.c | 14 +--------
operations/transform/transform-core.c | 49 ++++++++++++++++++---------------
2 files changed, 29 insertions(+), 34 deletions(-)
---
diff --git a/gegl/gegl-matrix.c b/gegl/gegl-matrix.c
index e813391..48a455e 100644
--- a/gegl/gegl-matrix.c
+++ b/gegl/gegl-matrix.c
@@ -219,18 +219,8 @@ gegl_matrix3_transform_point (GeglMatrix3 *matrix,
w = (*x * matrix->coeff [2][0] + *y * matrix->coeff [2][1] + matrix->coeff [2][2]);
- /*
- * Attempt at making near degenerate cases be handled somewhat
- * gracefully: Set a floor, above 0, for w.
- */
-#define PERSPECTIVE_TRANSFORM_EPSILON ((gdouble) 1.e-4)
-#define CLAMP_PERSPECTIVE_TRANSFORM(w) \
- ( (w) > PERSPECTIVE_TRANSFORM_EPSILON ? (w) : PERSPECTIVE_TRANSFORM_EPSILON )
-
- cw = CLAMP_PERSPECTIVE_TRANSFORM(w);
-
- xp = (*x * matrix->coeff [0][0] + *y * matrix->coeff [0][1] + matrix->coeff [0][2]) / cw;
- yp = (*x * matrix->coeff [1][0] + *y * matrix->coeff [1][1] + matrix->coeff [1][2]) / cw;
+ xp = (*x * matrix->coeff [0][0] + *y * matrix->coeff [0][1] + matrix->coeff [0][2]) / w;
+ yp = (*x * matrix->coeff [1][0] + *y * matrix->coeff [1][1] + matrix->coeff [1][2]) / w;
*x = xp;
*y = yp;
diff --git a/operations/transform/transform-core.c b/operations/transform/transform-core.c
index 1240a64..899645c 100644
--- a/operations/transform/transform-core.c
+++ b/operations/transform/transform-core.c
@@ -1012,11 +1012,9 @@ transform_generic (GeglBuffer *dest,
gdouble u_start,
v_start,
w_start,
- cw_start,
u_float,
v_float,
- w_float,
- cw_float;
+ w_float;
const Babl *format = babl_format ("RaGaBaA float");
gint dest_pixels,
@@ -1045,6 +1043,29 @@ transform_generic (GeglBuffer *dest,
dest_ptr = dest_buf;
/*
+ * First, determine if there are vanishing denominators anywhere
+ * within the four corners of the corner pixels. If the four
+ * corners themselves are "safe", the whole thing is safe. If
+ * unsafe, fill the whole thing with transparent black.
+ */
+ if ( (inverse.coeff [2][0] * roi->x +
+ inverse.coeff [2][1] * roi->y +
+ inverse.coeff [2][2] <= (gdouble) 0.) ||
+ (inverse.coeff [2][0] * (roi->x + roi->width) +
+ inverse.coeff [2][1] * roi->y +
+ inverse.coeff [2][2] <= (gdouble) 0.) ||
+ (inverse.coeff [2][0] * roi->x +
+ inverse.coeff [2][1] * (roi->y + roi->height) +
+ inverse.coeff [2][2] <= (gdouble) 0.) ||
+ (inverse.coeff [2][0] * (roi->x + roi->width) +
+ inverse.coeff [2][1] * (roi->y + roi->height) +
+ inverse.coeff [2][2] <= (gdouble) 0.) )
+ {
+ memset (dest_buf, 0x00, (gint) 4 * roi->width * roi->height);
+ return;
+ }
+
+ /*
* This code uses a variant of the (novel?) method of ensuring
* that scanlines stay, as much as possible, within an input
* "tile", given that these square "tiles" are biased so that
@@ -1078,21 +1099,11 @@ transform_generic (GeglBuffer *dest,
inverse.coeff [2][1] * (roi->y + (gdouble) 0.5) +
inverse.coeff [2][2];
-/*
- * Attempt at making near degenerate cases be handled somewhat
- * gracefully: Set a floor, above 0, for w.
- */
-#define PERSPECTIVE_TRANSFORM_EPSILON ((gdouble) 1.e-5)
-#define CLAMP_PERSPECTIVE_TRANSFORM(w) \
- ( (w) > PERSPECTIVE_TRANSFORM_EPSILON ? (w) : PERSPECTIVE_TRANSFORM_EPSILON )
-
- cw_start = CLAMP_PERSPECTIVE_TRANSFORM( w_start );
u_float = u_start + inverse.coeff [0][1] * (roi->height - (gint) 1);
v_float = v_start + inverse.coeff [1][1] * (roi->height - (gint) 1);
w_float = w_start + inverse.coeff [2][1] * (roi->height - (gint) 1);
- cw_float = CLAMP_PERSPECTIVE_TRANSFORM( w_float );
- if ((u_float + v_float)/cw_float < (u_start + v_start)/cw_start)
+ if ((u_float + v_float)/w_float < (u_start + v_start)/w_start)
{
/*
* Set the "change of direction" sign.
@@ -1105,7 +1116,6 @@ transform_generic (GeglBuffer *dest,
u_start = u_float;
v_start = v_float;
w_start = w_float;
- cw_start = cw_float;
}
/*
@@ -1115,9 +1125,8 @@ transform_generic (GeglBuffer *dest,
u_float = u_start + inverse.coeff [0][0] * (roi->width - (gint) 1);
v_float = v_start + inverse.coeff [1][0] * (roi->width - (gint) 1);
w_float = w_start + inverse.coeff [2][0] * (roi->width - (gint) 1);
- cw_float = CLAMP_PERSPECTIVE_TRANSFORM( w_float );
- if ((u_float + v_float)/cw_float < (u_start + v_start)/cw_start)
+ if ((u_float + v_float)/w_float < (u_start + v_start)/w_start)
{
flip_x = (gint) -1;
/*
@@ -1128,7 +1137,6 @@ transform_generic (GeglBuffer *dest,
u_start = u_float;
v_start = v_float;
w_start = w_float;
- cw_start = cw_float;
}
for (y = roi->height; y--;)
@@ -1136,13 +1144,12 @@ transform_generic (GeglBuffer *dest,
u_float = u_start;
v_float = v_start;
w_float = w_start;
- cw_float = cw_start;
for (x = roi->width; x--;)
{
GeglMatrix2 inverse_jacobian;
- gdouble w_recip = (gdouble) 1.0 / cw_float;
+ gdouble w_recip = (gdouble) 1.0 / w_float;
gdouble u = u_float * w_recip;
gdouble v = v_float * w_recip;
@@ -1167,7 +1174,6 @@ transform_generic (GeglBuffer *dest,
u_float += flip_x * inverse.coeff [0][0];
v_float += flip_x * inverse.coeff [1][0];
w_float += flip_x * inverse.coeff [2][0];
- cw_float = CLAMP_PERSPECTIVE_TRANSFORM( w_float );
}
dest_ptr += (gint) 4 * (flip_y - flip_x) * roi->width;
@@ -1175,7 +1181,6 @@ transform_generic (GeglBuffer *dest,
u_start += flip_y * inverse.coeff [0][1];
v_start += flip_y * inverse.coeff [1][1];
w_start += flip_y * inverse.coeff [2][1];
- cw_start = CLAMP_PERSPECTIVE_TRANSFORM( w_start );
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]