[gegl/samplers] breaking the lohalo code to make it more powerful
- From: Nicolas Robidoux <nrobidoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/samplers] breaking the lohalo code to make it more powerful
- Date: Wed, 15 Jun 2011 21:31:29 +0000 (UTC)
commit e65d4c5329039d03d76ab9ac39760d0c38e37832
Author: Nicolas Robidoux <nicolas robidoux gmail com>
Date: Wed Jun 15 17:31:21 2011 -0400
breaking the lohalo code to make it more powerful
gegl/buffer/gegl-sampler-lohalo.c | 271 ++++++++++++++++++++++++++++---------
1 files changed, 208 insertions(+), 63 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler-lohalo.c b/gegl/buffer/gegl-sampler-lohalo.c
index 8bd311d..3e49ab9 100644
--- a/gegl/buffer/gegl-sampler-lohalo.c
+++ b/gegl/buffer/gegl-sampler-lohalo.c
@@ -1014,18 +1014,22 @@ lbb( const gfloat c00,
}
static inline gfloat
-triangle( const gdouble c_major_x,
- const gdouble c_major_y,
- const gdouble c_minor_x,
- const gdouble c_minor_y,
- const gdouble s,
- const gdouble t )
+triangle( const gfloat c_major_x,
+ const gfloat c_major_y,
+ const gfloat c_minor_x,
+ const gfloat c_minor_y,
+ const gfloat s,
+ const gfloat t )
{
- const gdouble q1 = s * c_major_x + t * c_major_y;
- const gdouble q2 = s * c_minor_x + t * c_minor_y;
- const gdouble r2 = q1 * q1 + q2 * q2;
+ const gfloat q1 = s * c_major_x + t * c_major_y;
+ const gfloat q2 = s * c_minor_x + t * c_minor_y;
+ const gfloat r2 = q1 * q1 + q2 * q2;
const gfloat weight =
- ( ( r2 < 1. ) ? (gfloat) ( 1. - sqrt( r2 ) ) : (gfloat) 0. );
+ (
+ ( r2 < (gfloat) 1. )
+ ? (gfloat) ( (gfloat) 1. - sqrtf( r2 ) )
+ : (gfloat) 0.
+ );
return weight;
}
@@ -1807,14 +1811,13 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
* +
* ( s * c_minor_x + t * c_minor_y )^2.
*/
- const gdouble c_major_x = major_unit_x / major_mag;
- const gdouble c_major_y = major_unit_y / major_mag;
- const gdouble c_minor_x = minor_unit_x / minor_mag;
- const gdouble c_minor_y = minor_unit_y / minor_mag;
+ 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;
/*
- * Ellipse coefficients. Most of them are not needed.
- *
+ * Ellipse coefficients:
*
* const gdouble ellipse_a =
* major_y * major_y + minor_y * minor_y;
@@ -1822,6 +1825,19 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
* -2.0 * ( major_x * major_y + minor_x * minor_y );
* const gdouble ellipse_c =
* major_x * major_x + minor_x * minor_x;
+ *
+ * Bounding box of the ellipse:
+ *
+ * const gdouble bounding_box_factor =
+ * ellipse_f * ellipse_f
+ * /
+ * ( ellipse_a * ellipse_c + -.25 * ellipse_b * ellipse_b );
+ * const gdouble bounding_box_half_width =
+ * sqrt( ellipse_c * bounding_box_factor );
+ * const gdouble bounding_box_half_height =
+ * sqrt( ellipse_a * bounding_box_factor );
+ *
+ * They are not needed here.
*/
const gdouble ellipse_f = major_mag * minor_mag;
@@ -1833,6 +1849,8 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
if (ellipse_f<(gdouble) 1. + epsilon_for_ellipse_f)
{
/*
+ * The result will (almost) be pure LBB-Nohal.
+ *
* Ship out the array of new pixel values and return:
*/
babl_process (self->fish, newval, output, 1);
@@ -1840,62 +1858,189 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
}
{
+ const gfloat radius = (gfloat) 2.5;
/*
- * For reference, here is the bounding box of the ellipse:
- *
- * const gdouble bounding_box_factor =
- * ellipse_f * ellipse_f
- * /
- * ( ellipse_a * ellipse_c + -.25 * ellipse_b * ellipse_b );
- * const gdouble bounding_box_half_width =
- * sqrt( ellipse_c * bounding_box_factor );
- * const gdouble bounding_box_half_height =
- * sqrt( ellipse_a * bounding_box_factor );
- *
- * We don't need these values.
+ * Grab the pixel values located strictly within a
+ * distance of 2.5 from the location of interest. These
+ * fit within the context_rect of "pure" LBB-Nohalo; which
+ * ones exactly fit depends on the signs of x_0 and y_0.
*/
- gfloat total_weight = (gfloat) 0.;
-
gfloat ewa_newval[channels];
- ewa_newval[0] = (gfloat) 0.;
- ewa_newval[1] = (gfloat) 0.;
- ewa_newval[2] = (gfloat) 0.;
- ewa_newval[3] = (gfloat) 0.;
- const gfloat radius = (gfloat) 2.5;
+ gfloat total_weight = (gfloat) 0.;
+
/*
- * Grab the pixel values located strictly within a
- * distance of 2.5 from the location of interest. These
- * fit within the context_rect of "pure" LBB-Nohalo. Which
- * ones, exactly, depends on the signs of x_0 and y_0.
- *
* The central 3x3 block of the 5x5 are always close
- * enough to be within a radius of 2.5.
+ * enough to be within radius 2.5:
+ */
+ {
+ const gint skip = -row_skip - channels;
+ const gfloat weight = triangle(c_major_x,
+ c_major_y,
+ c_minor_x,
+ c_minor_y,
+ (gfloat) -1. - x_0,
+ (gfloat) -1. - y_0);
+ total_weight += weight;
+ ewa_newval[0] = weight * input_bptr[ skip ];
+ ewa_newval[1] = weight * input_bptr[ skip + 1 ];
+ ewa_newval[2] = weight * input_bptr[ skip + 2 ];
+ ewa_newval[3] = weight * input_bptr[ skip + 3 ];
+ }
+ {
+ const gint skip = -row_skip;
+ const gfloat weight = triangle(c_major_x,
+ c_major_y,
+ c_minor_x,
+ c_minor_y,
+ - x_0,
+ (gfloat) -1. - y_0);
+ total_weight += weight;
+ ewa_newval[0] += weight * input_bptr[ skip ];
+ ewa_newval[1] += weight * input_bptr[ skip + 1 ];
+ ewa_newval[2] += weight * input_bptr[ skip + 2 ];
+ ewa_newval[3] += weight * input_bptr[ skip + 3 ];
+ }
+ {
+ const gint skip = -row_skip + channels;
+ const gfloat weight = triangle(c_major_x,
+ c_major_y,
+ c_minor_x,
+ c_minor_y,
+ (gfloat) 1. - x_0,
+ (gfloat) -1. - y_0);
+ total_weight += weight;
+ ewa_newval[0] += weight * input_bptr[ skip ];
+ ewa_newval[1] += weight * input_bptr[ skip + 1 ];
+ ewa_newval[2] += weight * input_bptr[ skip + 2 ];
+ ewa_newval[3] += weight * input_bptr[ skip + 3 ];
+ }
+ {
+ const gint skip = - channels;
+ const gfloat weight = triangle(c_major_x,
+ c_major_y,
+ c_minor_x,
+ c_minor_y,
+ (gfloat) -1. - x_0,
+ - y_0);
+ total_weight += weight;
+ ewa_newval[0] = weight * input_bptr[ skip ];
+ ewa_newval[1] = weight * input_bptr[ skip + 1 ];
+ ewa_newval[2] = weight * input_bptr[ skip + 2 ];
+ ewa_newval[3] = weight * input_bptr[ skip + 3 ];
+ }
+ {
+ const gint skip = 0;
+ const gfloat weight = triangle(c_major_x,
+ c_major_y,
+ c_minor_x,
+ c_minor_y,
+ - x_0,
+ - y_0);
+ total_weight += weight;
+ ewa_newval[0] += weight * input_bptr[ skip ];
+ ewa_newval[1] += weight * input_bptr[ skip + 1 ];
+ ewa_newval[2] += weight * input_bptr[ skip + 2 ];
+ ewa_newval[3] += weight * input_bptr[ skip + 3 ];
+ }
+ {
+ const gint skip = channels;
+ const gfloat weight = triangle(c_major_x,
+ c_major_y,
+ c_minor_x,
+ c_minor_y,
+ (gfloat) 1. - x_0,
+ - y_0);
+ total_weight += weight;
+ ewa_newval[0] += weight * input_bptr[ skip ];
+ ewa_newval[1] += weight * input_bptr[ skip + 1 ];
+ ewa_newval[2] += weight * input_bptr[ skip + 2 ];
+ ewa_newval[3] += weight * input_bptr[ skip + 3 ];
+ }
+ {
+ const gint skip = row_skip - channels;
+ const gfloat weight = triangle(c_major_x,
+ c_major_y,
+ c_minor_x,
+ c_minor_y,
+ (gfloat) -1. - x_0,
+ (gfloat) 1. - y_0);
+ total_weight += weight;
+ ewa_newval[0] += weight * input_bptr[ skip ];
+ ewa_newval[1] += weight * input_bptr[ skip + 1 ];
+ ewa_newval[2] += weight * input_bptr[ skip + 2 ];
+ ewa_newval[3] += weight * input_bptr[ skip + 3 ];
+ }
+ {
+ const gint skip = row_skip;
+ const gfloat weight = triangle(c_major_x,
+ c_major_y,
+ c_minor_x,
+ c_minor_y,
+ - x_0,
+ (gfloat) 1. - y_0);
+ total_weight += weight;
+ ewa_newval[0] += weight * input_bptr[ skip ];
+ ewa_newval[1] += weight * input_bptr[ skip + 1 ];
+ ewa_newval[2] += weight * input_bptr[ skip + 2 ];
+ ewa_newval[3] += weight * input_bptr[ skip + 3 ];
+ }
+ {
+ const gint skip = row_skip + channels;
+ const gfloat weight = triangle(c_major_x,
+ c_major_y,
+ c_minor_x,
+ c_minor_y,
+ (gfloat) 1. - x_0,
+ (gfloat) 1. - y_0);
+ total_weight += weight;
+ ewa_newval[0] += weight * input_bptr[ skip ];
+ ewa_newval[1] += weight * input_bptr[ skip + 1 ];
+ ewa_newval[2] += weight * input_bptr[ skip + 2 ];
+ ewa_newval[3] += weight * input_bptr[ skip + 3 ];
+ }
+
+ const gfloat theta = (gfloat) ( 1. / ellipse_f );
+
+ if (major_mag <= (gdouble) 2.5)
+ {
+ const gfloat ewa_factor =
+ ( (gfloat) 1. - theta ) / total_weight;
+ newval[0] = theta * newval[0] + ewa_factor * ewa_newval[0];
+ newval[1] = theta * newval[1] + ewa_factor * ewa_newval[1];
+ newval[2] = theta * newval[2] + ewa_factor * ewa_newval[2];
+ newval[3] = theta * newval[3] + ewa_factor * ewa_newval[3];
+
+ babl_process (self->fish, newval, output, 1);
+ return;
+ }
+
+ /*
+ * If major_mag > 2.5, we pull data from higher level
+ * mipmap.
*/
- do
- {
- const gint y_shift = i_y * row_skip;
- gint i_x = left;
- do
- {
- const gint pos = i_x * channels + y_shift;
- const gfloat weight = triangle(c_major_x,
- c_major_y,
- c_minor_x,
- c_minor_y,
- i_x - x_0,
- i_y - y_0);
- total_weight += weight;
- ewa_newval[0] += input_bptr[pos ] * weight;
- ewa_newval[1] += input_bptr[pos+1] * weight;
- ewa_newval[2] += input_bptr[pos+2] * weight;
- ewa_newval[3] += input_bptr[pos+3] * weight;
- } while (++i_x<=rite);
- } while (++i_y<=bot);
-
-
+ /* do */
+ /* { */
+ /* const gint y_shift = i_y * row_skip; */
+ /* gint i_x = left; */
+ /* do */
+ /* { */
+ /* const gint pos = i_x * channels + y_shift; */
+ /* const gfloat weight = triangle(c_major_x, */
+ /* c_major_y, */
+ /* c_minor_x, */
+ /* c_minor_y, */
+ /* i_x - x_0, */
+ /* i_y - y_0); */
+ /* total_weight += weight; */
+ /* ewa_newval[0] += input_bptr[pos ] * weight; */
+ /* ewa_newval[1] += input_bptr[pos+1] * weight; */
+ /* ewa_newval[2] += input_bptr[pos+2] * weight; */
+ /* ewa_newval[3] += input_bptr[pos+3] * weight; */
+ /* } while (++i_x<=rite); */
+ /* } while (++i_y<=bot); */
/* if (y_0<(gfloat) 0.) */
/* { */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]