[gegl] put 0s in transform_generic's output
- From: Nicolas Robidoux <nrobidoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] put 0s in transform_generic's output
- Date: Tue, 18 Dec 2012 15:10:17 +0000 (UTC)
commit b7970825df887eedb89d0212551c2ced9f286ff7
Author: Nicolas Robidoux <nrobidoux git gnome org>
Date: Mon Dec 17 21:29:58 2012 -0500
put 0s in transform_generic's output
operations/transform/transform-core.c | 375 ++++++++++++++++++---------------
1 files changed, 207 insertions(+), 168 deletions(-)
---
diff --git a/operations/transform/transform-core.c b/operations/transform/transform-core.c
index 6b8115a..2d254e8 100644
--- a/operations/transform/transform-core.c
+++ b/operations/transform/transform-core.c
@@ -197,9 +197,6 @@ op_transform_class_init (OpTransformClass *klass)
0.,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_FILTER,
- /*
- * Lanczos is gone.
- */
g_param_spec_string (
"filter",
_("Filter"),
@@ -213,6 +210,9 @@ op_transform_class_init (OpTransformClass *klass)
_("Hard edges"),
FALSE,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ /*
+ * Lanczos is gone. This is lint.
+ */
g_object_class_install_property (gobject_class, PROP_LANCZOS_WIDTH,
g_param_spec_int (
"lanczos-width",
@@ -432,8 +432,8 @@ gegl_transform_is_composite_node (OpTransform *transform)
GeglOperation *op = GEGL_OPERATION (transform);
GeglOperation *source;
- connections = gegl_pad_get_connections (gegl_node_get_pad (op->node,
- "input"));
+ connections = gegl_pad_get_connections (gegl_node_get_pad (op->node,"input"));
+
if (! connections)
return FALSE;
@@ -466,8 +466,7 @@ static GeglRectangle
gegl_transform_get_bounding_box (GeglOperation *op)
{
OpTransform *transform = OP_TRANSFORM (op);
- GeglMatrix3 matrix,
- inverse;
+ GeglMatrix3 matrix;
GeglRectangle in_rect = {0,0,0,0},
have_rect;
gdouble have_points [8];
@@ -530,8 +529,20 @@ gegl_transform_get_bounding_box (GeglOperation *op)
/*
* Does "- (gint) 1" interact badly with {*,*,0,0}?
*/
- in_rect.width += context_rect.width - (gint) 1;
- in_rect.height += context_rect.height - (gint) 1;
+ in_rect.width += (
+ context_rect.width - (gint) 1 > (gint) 0
+ ?
+ context_rect.width - (gint) 1
+ :
+ (gint) 0
+ );
+ in_rect.height += (
+ context_rect.height - (gint) 1 > (gint) 0
+ ?
+ context_rect.height - (gint) 1
+ :
+ (gint) 0
+ );
}
#endif
@@ -562,28 +573,28 @@ gegl_transform_get_bounding_box (GeglOperation *op)
gegl_transform_bounding_box (have_points, 4, &have_rect);
- gegl_transform_create_composite_matrix (transform, &inverse);
- gegl_matrix3_invert (&inverse);
-
- /*
- * If there are vanishing or negative denominators within the area
- * of the have_rect, return a null rectangle.
- */
- if ( (inverse.coeff [2][0] * have_rect.x +
- inverse.coeff [2][1] * have_rect.y +
- inverse.coeff [2][2] <= (gdouble) 1.e-4) ||
- (inverse.coeff [2][0] * (have_rect.x + have_rect.width) +
- inverse.coeff [2][1] * have_rect.y +
- inverse.coeff [2][2] <= (gdouble) 1.e-4) ||
- (inverse.coeff [2][0] * have_rect.x +
- inverse.coeff [2][1] * (have_rect.y + have_rect.height) +
- inverse.coeff [2][2] <= (gdouble) 1.e-4) ||
- (inverse.coeff [2][0] * (have_rect.x + have_rect.width) +
- inverse.coeff [2][1] * (have_rect.y + have_rect.height) +
- inverse.coeff [2][2] <= (gdouble) 1.e-4) )
- {
- return (GeglRectangle) {0,0,0,0};
- }
+ /* /\* */
+ /* * If there are vanishing or negative denominators within the area */
+ /* * of the have_rect, return a null rectangle. */
+ /* *\/ */
+ /* gegl_transform_create_composite_matrix (transform, &inverse); */
+ /* gegl_matrix3_invert (&inverse); */
+
+ /* if ( (inverse.coeff [2][0] * have_rect.x + */
+ /* inverse.coeff [2][1] * have_rect.y + */
+ /* inverse.coeff [2][2] <= (gdouble) 1.e-2) || */
+ /* (inverse.coeff [2][0] * (have_rect.x + have_rect.width) + */
+ /* inverse.coeff [2][1] * have_rect.y + */
+ /* inverse.coeff [2][2] <= (gdouble) 1.e-2) || */
+ /* (inverse.coeff [2][0] * have_rect.x + */
+ /* inverse.coeff [2][1] * (have_rect.y + have_rect.height) + */
+ /* inverse.coeff [2][2] <= (gdouble) 1.e-2) || */
+ /* (inverse.coeff [2][0] * (have_rect.x + have_rect.width) + */
+ /* inverse.coeff [2][1] * (have_rect.y + have_rect.height) + */
+ /* inverse.coeff [2][2] <= (gdouble) 1.e-2) ) */
+ /* { */
+ /* return (GeglRectangle) {0,0,0,0}; */
+ /* } */
return have_rect;
}
@@ -681,6 +692,22 @@ gegl_transform_get_required_for_output (GeglOperation *op,
need_points [6] = need_points [0];
need_points [7] = need_points [5];
+ /* if ( (inverse.coeff [2][0] * requested_rect.x + */
+ /* inverse.coeff [2][1] * requested_rect.y + */
+ /* inverse.coeff [2][2] <= (gdouble) 1.e-2) || */
+ /* (inverse.coeff [2][0] * (requested_rect.x + requested_rect.width) + */
+ /* inverse.coeff [2][1] * requested_rect.y + */
+ /* inverse.coeff [2][2] <= (gdouble) 1.e-2) || */
+ /* (inverse.coeff [2][0] * requested_rect.x + */
+ /* inverse.coeff [2][1] * (requested_rect.y + requested_rect.height) + */
+ /* inverse.coeff [2][2] <= (gdouble) 1.e-2) || */
+ /* (inverse.coeff [2][0] * (requested_rect.x + requested_rect.width) + */
+ /* inverse.coeff [2][1] * (requested_rect.y + requested_rect.height) + */
+ /* inverse.coeff [2][2] <= (gdouble) 1.e-2) ) */
+ /* { */
+ /* return (GeglRectangle) {0,0,0,0}; */
+ /* } */
+
for (i = 0; i < 8; i += 2)
gegl_matrix3_transform_point (&inverse,
need_points + i,
@@ -1043,12 +1070,38 @@ transform_generic (GeglBuffer *dest,
const Babl *format = babl_format ("RaGaBaA float");
gint dest_pixels,
+ file13 = 1,
flip_x = 1,
flip_y = 1;
g_object_get (dest, "pixels", &dest_pixels, NULL);
dest_extent = gegl_buffer_get_extent (dest);
+ /*
+ * First, determine if there are vanishing or negative denominators
+ * anywhere within the four outer corners of the corner pixels. If
+ * these locations themselves are "safe", the whole thing is
+ * safe. If unsafe, fill the whole thing with transparent black.
+ */
+ gegl_matrix3_copy_into (&inverse, matrix);
+ gegl_matrix3_invert (&inverse);
+
+ if ( (inverse.coeff [2][0] * (*dest_extent).x +
+ inverse.coeff [2][1] * (*dest_extent).y +
+ inverse.coeff [2][2] < (gdouble) 0.9) ||
+ (inverse.coeff [2][0] * ((*dest_extent).x + (*dest_extent).width) +
+ inverse.coeff [2][1] * (*dest_extent).y +
+ inverse.coeff [2][2] < (gdouble) 0.9) ||
+ (inverse.coeff [2][0] * (*dest_extent).x +
+ inverse.coeff [2][1] * ((*dest_extent).y + (*dest_extent).height) +
+ inverse.coeff [2][2] < (gdouble) 0.9) ||
+ (inverse.coeff [2][0] * ((*dest_extent).x + (*dest_extent).width) +
+ inverse.coeff [2][1] * ((*dest_extent).y + (*dest_extent).height) +
+ inverse.coeff [2][2] < (gdouble) 0.9) )
+ {
+ file13 = (gint) 1;
+ }
+
i = gegl_buffer_iterator_new (dest,
dest_extent,
level,
@@ -1056,15 +1109,10 @@ transform_generic (GeglBuffer *dest,
GEGL_BUFFER_WRITE,
GEGL_ABYSS_NONE);
- gegl_matrix3_copy_into (&inverse, matrix);
- gegl_matrix3_invert (&inverse);
-
while (gegl_buffer_iterator_next (i))
{
GeglRectangle *roi = &i->roi[0];
- gfloat *dest_ptr;
-
dest_buf = (gfloat *)i->data[0];
/*
@@ -1074,141 +1122,132 @@ transform_generic (GeglBuffer *dest,
* 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) 1.e-2) ||
- (inverse.coeff [2][0] * (roi->x + roi->width) +
- inverse.coeff [2][1] * roi->y +
- inverse.coeff [2][2] <= (gdouble) 1.e-2) ||
- (inverse.coeff [2][0] * roi->x +
- inverse.coeff [2][1] * (roi->y + roi->height) +
- inverse.coeff [2][2] <= (gdouble) 1.e-2) ||
- (inverse.coeff [2][0] * (roi->x + roi->width) +
- inverse.coeff [2][1] * (roi->y + roi->height) +
- inverse.coeff [2][2] <= (gdouble) 1.e-2) )
+ if (file13)
{
memset (dest_buf, '\0', sizeof(dest_buf));
- return;
}
-
- dest_ptr = dest_buf;
-
- /*
- * 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
- * there is more elbow room at the bottom and right than at the
- * top and left, explained in the transform_affine function. It
- * is not as foolproof because perspective transformations
- * change the orientation of scanlines, and consequently what's
- * good at the bottom may not be best at the top. On the other
- * hand, the ROIs are generally small, so it's likely that
- * what's good for the goose is good for the gander.
- */
- /*
- * Find out if we should flip things in the vertical
- * direction. Flipping in the horizontal direction at the end
- * ensures that the very first filled scanline will be done in
- * the optimal order, even though the last one may not be. So,
- * "fixing" the horizontal direction last can be seen as a form
- * of greediness.
- */
- /*
- * Compute the positions of the pre-images of the top left and
- * bottom left pixels of the ROI.
- */
- u_start = inverse.coeff [0][0] * (roi->x + (gdouble) 0.5) +
- inverse.coeff [0][1] * (roi->y + (gdouble) 0.5) +
- inverse.coeff [0][2];
- v_start = inverse.coeff [1][0] * (roi->x + (gdouble) 0.5) +
- inverse.coeff [1][1] * (roi->y + (gdouble) 0.5) +
- inverse.coeff [1][2];
- w_start = inverse.coeff [2][0] * (roi->x + (gdouble) 0.5) +
- inverse.coeff [2][1] * (roi->y + (gdouble) 0.5) +
- inverse.coeff [2][2];
-
- 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);
-
- if ((u_float + v_float)/w_float < (u_start + v_start)/w_start)
- {
- /*
- * Set the "change of direction" sign.
- */
- flip_y = (gint) -1;
- /*
- * Move the start to the previously last scanline.
- */
- dest_ptr += (gint) 4 * (roi->height - (gint) 1) * roi->width;
- u_start = u_float;
- v_start = v_float;
- w_start = w_float;
- }
-
- /*
- * Repeat in the horizontal direction, using the first scanline
- * selected by the vertical flip.
- */
- 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);
-
- if ((u_float + v_float)/w_float < (u_start + v_start)/w_start)
- {
- flip_x = (gint) -1;
- /*
- * Move the start to the previously last pixel of the
- * scanline.
- */
- dest_ptr += (gint) 4 * (roi->width - (gint) 1);
- u_start = u_float;
- v_start = v_float;
- w_start = w_float;
- }
-
- for (y = roi->height; y--;)
- {
- u_float = u_start;
- v_float = v_start;
- w_float = w_start;
-
- for (x = roi->width; x--;)
- {
- GeglMatrix2 inverse_jacobian;
-
- gdouble w_recip = (gdouble) 1.0 / w_float;
- gdouble u = u_float * w_recip;
- gdouble v = v_float * w_recip;
-
- 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;
-
- gegl_sampler_get (sampler,
- u,
- v,
- &inverse_jacobian,
- dest_ptr,
- GEGL_ABYSS_NONE);
-
- dest_ptr += flip_x * (gint) 4;
-
- u_float += flip_x * inverse.coeff [0][0];
- v_float += flip_x * inverse.coeff [1][0];
- w_float += flip_x * inverse.coeff [2][0];
- }
-
- dest_ptr += (gint) 4 * (flip_y - flip_x) * roi->width;
-
- u_start += flip_y * inverse.coeff [0][1];
- v_start += flip_y * inverse.coeff [1][1];
- w_start += flip_y * inverse.coeff [2][1];
+ else
+ {
+ gfloat * restrict dest_ptr = dest_buf;
+
+ /*
+ * 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 there is more elbow room at the bottom and
+ * right than at the top and left, explained in the
+ * transform_affine function. It is not as foolproof because
+ * perspective transformations change the orientation of
+ * scanlines, and consequently what's good at the bottom may
+ * not be best at the top. On the other hand, the ROIs are
+ * generally small, so it's likely that what's good for the
+ * goose is good for the gander.
+ */
+ /*
+ * Find out if we should flip things in the vertical
+ * direction. Flipping in the horizontal direction at the
+ * end ensures that the very first filled scanline will be
+ * done in the optimal order, even though the last one may
+ * not be. So, "fixing" the horizontal direction last can be
+ * seen as a form of greediness.
+ */
+ /*
+ * Compute the positions of the pre-images of the top left and
+ * bottom left pixels of the ROI.
+ */
+ u_start = inverse.coeff [0][0] * (roi->x + (gdouble) 0.5) +
+ inverse.coeff [0][1] * (roi->y + (gdouble) 0.5) +
+ inverse.coeff [0][2];
+ v_start = inverse.coeff [1][0] * (roi->x + (gdouble) 0.5) +
+ inverse.coeff [1][1] * (roi->y + (gdouble) 0.5) +
+ inverse.coeff [1][2];
+ w_start = inverse.coeff [2][0] * (roi->x + (gdouble) 0.5) +
+ inverse.coeff [2][1] * (roi->y + (gdouble) 0.5) +
+ inverse.coeff [2][2];
+
+ 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);
+
+ if ((u_float + v_float)/w_float < (u_start + v_start)/w_start)
+ {
+ /*
+ * Set the "change of direction" sign.
+ */
+ flip_y = (gint) -1;
+ /*
+ * Move the start to the previously last scanline.
+ */
+ dest_ptr += (gint) 4 * (roi->height - (gint) 1) * roi->width;
+ u_start = u_float;
+ v_start = v_float;
+ w_start = w_float;
+ }
+
+ /*
+ * Repeat in the horizontal direction, using the first
+ * scanline selected by the vertical flip.
+ */
+ 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);
+
+ if ((u_float + v_float)/w_float < (u_start + v_start)/w_start)
+ {
+ flip_x = (gint) -1;
+ /*
+ * Move the start to the previously last pixel of the
+ * scanline.
+ */
+ dest_ptr += (gint) 4 * (roi->width - (gint) 1);
+ u_start = u_float;
+ v_start = v_float;
+ w_start = w_float;
+ }
+
+ for (y = roi->height; y--;)
+ {
+ u_float = u_start;
+ v_float = v_start;
+ w_float = w_start;
+
+ for (x = roi->width; x--;)
+ {
+ GeglMatrix2 inverse_jacobian;
+
+ gdouble w_recip = (gdouble) 1.0 / w_float;
+ gdouble u = u_float * w_recip;
+ gdouble v = v_float * w_recip;
+
+ 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;
+
+ gegl_sampler_get (sampler,
+ u,
+ v,
+ &inverse_jacobian,
+ dest_ptr,
+ GEGL_ABYSS_NONE);
+
+ dest_ptr += flip_x * (gint) 4;
+
+ u_float += flip_x * inverse.coeff [0][0];
+ v_float += flip_x * inverse.coeff [1][0];
+ w_float += flip_x * inverse.coeff [2][0];
+ }
+
+ dest_ptr += (gint) 4 * (flip_y - flip_x) * roi->width;
+
+ u_start += flip_y * inverse.coeff [0][1];
+ v_start += flip_y * inverse.coeff [1][1];
+ w_start += flip_y * inverse.coeff [2][1];
+ }
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]