[gegl/samplers] restructure logic by making the branch treat the case in which we need EWA results
- From: Nicolas Robidoux <nrobidoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/samplers] restructure logic by making the branch treat the case in which we need EWA results
- Date: Fri, 24 Jun 2011 13:46:33 +0000 (UTC)
commit b88ed8f72444969a69991022e042bcfe0118e2f8
Author: Nicolas Robidoux <nicolas robidoux gmail com>
Date: Fri Jun 24 09:46:23 2011 -0400
restructure logic by making the branch treat the case in which we need EWA results
gegl/buffer/gegl-sampler-lohalo.c | 727 ++++++++++++++++++-------------------
1 files changed, 363 insertions(+), 364 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler-lohalo.c b/gegl/buffer/gegl-sampler-lohalo.c
index cd323b5..777274d 100644
--- a/gegl/buffer/gegl-sampler-lohalo.c
+++ b/gegl/buffer/gegl-sampler-lohalo.c
@@ -1953,395 +1953,394 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
* downsampling scheme at all.
*/
- if (twice_s1s1 < (gdouble) 2. + LOHALO_FUDGE)
+ if (twice_s1s1 >= (gdouble) 2. + LOHALO_FUDGE)
{
/*
- * The result is (almost) pure LBB-Nohalo. Pretend it is and
- * ship out the array of new pixel values and return:
+ * The result is not (almost) pure LBB-Nohalo. Compute the
+ * teepee component.
*/
- babl_process (self->fish, newval, output, 1);
- return;
- }
-
- {
- const gdouble s1s1 = (gdouble) 0.5 * twice_s1s1;
- /*
- * s2 the smallest singular value of the inverse Jacobian
- * matrix. Its reciprocal is the largest singular value of the
- * Jacobian matrix itself.
- */
- const gdouble s2s2 =
- (gdouble) 0.5 * ( frobenius_squared - sqrt_discriminant );
-
- const gdouble s1s1minusn11 = s1s1 - n11;
- const gdouble s1s1minusn22 = s1s1 - n22;
- /*
- * u1, the first column of the U factor of a singular
- * decomposition of Jinv, is a (non-normalized) left singular
- * vector corresponding to s1. It has entries u11 and u21. We
- * compute u1 from the fact that it is an eigenvector of n
- * corresponding to the eigenvalue s1^2.
- */
- const gdouble s1s1minusn11_squared = s1s1minusn11 * s1s1minusn11;
- const gdouble s1s1minusn22_squared = s1s1minusn22 * s1s1minusn22;
- /*
- * The following selects the largest row of n-s1^2 I ("I"
- * being the 2x2 identity matrix) as the one which is used to
- * find the eigenvector. If both s1^2-n11 and s1^2-n22 are
- * zero, n-s1^2 I is the zero matrix. In that case, any
- * vector is an eigenvector; in addition, norm below is equal
- * to zero, and, in exact arithmetic, this is the only case in
- * which norm = 0. So, setting u1 to the simple but arbitrary
- * vector [1,0] if norm = 0 safely takes care of all cases.
- */
- const gdouble temp_u11 =
- s1s1minusn11_squared >= s1s1minusn22_squared
- ?
- n12
- :
- s1s1minusn22;
- const gdouble temp_u21 =
- s1s1minusn11_squared >= s1s1minusn22_squared
- ?
- s1s1minusn11
- :
- n21;
- const gdouble norm =
- sqrt( temp_u11 * temp_u11 + temp_u21 * temp_u21 );
- /*
- * Finalize the entries of first left singular vector
- * (associated with the largest singular value).
- */
- const gdouble u11 =
- norm > (gdouble) 0.0 ? temp_u11 / norm : (gdouble) 1.0;
- const gdouble u21 =
- norm > (gdouble) 0.0 ? temp_u21 / norm : (gdouble) 0.0;
- /*
- * Clamp the singular values up to 1:
- */
- const gdouble major_mag =
- s1s1 <= (gdouble) 1.0 ? (gdouble) 1.0 : sqrt( s1s1 );
- const gdouble minor_mag =
- s2s2 <= (gdouble) 1.0 ? (gdouble) 1.0 : sqrt( s2s2 );
- /*
- * Unit major and minor axis direction vectors:
- */
- const gdouble major_unit_x = u11;
- const gdouble major_unit_y = u21;
- const gdouble minor_unit_x = -u21;
- const gdouble minor_unit_y = u11;
-
- /*
- * The square of the distance to the key location in output
- * place of a point [s,t] in input space is the square root of
- *
- * ( s * c_major_x + t * c_major_y )^2
- * +
- * ( s * c_minor_x + t * c_minor_y )^2.
+ const gdouble s1s1 = (gdouble) 0.5 * twice_s1s1;
+ /*
+ * s2 the smallest singular value of the inverse Jacobian
+ * matrix. Its reciprocal is the largest singular value of
+ * the Jacobian matrix itself.
*/
- const gfloat c_major_x = major_unit_x / major_mag;
- const gfloat c_major_y = major_unit_y / major_mag;
- const gfloat c_minor_x = minor_unit_x / minor_mag;
- const gfloat c_minor_y = minor_unit_y / minor_mag;
-
- /*
- * Major and minor axis direction vectors:
- */
- const gdouble major_x = major_mag * major_unit_x;
- const gdouble major_y = major_mag * major_unit_y;
- const gdouble minor_x = minor_mag * minor_unit_x;
- const gdouble minor_y = minor_mag * minor_unit_y;
+ const gdouble s2s2 =
+ (gdouble) 0.5 * ( frobenius_squared - sqrt_discriminant );
- /*
- * Ellipse coefficients:
- */
- const gdouble ellipse_a =
- major_y * major_y + minor_y * minor_y;
- const gdouble ellipse_b =
- (gdouble) -2.0 * ( major_x * major_y + minor_x * minor_y );
- const gdouble ellipse_c =
- major_x * major_x + minor_x * minor_x;
- const gdouble ellipse_f = major_mag * minor_mag;
-
- /*
- * Bounding box of the ellipse:
- */
- const gdouble bounding_box_factor =
- ellipse_f * ellipse_f
- /
- ( ellipse_a * ellipse_c + (gdouble) -.25 * ellipse_b * ellipse_b );
- const gfloat bounding_box_half_width =
- sqrtf( (gfloat) (ellipse_c * bounding_box_factor) );
- const gfloat bounding_box_half_height =
- sqrtf( (gfloat) (ellipse_a * bounding_box_factor) );
- /*
- * Versions which give a bit of wiggle room:
- */
- const gfloat fudged_bounding_box_half_width =
- bounding_box_half_width - LOHALO_FUDGEF;
- const gfloat fudged_bounding_box_half_height =
- bounding_box_half_height - LOHALO_FUDGEF;
-
- /*
- * Accumulator for the EWA weights:
- */
- gfloat total_weight = (gfloat) 0.0;
- /*
- * Storage for the EWA contribution:
- */
- gfloat ewa_newval[channels];
- ewa_newval[0] = (gfloat) 0.0;
- ewa_newval[1] = (gfloat) 0.0;
- ewa_newval[2] = (gfloat) 0.0;
- ewa_newval[3] = (gfloat) 0.0;
-
- /*
- * Grab the pixel values located within the context_rect of
- * "pure" LBB-Nohalo. Farther ones will be accessed through
- * higher mipmap levels.
- */
- /*
- * First (top) row of the 5x5 context_rect, from left to
- * right:
- */
- LOHALO_CALL_EWA_UPDATE(-2,-2);
- LOHALO_CALL_EWA_UPDATE(-1,-2);
- LOHALO_CALL_EWA_UPDATE( 0,-2);
- LOHALO_CALL_EWA_UPDATE( 1,-2);
- LOHALO_CALL_EWA_UPDATE( 2,-2);
- /*
- * Second row of the 5x5:
- */
- LOHALO_CALL_EWA_UPDATE(-2,-1);
- LOHALO_CALL_EWA_UPDATE(-1,-1);
- LOHALO_CALL_EWA_UPDATE( 0,-1);
- LOHALO_CALL_EWA_UPDATE( 1,-1);
- LOHALO_CALL_EWA_UPDATE( 2,-1);
- /*
- * Third row:
- */
- LOHALO_CALL_EWA_UPDATE(-2, 0);
- LOHALO_CALL_EWA_UPDATE(-1, 0);
- LOHALO_CALL_EWA_UPDATE( 0, 0);
- LOHALO_CALL_EWA_UPDATE( 1, 0);
- LOHALO_CALL_EWA_UPDATE( 2, 0);
- /*
- * Fourth row:
- */
- LOHALO_CALL_EWA_UPDATE(-2, 1);
- LOHALO_CALL_EWA_UPDATE(-1, 1);
- LOHALO_CALL_EWA_UPDATE( 0, 1);
- LOHALO_CALL_EWA_UPDATE( 1, 1);
- LOHALO_CALL_EWA_UPDATE( 2, 1);
- /*
- * Fifth row of the 5x5 context_rect:
- */
- LOHALO_CALL_EWA_UPDATE(-2, 2);
- LOHALO_CALL_EWA_UPDATE(-1, 2);
- LOHALO_CALL_EWA_UPDATE( 0, 2);
- LOHALO_CALL_EWA_UPDATE( 1, 2);
- LOHALO_CALL_EWA_UPDATE( 2, 2);
-
- {
+ const gdouble s1s1minusn11 = s1s1 - n11;
+ const gdouble s1s1minusn22 = s1s1 - n22;
+ /*
+ * u1, the first column of the U factor of a singular
+ * decomposition of Jinv, is a (non-normalized) left
+ * singular vector corresponding to s1. It has entries u11
+ * and u21. We compute u1 from the fact that it is an
+ * eigenvector of n corresponding to the eigenvalue s1^2.
+ */
+ const gdouble s1s1minusn11_squared = s1s1minusn11 * s1s1minusn11;
+ const gdouble s1s1minusn22_squared = s1s1minusn22 * s1s1minusn22;
+ /*
+ * The following selects the largest row of n-s1^2 I ("I"
+ * being the 2x2 identity matrix) as the one which is used
+ * to find the eigenvector. If both s1^2-n11 and s1^2-n22
+ * are zero, n-s1^2 I is the zero matrix. In that case, any
+ * vector is an eigenvector; in addition, norm below is
+ * equal to zero, and, in exact arithmetic, this is the only
+ * case in which norm = 0. So, setting u1 to the simple but
+ * arbitrary vector [1,0] if norm = 0 safely takes care of
+ * all cases.
+ */
+ const gdouble temp_u11 =
+ s1s1minusn11_squared >= s1s1minusn22_squared
+ ?
+ n12
+ :
+ s1s1minusn22;
+ const gdouble temp_u21 =
+ s1s1minusn11_squared >= s1s1minusn22_squared
+ ?
+ s1s1minusn11
+ :
+ n21;
+ const gdouble norm =
+ sqrt( temp_u11 * temp_u11 + temp_u21 * temp_u21 );
/*
- * Relative weight of the contribution of LBB-Nohalo:
+ * Finalize the entries of first left singular vector
+ * (associated with the largest singular value).
*/
- const gfloat theta = (gfloat) ( (gdouble) 1. / ellipse_f );
+ const gdouble u11 =
+ norm > (gdouble) 0.0 ? temp_u11 / norm : (gdouble) 1.0;
+ const gdouble u21 =
+ norm > (gdouble) 0.0 ? temp_u21 / norm : (gdouble) 0.0;
+ /*
+ * Clamp the singular values up to 1:
+ */
+ const gdouble major_mag =
+ s1s1 <= (gdouble) 1.0 ? (gdouble) 1.0 : sqrt( s1s1 );
+ const gdouble minor_mag =
+ s2s2 <= (gdouble) 1.0 ? (gdouble) 1.0 : sqrt( s2s2 );
+ /*
+ * Unit major and minor axis direction vectors:
+ */
+ const gdouble major_unit_x = u11;
+ const gdouble major_unit_y = u21;
+ const gdouble minor_unit_x = -u21;
+ const gdouble minor_unit_y = u11;
/*
- * In order to know whether we use higher mipmap level
- * values, we need to check whether there is a level 1
- * mipmap location within the ellipse. So, we need to
- * determine the alignment of the level 1 mipmap level
- * w.r.t. the current level 0.
+ * The square of the distance to the key location in output
+ * place of a point [s,t] in input space is the square root of
*
- * We use a 5x5 context_rect at level 0; consequently, we
- * can access pixels which are 2 away from the anchor pixel
- * location in box distance.
+ * ( s * c_major_x + t * c_major_y )^2
+ * +
+ * ( s * c_minor_x + t * c_minor_y )^2.
+ */
+ const gfloat c_major_x = major_unit_x / major_mag;
+ const gfloat c_major_y = major_unit_y / major_mag;
+ const gfloat c_minor_x = minor_unit_x / minor_mag;
+ const gfloat c_minor_y = minor_unit_y / minor_mag;
+
+ /*
+ * Major and minor axis direction vectors:
*/
+ const gdouble major_x = major_mag * major_unit_x;
+ const gdouble major_y = major_mag * major_unit_y;
+ const gdouble minor_x = minor_mag * minor_unit_x;
+ const gdouble minor_y = minor_mag * minor_unit_y;
+
/*
- * Find the closest locations, on all four sides, of level 1
- * pixels which average data not found in the level 0 5x5.
+ * Ellipse coefficients:
*/
- const gint odd_ix_0 = ix_0 % 2;
- const gint odd_iy_0 = iy_0 % 2;
- const gfloat closest_left =
- odd_ix_0 ? (gfloat) -3.5 : (gfloat) -2.5;
- const gfloat closest_rite =
- odd_ix_0 ? (gfloat) 2.5 : (gfloat) 3.5;
- const gfloat closest_top =
- odd_iy_0 ? (gfloat) -3.5 : (gfloat) -2.5;
- const gfloat closest_bot =
- odd_iy_0 ? (gfloat) 2.5 : (gfloat) 3.5;
-
- if (
- ( x_0 - fudged_bounding_box_half_width <= closest_left )
- ||
- ( x_0 + fudged_bounding_box_half_width >= closest_rite )
- ||
- ( y_0 - fudged_bounding_box_half_height <= closest_top )
- ||&
- ( y_0 + fudged_bounding_box_half_height >= closest_bot )
- )
- {
- /*
- * We most likely need higher mipmap level(s) because
- * the bounding box of the ellipse covers mipmap pixel
- * locations which involve data not "covered" by the 5x5
- * level 0 context_rect. (The ellipse may still fail to
- * involve mipmap level 1 values--in which case all
- * mipmap pixel values will get 0 coefficients--but we
- * used a quick and dirty bounding box test which lets
- * through false positives.)
- */
+ const gdouble ellipse_a =
+ major_y * major_y + minor_y * minor_y;
+ const gdouble ellipse_b =
+ (gdouble) -2.0 * ( major_x * major_y + minor_x * minor_y );
+ const gdouble ellipse_c =
+ major_x * major_x + minor_x * minor_x;
+ const gdouble ellipse_f = major_mag * minor_mag;
- /*
- * Nearest mipmap anchor pixel location:
- */
- const gint ix_1 = LOHALO_FLOORED_DIVISION_BY_2(ix_0);
- const gint iy_1 = LOHALO_FLOORED_DIVISION_BY_2(iy_0);
-
- /*
- * ADAM: THE POINTER get NEEDS TO BE HERE.
- */
+ /*
+ * Bounding box of the ellipse:
+ */
+ const gdouble bounding_box_factor =
+ ellipse_f * ellipse_f
+ /
+ ( ellipse_a * ellipse_c + (gdouble) -.25 * ellipse_b * ellipse_b );
+ const gfloat bounding_box_half_width =
+ sqrtf( (gfloat) (ellipse_c * bounding_box_factor) );
+ const gfloat bounding_box_half_height =
+ sqrtf( (gfloat) (ellipse_a * bounding_box_factor) );
+ /*
+ * Versions which give a bit of wiggle room:
+ */
+ const gfloat fudged_bounding_box_half_width =
+ bounding_box_half_width - LOHALO_FUDGEF;
+ const gfloat fudged_bounding_box_half_height =
+ bounding_box_half_height - LOHALO_FUDGEF;
- /*
- * Position of the sampling location in the coordinate
- * system defined by the mipmap "pixel locations"
- * relative to the level 1 anchor pixel location:
- */
- const gfloat x_1 =
- x_0 + (gfloat) ( ix_0 - 2 * ix_1 ) - (gfloat) 0.5;
- const gfloat y_1 =
- y_0 + (gfloat) ( iy_0 - 2 * iy_1 ) - (gfloat) 0.5;
+ /*
+ * Accumulator for the EWA weights:
+ */
+ gfloat total_weight = (gfloat) 0.0;
+ /*
+ * Storage for the EWA contribution:
+ */
+ gfloat ewa_newval[channels];
+ ewa_newval[0] = (gfloat) 0.0;
+ ewa_newval[1] = (gfloat) 0.0;
+ ewa_newval[2] = (gfloat) 0.0;
+ ewa_newval[3] = (gfloat) 0.0;
+
+ /*
+ * Grab the pixel values located within the context_rect of
+ * "pure" LBB-Nohalo. Farther ones will be accessed through
+ * higher mipmap levels.
+ */
+ /*
+ * First (top) row of the 5x5 context_rect, from left to
+ * right:
+ */
+ LOHALO_CALL_EWA_UPDATE(-2,-2);
+ LOHALO_CALL_EWA_UPDATE(-1,-2);
+ LOHALO_CALL_EWA_UPDATE( 0,-2);
+ LOHALO_CALL_EWA_UPDATE( 1,-2);
+ LOHALO_CALL_EWA_UPDATE( 2,-2);
+ /*
+ * Second row of the 5x5:
+ */
+ LOHALO_CALL_EWA_UPDATE(-2,-1);
+ LOHALO_CALL_EWA_UPDATE(-1,-1);
+ LOHALO_CALL_EWA_UPDATE( 0,-1);
+ LOHALO_CALL_EWA_UPDATE( 1,-1);
+ LOHALO_CALL_EWA_UPDATE( 2,-1);
+ /*
+ * Third row:
+ */
+ LOHALO_CALL_EWA_UPDATE(-2, 0);
+ LOHALO_CALL_EWA_UPDATE(-1, 0);
+ LOHALO_CALL_EWA_UPDATE( 0, 0);
+ LOHALO_CALL_EWA_UPDATE( 1, 0);
+ LOHALO_CALL_EWA_UPDATE( 2, 0);
+ /*
+ * Fourth row:
+ */
+ LOHALO_CALL_EWA_UPDATE(-2, 1);
+ LOHALO_CALL_EWA_UPDATE(-1, 1);
+ LOHALO_CALL_EWA_UPDATE( 0, 1);
+ LOHALO_CALL_EWA_UPDATE( 1, 1);
+ LOHALO_CALL_EWA_UPDATE( 2, 1);
+ /*
+ * Fifth row of the 5x5 context_rect:
+ */
+ LOHALO_CALL_EWA_UPDATE(-2, 2);
+ LOHALO_CALL_EWA_UPDATE(-1, 2);
+ LOHALO_CALL_EWA_UPDATE( 0, 2);
+ LOHALO_CALL_EWA_UPDATE( 1, 2);
+ LOHALO_CALL_EWA_UPDATE( 2, 2);
- /*
- * Key index ranges:
- */
- const gint in_left_ix = -2 + odd_ix_0;
- const gint in_rite_ix = 2 - odd_ix_0;
- const gint in_top_iy = -2 + odd_iy_0;
- const gint in_bot_iy = 2 - odd_iy_0;
-
- const gint out_left =
- LOHALO_MAX
- (
- (gint)
- (
- ceilf
- (
- ( x_1 - bounding_box_half_width )
- *
- (gfloat) 0.5
- )
- )
- ,
- LOHALO_CONTEXT_RECT_SHIFT_1
- );
- const gint out_rite =
- LOHALO_MIN
- (
- -LOHALO_CONTEXT_RECT_SHIFT_1
- ,
- (gint)
- (
- floorf
- (
- ( x_1 + bounding_box_half_width )
- *
- (gfloat) 0.5
- )
- )
- );
- const gint out_top =
- LOHALO_MAX
- (
- (gint)
- (
- ceilf
- (
- ( y_1 - bounding_box_half_height )
- *
- (gfloat) 0.5
- )
- )
- ,
- LOHALO_CONTEXT_RECT_SHIFT_1
- );
- const gint out_bot =
- LOHALO_MIN
- (
- -LOHALO_CONTEXT_RECT_SHIFT_1
- ,
- (gint)
- (
- floorf
- (
- ( y_1 + bounding_box_half_height )
- *
- (gfloat) 0.5
- )
- )
- );
+ {
+ /*
+ * Relative weight of the contribution of LBB-Nohalo:
+ */
+ const gfloat theta = (gfloat) ( (gdouble) 1. / ellipse_f );
- /*
- * Update using mipmap level 1 values.
- *
- * Possible future improvement: When the ellipse is
- * slanted, one could avoid many operations using
- * Anthony Thyssen's formulas for the bounding
- * parallelogram with horizontal top and bottom. When
- * both the magnification factors are the same, or when
- * there is no rotation, using these formulas makes no
- * difference.
- */
+ /*
+ * In order to know whether we use higher mipmap level
+ * values, we need to check whether there is a level 1
+ * mipmap location within the ellipse. So, we need to
+ * determine the alignment of the level 1 mipmap level
+ * w.r.t. the current level 0.
+ *
+ * We use a 5x5 context_rect at level 0; consequently, we
+ * can access pixels which are 2 away from the anchor
+ * pixel location in box distance.
+ */
+ /*
+ * Find the closest locations, on all four sides, of level 1
+ * pixels which average data not found in the level 0 5x5.
+ */
+ const gint odd_ix_0 = ix_0 % 2;
+ const gint odd_iy_0 = iy_0 % 2;
+ const gfloat closest_left =
+ odd_ix_0 ? (gfloat) -3.5 : (gfloat) -2.5;
+ const gfloat closest_rite =
+ odd_ix_0 ? (gfloat) 2.5 : (gfloat) 3.5;
+ const gfloat closest_top =
+ odd_iy_0 ? (gfloat) -3.5 : (gfloat) -2.5;
+ const gfloat closest_bot =
+ odd_iy_0 ? (gfloat) 2.5 : (gfloat) 3.5;
+
+ if (
+ ( x_0 - fudged_bounding_box_half_width <= closest_left )
+ ||
+ ( x_0 + fudged_bounding_box_half_width >= closest_rite )
+ ||
+ ( y_0 - fudged_bounding_box_half_height <= closest_top )
+ ||&
+ ( y_0 + fudged_bounding_box_half_height >= closest_bot )
+ )
{
- gint i;
- for ( i = out_top ; i < in_top; i++ )
- {
- gint j;
- for ( j = out_left; j <= out_rite; j++ )
- {
- LOHALO_CALL_LEVEL_1_EWA_UPDATE( j, i );
- }
- }
- do
- {
- gint j;
- for ( j = out_left; j < in_left; j++ )
- {
- LOHALO_CALL_LEVEL_1_EWA_UPDATE( j, i );
- }
- for ( j = in_rite + 1; j <= out_rite; j++ )
- {
- LOHALO_CALL_LEVEL_1_EWA_UPDATE( j, i );
- }
- } while ( ++i <= in_bot );
- for ( i = in_bot + 1; i <= out_bot; i++ )
- {
- gint j;
- for ( j = out_left; j <= out_rite; j++ )
+ /*
+ * We most likely need higher mipmap level(s) because
+ * the bounding box of the ellipse covers mipmap pixel
+ * locations which involve data not "covered" by the
+ * 5x5 level 0 context_rect. (The ellipse may still
+ * fail to involve mipmap level 1 values--in which
+ * case all mipmap pixel values will get 0
+ * coefficients--but we used a quick and dirty
+ * bounding box test which lets through false
+ * positives.)
+ */
+
+ /*
+ * Nearest mipmap anchor pixel location:
+ */
+ const gint ix_1 = LOHALO_FLOORED_DIVISION_BY_2(ix_0);
+ const gint iy_1 = LOHALO_FLOORED_DIVISION_BY_2(iy_0);
+
+ /*
+ * ADAM: THE POINTER get NEEDS TO BE HERE.
+ */
+
+ /*
+ * Position of the sampling location in the coordinate
+ * system defined by the mipmap "pixel locations"
+ * relative to the level 1 anchor pixel location:
+ */
+ const gfloat x_1 =
+ x_0 + (gfloat) ( ix_0 - 2 * ix_1 ) - (gfloat) 0.5;
+ const gfloat y_1 =
+ y_0 + (gfloat) ( iy_0 - 2 * iy_1 ) - (gfloat) 0.5;
+
+ /*
+ * Key index ranges:
+ */
+ const gint in_left_ix = -2 + odd_ix_0;
+ const gint in_rite_ix = 2 - odd_ix_0;
+ const gint in_top_iy = -2 + odd_iy_0;
+ const gint in_bot_iy = 2 - odd_iy_0;
+
+ const gint out_left =
+ LOHALO_MAX
+ (
+ (gint)
+ (
+ ceilf
+ (
+ ( x_1 - bounding_box_half_width )
+ *
+ (gfloat) 0.5
+ )
+ )
+ ,
+ LOHALO_CONTEXT_RECT_SHIFT_1
+ );
+ const gint out_rite =
+ LOHALO_MIN
+ (
+ -LOHALO_CONTEXT_RECT_SHIFT_1
+ ,
+ (gint)
+ (
+ floorf
+ (
+ ( x_1 + bounding_box_half_width )
+ *
+ (gfloat) 0.5
+ )
+ )
+ );
+ const gint out_top =
+ LOHALO_MAX
+ (
+ (gint)
+ (
+ ceilf
+ (
+ ( y_1 - bounding_box_half_height )
+ *
+ (gfloat) 0.5
+ )
+ )
+ ,
+ LOHALO_CONTEXT_RECT_SHIFT_1
+ );
+ const gint out_bot =
+ LOHALO_MIN
+ (
+ -LOHALO_CONTEXT_RECT_SHIFT_1
+ ,
+ (gint)
+ (
+ floorf
+ (
+ ( y_1 + bounding_box_half_height )
+ *
+ (gfloat) 0.5
+ )
+ )
+ );
+
+ /*
+ * Update using mipmap level 1 values.
+ *
+ * Possible future improvement: When the ellipse is
+ * slanted, one could avoid many operations using
+ * Anthony Thyssen's formulas for the bounding
+ * parallelogram with horizontal top and bottom. When
+ * both the magnification factors are the same, or
+ * when there is no rotation, using these formulas
+ * makes no difference.
+ */
+ {
+ gint i;
+ for ( i = out_top ; i < in_top; i++ )
+ {
+ gint j;
+ for ( j = out_left; j <= out_rite; j++ )
+ {
+ LOHALO_CALL_LEVEL_1_EWA_UPDATE( j, i );
+ }
+ }
+ do
+ {
+ gint j;
+ for ( j = out_left; j < in_left; j++ )
+ {
+ LOHALO_CALL_LEVEL_1_EWA_UPDATE( j, i );
+ }
+ for ( j = in_rite + 1; j <= out_rite; j++ )
+ {
+ LOHALO_CALL_LEVEL_1_EWA_UPDATE( j, i );
+ }
+ } while ( ++i <= in_bot );
+ for ( i = in_bot + 1; i <= out_bot; i++ )
+ {
+ gint j;
+ for ( j = out_left; j <= out_rite; j++ )
{
LOHALO_CALL_LEVEL_1_EWA_UPDATE( j, i );
}
- }
+ }
+ }
}
+ {
+ /*
+ * Blend:
+ */
+ const gfloat beta = ( (gfloat) 1. - theta ) / total_weight;
+ newval[0] = theta * newval[0] + beta * ewa_newval[0];
+ newval[1] = theta * newval[1] + beta * ewa_newval[1];
+ newval[2] = theta * newval[2] + beta * ewa_newval[2];
+ newval[3] = theta * newval[3] + beta * ewa_newval[3];
}
- {
- /*
- * Blend and ship out:
- */
- const gfloat beta = ( (gfloat) 1. - theta ) / total_weight;
- newval[0] = theta * newval[0] + beta * ewa_newval[0];
- newval[1] = theta * newval[1] + beta * ewa_newval[1];
- newval[2] = theta * newval[2] + beta * ewa_newval[2];
- newval[3] = theta * newval[3] + beta * ewa_newval[3];
-
- babl_process (self->fish, newval, output, 1);
- return;
}
}
- }
+ /*
+ * Ship out:
+ */
+ babl_process (self->fish, newval, output, 1);
+ return;
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]