[gegl] transform_generic: arithmetic branching
- From: Nicolas Robidoux <nrobidoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] transform_generic: arithmetic branching
- Date: Tue, 18 Dec 2012 18:28:58 +0000 (UTC)
commit 3db65ee8db24990c977f8e8314e63e29766ea5d2
Author: Nicolas Robidoux <nrobidoux git gnome org>
Date: Tue Dec 18 13:28:51 2012 -0500
transform_generic: arithmetic branching
operations/transform/transform-core.c | 238 +++++++++++++++------------------
1 files changed, 107 insertions(+), 131 deletions(-)
---
diff --git a/operations/transform/transform-core.c b/operations/transform/transform-core.c
index 0db4cbe..0773e4d 100644
--- a/operations/transform/transform-core.c
+++ b/operations/transform/transform-core.c
@@ -529,20 +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 > (gint) 0
- ?
- context_rect.width - (gint) 1
- :
- (gint) 0
- );
+ 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
- );
+ context_rect.height - (gint) 1 > (gint) 0
+ ?
+ context_rect.height - (gint) 1
+ :
+ (gint) 0
+ );
}
#endif
@@ -642,8 +642,8 @@ gegl_transform_get_required_for_output (GeglOperation *op,
requested_rect = *region;
sampler =
gegl_buffer_sampler_new (NULL,
- babl_format("RaGaBaA float"),
- gegl_sampler_type_from_string (transform->filter));
+ babl_format("RaGaBaA float"),
+ gegl_sampler_type_from_string (transform->filter));
context_rect = *gegl_sampler_get_context_rect (sampler);
g_object_unref (sampler);
@@ -1124,6 +1124,8 @@ transform_generic (GeglBuffer *dest,
gint x,
y,
dest_pixels,
+ bflip_x,
+ bflip_y,
flip_x,
flip_y;
@@ -1134,6 +1136,16 @@ transform_generic (GeglBuffer *dest,
gegl_matrix3_invert (&inverse);
/*
+ * 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.
+ */
+ /*
* Determine whether tile access should be "flipped". First, in the
* y direction.
*
@@ -1154,7 +1166,7 @@ transform_generic (GeglBuffer *dest,
u_float = u_start + inverse.coeff [0][1] * ((*dest_extent).height - (gint) 1);
v_float = v_start + inverse.coeff [1][1] * ((*dest_extent).height - (gint) 1);
w_float = w_start + inverse.coeff [2][1] * ((*dest_extent).height - (gint) 1);
-
+
if ((u_float + v_float)/w_float < (u_start + v_start)/w_start)
{
/*
@@ -1166,13 +1178,15 @@ transform_generic (GeglBuffer *dest,
/*
* Set the "change of direction" sign.
*/
- flip_y = (gint) -1;
+ bflip_y = (gint) 1;
}
else
{
- flip_y = (gint) 1;
+ bflip_y = (gint) 0;
}
-
+
+ flip_y = (gint) 1 - (gint) 2 * bflip_y;
+
/*
* Now in the horizontal direction. Done second because this is the
* most important one, and consequently we want to use the likely
@@ -1182,11 +1196,12 @@ transform_generic (GeglBuffer *dest,
v_float = v_start + inverse.coeff [1][0] * ((*dest_extent).width - (gint) 1);
w_float = w_start + inverse.coeff [2][0] * ((*dest_extent).width - (gint) 1);
- flip_x = ((u_float + v_float)/w_float < (u_start + v_start)/w_start)
- ?
- (gint) -1
- :
- (gint) 1;
+ bflip_x = ((u_float + v_float)/w_float < (u_start + v_start)/w_start)
+ ?
+ (gint) 1
+ :
+ (gint) 0;
+ flip_x = (gint) 1 - (gint) 2 * bflip_x;
/*
* Construct an output tile iterator.
@@ -1205,112 +1220,73 @@ transform_generic (GeglBuffer *dest,
{
GeglRectangle *roi = &i->roi[0];
gfloat * restrict dest_buf = (gfloat *)i->data[0];
- 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];
+ gfloat * restrict dest_ptr =
+ dest_buf +
+ (gint) 4 * ( bflip_x * (roi->width - (gint) 1) +
+ bflip_y * (roi->height - (gint) 1) * roi->width );
+
+ u_start =
+ inverse.coeff [0][0] * ( roi->x + bflip_x * (roi->width - (gint) 1) +
+ (gdouble) 0.5 ) +
+ inverse.coeff [0][1] * ( roi->y + bflip_y * (roi->height - (gint) 1) +
+ (gdouble) 0.5 ) +
+ inverse.coeff [0][2];
+ v_start =
+ inverse.coeff [1][0] * ( roi->x + bflip_x * (roi->width - (gint) 1) +
+ (gdouble) 0.5 ) +
+ inverse.coeff [1][1] * ( roi->y + bflip_y * (roi->height - (gint) 1) +
+ (gdouble) 0.5 ) +
+ inverse.coeff [1][2];
+ w_start =
+ inverse.coeff [2][0] * ( roi->x + bflip_x * (roi->width - (gint) 1) +
+ (gdouble) 0.5 ) +
+ inverse.coeff [2][1] * ( roi->y + bflip_y * (roi->height - (gint) 1) +
+ (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 (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;
- }
-
- 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 (flip_x - (gint) 1)
- {
- 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];
- }
+ {
+ 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);
+
+ 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 += flip_x * (gint) 4;
+ }
+
+ u_start += flip_y * inverse.coeff [0][1];
+ v_start += flip_y * inverse.coeff [1][1];
+ w_start += flip_y * inverse.coeff [2][1];
+
+ dest_ptr += (gint) 4 * (flip_y - flip_x) * roi->width;
+ }
}
}
@@ -1430,9 +1406,9 @@ gegl_transform_process (GeglOperation *operation,
output = gegl_operation_context_get_target (context, "output");
sampler =
- gegl_buffer_sampler_new (input,
- babl_format("RaGaBaA float"),
- gegl_sampler_type_from_string (transform->filter));
+ gegl_buffer_sampler_new (input,
+ babl_format("RaGaBaA float"),
+ gegl_sampler_type_from_string (transform->filter));
if (gegl_matrix3_is_affine (&matrix))
transform_affine (output, input, &matrix, sampler, context->level);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]