[gegl] lohalo can now downsample by .0003 in each direction without major loss of quality
- From: Nicolas Robidoux <nrobidoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] lohalo can now downsample by .0003 in each direction without major loss of quality
- Date: Sat, 22 Dec 2012 01:25:00 +0000 (UTC)
commit f3123b083ae3ffb31b8beda2c50d5811422fca69
Author: Nicolas Robidoux <nrobidoux git gnome org>
Date: Fri Dec 21 20:24:51 2012 -0500
lohalo can now downsample by .0003 in each direction without major loss of quality
gegl/buffer/gegl-sampler-lohalo.c | 401 ++++++++++++++++++++++---------------
gegl/buffer/gegl-sampler.h | 2 +-
2 files changed, 243 insertions(+), 160 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler-lohalo.c b/gegl/buffer/gegl-sampler-lohalo.c
index 57412d4..7ab94b4 100644
--- a/gegl/buffer/gegl-sampler-lohalo.c
+++ b/gegl/buffer/gegl-sampler-lohalo.c
@@ -294,7 +294,7 @@
for ( i = out_top_##_level_; i <= in_top_##_level_; i++ ) \
{ \
gint j = out_left_##_level_; \
- do { \
+ do { \
LOHALO_MIPMAP_PIXEL_UPDATE(_level_); \
} while ( ++j <= out_rite_##_level_ ); \
} \
@@ -391,7 +391,7 @@ gegl_sampler_lohalo_class_init (GeglSamplerLohaloClass *klass)
* IMPORTANT: LOHALO_OFFSET_0 SHOULD BE AN INTEGER >= 2.
*/
#define LOHALO_OFFSET_0 (4)
-#define LOHALO_SIZE_0 ( 1 + 2 * LOHALO_OFFSET_0 )
+#define LOHALO_SIZE_0 (1+2*LOHALO_OFFSET_0)
/*
* The higher mipmap context_rects must be set so that there is at
@@ -404,7 +404,7 @@ gegl_sampler_lohalo_class_init (GeglSamplerLohaloClass *klass)
* previous level's offset.
*/
#define LOHALO_OFFSET_MIPMAP (4)
-#define LOHALO_SIZE_MIPMAP ( 1 + 2 * LOHALO_OFFSET_MIPMAP )
+#define LOHALO_SIZE_MIPMAP (1+2*LOHALO_OFFSET_MIPMAP)
#define LOHALO_OFFSET_1 LOHALO_OFFSET_MIPMAP
#define LOHALO_SIZE_1 LOHALO_SIZE_MIPMAP
@@ -415,6 +415,18 @@ gegl_sampler_lohalo_class_init (GeglSamplerLohaloClass *klass)
#define LOHALO_OFFSET_3 LOHALO_OFFSET_MIPMAP
#define LOHALO_SIZE_3 LOHALO_SIZE_MIPMAP
+#define LOHALO_OFFSET_4 LOHALO_OFFSET_MIPMAP
+#define LOHALO_SIZE_4 LOHALO_SIZE_MIPMAP
+
+#define LOHALO_OFFSET_5 LOHALO_OFFSET_MIPMAP
+#define LOHALO_SIZE_5 LOHALO_SIZE_MIPMAP
+
+#define LOHALO_OFFSET_6 LOHALO_OFFSET_MIPMAP
+#define LOHALO_SIZE_6 LOHALO_SIZE_MIPMAP
+
+#define LOHALO_OFFSET_7 ((GEGL_SAMPLER_MAXIMUM_HEIGHT-1)/2)
+#define LOHALO_SIZE_7 (1+2*LOHALO_SIZE_6)
+
/*
* Lohalo always uses some mipmap level 0 values, but not always
* higher mipmap values.
@@ -442,6 +454,26 @@ gegl_sampler_lohalo_init (GeglSamplerLohalo *self)
GEGL_SAMPLER (self)->context_rect[3].width = LOHALO_SIZE_3;
GEGL_SAMPLER (self)->context_rect[3].height = LOHALO_SIZE_3;
+ GEGL_SAMPLER (self)->context_rect[4].x = -LOHALO_OFFSET_4;
+ GEGL_SAMPLER (self)->context_rect[4].y = -LOHALO_OFFSET_4;
+ GEGL_SAMPLER (self)->context_rect[4].width = LOHALO_SIZE_4;
+ GEGL_SAMPLER (self)->context_rect[4].height = LOHALO_SIZE_4;
+
+ GEGL_SAMPLER (self)->context_rect[5].x = -LOHALO_OFFSET_5;
+ GEGL_SAMPLER (self)->context_rect[5].y = -LOHALO_OFFSET_5;
+ GEGL_SAMPLER (self)->context_rect[5].width = LOHALO_SIZE_5;
+ GEGL_SAMPLER (self)->context_rect[5].height = LOHALO_SIZE_5;
+
+ GEGL_SAMPLER (self)->context_rect[6].x = -LOHALO_OFFSET_6;
+ GEGL_SAMPLER (self)->context_rect[6].y = -LOHALO_OFFSET_6;
+ GEGL_SAMPLER (self)->context_rect[6].width = LOHALO_SIZE_6;
+ GEGL_SAMPLER (self)->context_rect[6].height = LOHALO_SIZE_6;
+
+ GEGL_SAMPLER (self)->context_rect[7].x = -LOHALO_OFFSET_7;
+ GEGL_SAMPLER (self)->context_rect[7].y = -LOHALO_OFFSET_7;
+ GEGL_SAMPLER (self)->context_rect[7].width = LOHALO_SIZE_7;
+ GEGL_SAMPLER (self)->context_rect[7].height = LOHALO_SIZE_7;
+
GEGL_SAMPLER (self)->interpolate_format = babl_format ("RaGaBaA float");
}
@@ -2322,8 +2354,8 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
input_bptr,
&total_weight,
ewa_newval);
- } while ( ++j <= out_rite_0 );
- } while ( ++i <= out_bot_0 );
+ } while ( ++j <= out_rite_0 );
+ } while ( ++i <= out_bot_0 );
}
{
@@ -2351,13 +2383,10 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
*/
LOHALO_FIND_CLOSEST_LOCATIONS(0,1)
- if (( x_0 - bounding_box_half_width < closest_left_1 )
- ||
- ( x_0 + bounding_box_half_width > closest_rite_1 )
- ||
- ( y_0 - bounding_box_half_height < closest_top_1 )
- ||
- ( y_0 + bounding_box_half_height > closest_bot_1 ))
+ if (( x_0 - bounding_box_half_width < closest_left_1 ) ||
+ ( x_0 + bounding_box_half_width > closest_rite_1 ) ||
+ ( y_0 - bounding_box_half_height < closest_top_1 ) ||
+ ( y_0 + bounding_box_half_height > closest_bot_1 ))
{
/*
* We most likely need higher mipmap level(s) because
@@ -2369,13 +2398,11 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
* 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);
-
/*
* Get pointer to mipmap level 1 data:
*/
@@ -2383,9 +2410,8 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
(gfloat*) gegl_sampler_get_from_mipmap (self,
ix_1,
iy_1,
- 1,
+ (gint) 1,
repeat_mode);
-
/*
* Position of the sampling location in the coordinate
* system defined by the mipmap "pixel locations"
@@ -2398,7 +2424,6 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
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:
*/
@@ -2408,155 +2433,213 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
*/
LOHALO_FIND_CLOSEST_INDICES(0,1)
/*
- * The "out" indices are the farthest relative mipmap
- * 1 indices we use at this level:
+ * The "out" indices are the farthest relative mipmap 1
+ * indices we use at this level:
*/
LOHALO_FIND_FARTHEST_INDICES(1)
-
/*
* Update using mipmap level 1 values.
*/
LOHALO_MIPMAP_EWA_UPDATE(1)
+
{
- /*
- * In order to know whether we use even higher
- * mipmap level values, we need to check whether
- * there is a level 2 mipmap location within the
- * ellipse. So, we need to determine the alignment
- * of the level 2 mipmap level w.r.t. the current
- * level 1.
- *
- * We use a LOHALO_SIZE_MIPMAPxLOHALO_SIZE_MIPMAP
- * context_rect at level 1; consequently, we can
- * access pixels which are LOHALO_OFFSET_MIPMAP away
- * from the level 1 anchor pixel location in box
- * distance.
- */
- /*
- * Determine whether the anchor level_1 pixel
- * locations are odd (VS even):
- */
- const gint odd_ix_1 = ix_1 % 2;
- const gint odd_iy_1 = iy_1 % 2;
- /*
- * Find the closest locations, on all four sides, of
- * level 2 pixels which involve data not found in
- * the level 1
- * LOHALO_SIZE_MIPMAPxLOHALO_SIZE_MIPMAP.
- */
- LOHALO_FIND_CLOSEST_LOCATIONS(1,2)
-
- if (( x_1 - bounding_box_half_width < closest_left_2 )
- ||
- ( x_1 + bounding_box_half_width > closest_rite_2 )
- ||
- ( y_1 - bounding_box_half_height < closest_top_2 )
- ||
- ( y_1 + bounding_box_half_height > closest_bot_2 ))
- {
- /*
- * We most likely need even higher mipmap
- * level(s) because the bounding box of the
- * ellipse covers mipmap pixel locations which
- * involve data not "covered" by the
- * LOHALO_SIZE_MIPMAP level 1 context_rect. (The
- * ellipse may still fail to involve mipmap
- * level 2 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_2 = LOHALO_FLOORED_DIVISION_BY_2(ix_1);
- const gint iy_2 = LOHALO_FLOORED_DIVISION_BY_2(iy_1);
-
- /*
- * Get pointer to mipmap level 2 data:
- */
- const gfloat* restrict input_bptr_2 =
- (gfloat*) gegl_sampler_get_from_mipmap (self,
- ix_2,
- iy_2,
- 2,
- repeat_mode);
-
- /*
- * Position of the sampling location in the
- * coordinate system defined by the mipmap
- * "pixel locations" relative to the level 1
- * anchor pixel location. The "-1"s are because
- * the center of a level 1 pixel is at a box
- * distance of 1 from the center of the closest
- * level 2 pixel.
- */
- const gfloat x_2 =
- x_1 + (gfloat) ( 2 * ( ix_1 - 2 * ix_2 ) - 1 );
- const gfloat y_2 =
- y_1 + (gfloat) ( 2 * ( iy_1 - 2 * iy_2 ) - 1 );
-
- /*
- * Key index ranges:
- */
- /*
- * The "in" indices are the closest relative
- * mipmap 2 indices of needed mipmap values:
- */
- LOHALO_FIND_CLOSEST_INDICES(1,2)
- /*
- * The "out" indices are the farthest relative
- * mipmap 1 indices we use at this level:
- */
- LOHALO_FIND_FARTHEST_INDICES(2)
-
- /*
- * Update using mipmap level 2 values.
- */
- LOHALO_MIPMAP_EWA_UPDATE(2)
- {
- /*
- * Third mipmap level.
- */
- const gint odd_ix_2 = ix_2 % 2;
- const gint odd_iy_2 = iy_2 % 2;
- LOHALO_FIND_CLOSEST_LOCATIONS(2,3)
-
- if (( x_2 - bounding_box_half_width <
- closest_left_3 )
- ||
- ( x_2 + bounding_box_half_width >
- closest_rite_3 )
- ||
- ( y_2 - bounding_box_half_height <
- closest_top_3 )
- ||
- ( y_2 + bounding_box_half_height >
- closest_bot_3 ))
- {
- const gint ix_3 =
- LOHALO_FLOORED_DIVISION_BY_2(ix_2);
- const gint iy_3 =
- LOHALO_FLOORED_DIVISION_BY_2(iy_2);
- const gfloat* restrict input_bptr_3 =
- (gfloat*) gegl_sampler_get_from_mipmap (self,
- ix_3,
- iy_3,
- 3,
- repeat_mode);
- const gfloat x_3 =
- x_2 + (gfloat) ( 2 * ( ix_2 - 2 * ix_3 ) - 1 );
- const gfloat y_3 =
- y_2 + (gfloat) ( 2 * ( iy_2 - 2 * iy_3 ) - 1 );
- LOHALO_FIND_CLOSEST_INDICES(2,3)
- LOHALO_FIND_FARTHEST_INDICES(3)
- LOHALO_MIPMAP_EWA_UPDATE(3)
- }
- }
- }
- }
- }
+ /*
+ * Second mipmap level.
+ */
+ const gint odd_ix_1 = ix_1 % 2;
+ const gint odd_iy_1 = iy_1 % 2;
+ LOHALO_FIND_CLOSEST_LOCATIONS(1,2)
+ if (( x_1 - bounding_box_half_width < closest_left_2 ) ||
+ ( x_1 + bounding_box_half_width > closest_rite_2 ) ||
+ ( y_1 - bounding_box_half_height < closest_top_2 ) ||
+ ( y_1 + bounding_box_half_height > closest_bot_2 ))
+ {
+ const gint ix_2 = LOHALO_FLOORED_DIVISION_BY_2(ix_1);
+ const gint iy_2 = LOHALO_FLOORED_DIVISION_BY_2(iy_1);
+ const gfloat* restrict input_bptr_2 =
+ (gfloat*) gegl_sampler_get_from_mipmap (self,
+ ix_2,
+ iy_2,
+ (gint) 2,
+ repeat_mode);
+ const gfloat x_2 =
+ x_1 + (gfloat) ( 2 * ( ix_1 - 2 * ix_2 ) - 1 );
+ const gfloat y_2 =
+ y_1 + (gfloat) ( 2 * ( iy_1 - 2 * iy_2 ) - 1 );
+ LOHALO_FIND_CLOSEST_INDICES(1,2)
+ LOHALO_FIND_FARTHEST_INDICES(2)
+ LOHALO_MIPMAP_EWA_UPDATE(2)
+
+ {
+ /*
+ * Third mipmap level.
+ */
+ const gint odd_ix_2 = ix_2 % 2;
+ const gint odd_iy_2 = iy_2 % 2;
+ LOHALO_FIND_CLOSEST_LOCATIONS(2,3)
+ if (( x_2 - bounding_box_half_width < closest_left_3 ) ||
+ ( x_2 + bounding_box_half_width > closest_rite_3 ) ||
+ ( y_2 - bounding_box_half_height < closest_top_3 ) ||
+ ( y_2 + bounding_box_half_height > closest_bot_3 ))
+ {
+ const gint ix_3 =
+ LOHALO_FLOORED_DIVISION_BY_2(ix_2);
+ const gint iy_3 =
+ LOHALO_FLOORED_DIVISION_BY_2(iy_2);
+ const gfloat* restrict input_bptr_3 =
+ (gfloat*) gegl_sampler_get_from_mipmap (self,
+ ix_3,
+ iy_3,
+ (gint) 3,
+ repeat_mode);
+ const gfloat x_3 =
+ x_2 + (gfloat) ( 2 * ( ix_2 - 2 * ix_3 ) - 1 );
+ const gfloat y_3 =
+ y_2 + (gfloat) ( 2 * ( iy_2 - 2 * iy_3 ) - 1 );
+ LOHALO_FIND_CLOSEST_INDICES(2,3)
+ LOHALO_FIND_FARTHEST_INDICES(3)
+ LOHALO_MIPMAP_EWA_UPDATE(3)
+
+ {
+ /*
+ * Fourth mipmap level.
+ */
+ const gint odd_ix_3 = ix_3 % 2;
+ const gint odd_iy_3 = iy_3 % 2;
+ LOHALO_FIND_CLOSEST_LOCATIONS(3,4)
+ if (( x_3 - bounding_box_half_width < closest_left_4 ) ||
+ ( x_3 + bounding_box_half_width > closest_rite_4 ) ||
+ ( y_3 - bounding_box_half_height < closest_top_4 ) ||
+ ( y_3 + bounding_box_half_height > closest_bot_4 ))
+ {
+ const gint ix_4 =
+ LOHALO_FLOORED_DIVISION_BY_2(ix_3);
+ const gint iy_4 =
+ LOHALO_FLOORED_DIVISION_BY_2(iy_3);
+ const gfloat* restrict input_bptr_4 =
+ (gfloat*) gegl_sampler_get_from_mipmap (self,
+ ix_4,
+ iy_4,
+ (gint) 4,
+ repeat_mode);
+ const gfloat x_4 =
+ x_3 + (gfloat) ( 2 * ( ix_3 - 2 * ix_4 ) - 1 );
+ const gfloat y_4 =
+ y_3 + (gfloat) ( 2 * ( iy_3 - 2 * iy_4 ) - 1 );
+ LOHALO_FIND_CLOSEST_INDICES(3,4)
+ LOHALO_FIND_FARTHEST_INDICES(4)
+ LOHALO_MIPMAP_EWA_UPDATE(4)
+
+ {
+ /*
+ * Fifth mipmap level.
+ */
+ const gint odd_ix_4 = ix_4 % 2;
+ const gint odd_iy_4 = iy_4 % 2;
+ LOHALO_FIND_CLOSEST_LOCATIONS(4,5)
+ if (( x_4 - bounding_box_half_width < closest_left_5 ) ||
+ ( x_4 + bounding_box_half_width > closest_rite_5 ) ||
+ ( y_4 - bounding_box_half_height < closest_top_5 ) ||
+ ( y_4 + bounding_box_half_height > closest_bot_5 ))
+ {
+ const gint ix_5 =
+ LOHALO_FLOORED_DIVISION_BY_2(ix_4);
+ const gint iy_5 =
+ LOHALO_FLOORED_DIVISION_BY_2(iy_4);
+ const gfloat* restrict input_bptr_5 =
+ (gfloat*) gegl_sampler_get_from_mipmap (self,
+ ix_5,
+ iy_5,
+ (gint) 5,
+ repeat_mode);
+ const gfloat x_5 =
+ x_4 + (gfloat) ( 2 * ( ix_4 - 2 * ix_5 ) - 1 );
+ const gfloat y_5 =
+ y_4 + (gfloat) ( 2 * ( iy_4 - 2 * iy_5 ) - 1 );
+ LOHALO_FIND_CLOSEST_INDICES(4,5)
+ LOHALO_FIND_FARTHEST_INDICES(5)
+ LOHALO_MIPMAP_EWA_UPDATE(5)
+
+ {
+ /*
+ * Sixth mipmap level.
+ */
+ const gint odd_ix_5 = ix_5 % 2;
+ const gint odd_iy_5 = iy_5 % 2;
+ LOHALO_FIND_CLOSEST_LOCATIONS(5,6)
+ if (( x_5 - bounding_box_half_width
+ < closest_left_6 ) ||
+ ( x_5 + bounding_box_half_width
+ > closest_rite_6 ) ||
+ ( y_5 - bounding_box_half_height
+ < closest_top_6 ) ||
+ ( y_5 + bounding_box_half_height
+ > closest_bot_6 ))
+ {
+ const gint ix_6 = LOHALO_FLOORED_DIVISION_BY_2(ix_5);
+ const gint iy_6 = LOHALO_FLOORED_DIVISION_BY_2(iy_5);
+ const gfloat* restrict input_bptr_6 = (gfloat*)
+ gegl_sampler_get_from_mipmap (self,
+ ix_6,
+ iy_6,
+ (gint) 6,
+ repeat_mode);
+ const gfloat x_6 =
+ x_5 + (gfloat) ( 2 * ( ix_5 - 2 * ix_6 ) - 1 );
+ const gfloat y_6 =
+ y_5 + (gfloat) ( 2 * ( iy_5 - 2 * iy_6 ) - 1 );
+ LOHALO_FIND_CLOSEST_INDICES(5,6)
+ LOHALO_FIND_FARTHEST_INDICES(6)
+ LOHALO_MIPMAP_EWA_UPDATE(6)
+
+ {
+ /*
+ * Seventh mipmap level (eight if counted
+ * from zero = straight up).
+ */
+ const gint odd_ix_6 = ix_6 % 2;
+ const gint odd_iy_6 = iy_6 % 2;
+ LOHALO_FIND_CLOSEST_LOCATIONS(6,7)
+ if (( x_6 - bounding_box_half_width
+ < closest_left_7 ) ||
+ ( x_6 + bounding_box_half_width
+ > closest_rite_7 ) ||
+ ( y_6 - bounding_box_half_height
+ < closest_top_7 ) ||
+ ( y_6 + bounding_box_half_height
+ > closest_bot_7 ))
+ {
+ const gint ix_7 =
+ LOHALO_FLOORED_DIVISION_BY_2(ix_6);
+ const gint iy_7 =
+ LOHALO_FLOORED_DIVISION_BY_2(iy_6);
+ const gfloat* restrict input_bptr_7 = (gfloat*)
+ gegl_sampler_get_from_mipmap (self,
+ ix_7,
+ iy_7,
+ (gint) 7,
+ repeat_mode);
+ const gfloat x_7 =
+ x_6 + (gfloat) ( 2 * ( ix_6 - 2 * ix_7 ) - 1 );
+ const gfloat y_7 =
+ y_6 + (gfloat) ( 2 * ( iy_6 - 2 * iy_7 ) - 1 );
+ LOHALO_FIND_CLOSEST_INDICES(6,7)
+ LOHALO_FIND_FARTHEST_INDICES(7)
+ LOHALO_MIPMAP_EWA_UPDATE(7)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
{
/*
* Blend the LBB-Nohalo and EWA results:
diff --git a/gegl/buffer/gegl-sampler.h b/gegl/buffer/gegl-sampler.h
index bec1c1c..bee4bc0 100644
--- a/gegl/buffer/gegl-sampler.h
+++ b/gegl/buffer/gegl-sampler.h
@@ -36,7 +36,7 @@ G_BEGIN_DECLS
* This should be set to the largest number of mipmap levels (counted
* starting at 0 = no box filtering) actually used by any sampler.
*/
-#define GEGL_SAMPLER_MIPMAP_LEVELS (4)
+#define GEGL_SAMPLER_MIPMAP_LEVELS (8)
/*
* Best thing to do seems to use rectangular buffer tiles that are
* twice as wide as they are tall.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]