[gegl] samplers use rectangular tiles
- From: Nicolas Robidoux <nrobidoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] samplers use rectangular tiles
- Date: Thu, 20 Dec 2012 18:41:00 +0000 (UTC)
commit 9025ff2fc1f0e38635130c7fbc4c5f65ed71a94f
Author: Nicolas Robidoux <nrobidoux git gnome org>
Date: Thu Dec 20 13:40:59 2012 -0500
samplers use rectangular tiles
gegl/buffer/gegl-sampler-cubic.c | 8 ++--
gegl/buffer/gegl-sampler-linear.c | 4 +-
gegl/buffer/gegl-sampler-lohalo.c | 6 ++--
gegl/buffer/gegl-sampler.c | 40 +++++++++++----------
gegl/buffer/gegl-sampler.h | 2 +-
operations/transform/transform-core.c | 64 ++++++++++++++++++--------------
6 files changed, 67 insertions(+), 57 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler-cubic.c b/gegl/buffer/gegl-sampler-cubic.c
index 8448adf..33ba4b5 100644
--- a/gegl/buffer/gegl-sampler-cubic.c
+++ b/gegl/buffer/gegl-sampler-cubic.c
@@ -167,10 +167,10 @@ gegl_sampler_cubic_get ( GeglSampler *self,
{
GeglSamplerCubic *cubic = (GeglSamplerCubic*)(self);
const gint offsets[16] =
- {-4-GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT *4, 4, 4, 4,
- (GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT-3)*4, 4, 4, 4,
- (GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT-3)*4, 4, 4, 4,
- (GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT-3)*4, 4, 4, 4};
+ {-4-2*GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT *4, 4, 4, 4,
+ (2*GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT-3)*4, 4, 4, 4,
+ (2*GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT-3)*4, 4, 4, 4,
+ (2*GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT-3)*4, 4, 4, 4};
gfloat *sampler_bptr;
gfloat factor;
gfloat newval[4] = {0.0, 0.0, 0.0, 0.0};
diff --git a/gegl/buffer/gegl-sampler-linear.c b/gegl/buffer/gegl-sampler-linear.c
index bb63b76..88c8da4 100644
--- a/gegl/buffer/gegl-sampler-linear.c
+++ b/gegl/buffer/gegl-sampler-linear.c
@@ -66,7 +66,7 @@ gegl_sampler_linear_class_init (GeglSamplerLinearClass *klass)
* 0 if it is found that round off error never sends things "too far
* away". Nicolas would be very surprised if more than 1 is necessary.
*/
-#define LINEAR_EXTRA_ELBOW_ROOM 1
+#define LINEAR_EXTRA_ELBOW_ROOM 0
static void
gegl_sampler_linear_init (GeglSamplerLinear *self)
@@ -86,7 +86,7 @@ gegl_sampler_linear_get ( GeglSampler* restrict self,
void* restrict output,
GeglAbyssPolicy repeat_mode)
{
- const gint pixels_per_buffer_row = GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT;
+ const gint pixels_per_buffer_row = (gint) 2 * GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT;
const gint channels = 4;
/*
diff --git a/gegl/buffer/gegl-sampler-lohalo.c b/gegl/buffer/gegl-sampler-lohalo.c
index 07b09c3..20a142e 100644
--- a/gegl/buffer/gegl-sampler-lohalo.c
+++ b/gegl/buffer/gegl-sampler-lohalo.c
@@ -411,7 +411,7 @@ gegl_sampler_lohalo_class_init (GeglSamplerLohaloClass *klass)
/*
* IMPORTANT: LOHALO_OFFSET_0 SHOULD BE AN INTEGER >= 2.
*/
-#define LOHALO_OFFSET_0 (8)
+#define LOHALO_OFFSET_0 (7)
#define LOHALO_SIZE_0 ( 1 + 2 * LOHALO_OFFSET_0 )
/*
@@ -424,7 +424,7 @@ gegl_sampler_lohalo_class_init (GeglSamplerLohaloClass *klass)
* mipmap level's offset should almost never be smaller than half the
* previous level's offset.
*/
-#define LOHALO_OFFSET_MIPMAP (8)
+#define LOHALO_OFFSET_MIPMAP (7)
#define LOHALO_SIZE_MIPMAP ( 1 + 2 * LOHALO_OFFSET_MIPMAP )
#define LOHALO_OFFSET_1 LOHALO_OFFSET_MIPMAP
@@ -1442,7 +1442,7 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
* corresponds to fetch_rectangle.width in gegl_sampler_get_ptr.
*/
const gint channels = 4;
- const gint pixels_per_row = GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT;
+ const gint pixels_per_row = (gint) 2 * GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT;
const gint row_skip = channels * pixels_per_row;
/*
diff --git a/gegl/buffer/gegl-sampler.c b/gegl/buffer/gegl-sampler.c
index f2bc629..bd2a273 100644
--- a/gegl/buffer/gegl-sampler.c
+++ b/gegl/buffer/gegl-sampler.c
@@ -227,8 +227,10 @@ gegl_sampler_get_ptr (GeglSampler *const sampler,
*/
const gint maximum_width_and_height =
GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT;
- g_assert (sampler->context_rect[0].width <= maximum_width_and_height);
- g_assert (sampler->context_rect[0].height <= maximum_width_and_height);
+ g_assert (sampler->context_rect[0].width <=
+ (gint) 2 * maximum_width_and_height);
+ g_assert (sampler->context_rect[0].height <=
+ maximum_width_and_height);
if ((sampler->sampler_buffer[0] == NULL)
||
@@ -267,14 +269,14 @@ gegl_sampler_get_ptr (GeglSampler *const sampler,
*/
fetch_rectangle.x =
x + sampler->context_rect[0].x -
- (maximum_width_and_height - sampler->context_rect[0].width ) /
- (gint) 8;
+ ((gint) 2 * maximum_width_and_height - sampler->context_rect[0].width ) /
+ (gint) 4;
fetch_rectangle.y =
y + sampler->context_rect[0].y -
(maximum_width_and_height - sampler->context_rect[0].height) /
- (gint) 8;
+ (gint) 4;
- fetch_rectangle.width = maximum_width_and_height;
+ fetch_rectangle.width = (gint) 2 * maximum_width_and_height;
fetch_rectangle.height = maximum_width_and_height;
if (sampler->sampler_buffer[0] == NULL)
@@ -283,7 +285,7 @@ gegl_sampler_get_ptr (GeglSampler *const sampler,
* Always request the same amount of pixels:
*/
sampler->sampler_buffer[0] =
- g_malloc0 (( maximum_width_and_height * maximum_width_and_height )
+ g_malloc0 (( (gint) 2 * maximum_width_and_height * maximum_width_and_height )
* bpp);
}
@@ -327,7 +329,7 @@ gegl_sampler_get_from_buffer (GeglSampler *const sampler,
*/
const gint maximum_width_and_height =
GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT;
- g_assert (sampler->context_rect[0].width <= maximum_width_and_height);
+ g_assert (sampler->context_rect[0].width <= (gint) 2 * maximum_width_and_height);
g_assert (sampler->context_rect[0].height <= maximum_width_and_height);
if ((sampler->sampler_buffer[0] == NULL)
@@ -349,13 +351,13 @@ gegl_sampler_get_from_buffer (GeglSampler *const sampler,
GeglRectangle fetch_rectangle;
fetch_rectangle.x = x -
- (maximum_width_and_height - sampler->context_rect[0].width ) /
- (gint) 8;
+ ((gint) 2 * maximum_width_and_height - sampler->context_rect[0].width ) /
+ (gint) 4;
fetch_rectangle.y = y -
(maximum_width_and_height - sampler->context_rect[0].height) /
- (gint) 8;
+ (gint) 4;
- fetch_rectangle.width = maximum_width_and_height;
+ fetch_rectangle.width = (gint) 2 * maximum_width_and_height;
fetch_rectangle.height = maximum_width_and_height;
if (sampler->sampler_buffer[0] == NULL)
@@ -364,7 +366,7 @@ gegl_sampler_get_from_buffer (GeglSampler *const sampler,
* Always request the same amount of pixels:
*/
sampler->sampler_buffer[0] =
- g_malloc0 (( maximum_width_and_height * maximum_width_and_height )
+ g_malloc0 (( (gint) 2 * maximum_width_and_height * maximum_width_and_height )
* bpp);
}
@@ -411,7 +413,7 @@ gegl_sampler_get_from_mipmap (GeglSampler *const sampler,
*/
const gint maximum_width_and_height =
GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT;
- g_assert (sampler->context_rect[level].width <= maximum_width_and_height);
+ g_assert (sampler->context_rect[level].width <= (gint) 2 * maximum_width_and_height);
g_assert (sampler->context_rect[level].height <= maximum_width_and_height);
g_assert (level >= 0 && level < GEGL_SAMPLER_MIPMAP_LEVELS);
@@ -441,14 +443,14 @@ gegl_sampler_get_from_mipmap (GeglSampler *const sampler,
fetch_rectangle.x =
x + sampler->context_rect[level].x -
- (maximum_width_and_height - sampler->context_rect[level].width ) /
- (gint) 8;
+ ((gint) 2 * maximum_width_and_height - sampler->context_rect[level].width ) /
+ (gint) 4;
fetch_rectangle.y =
y + sampler->context_rect[level].y -
(maximum_width_and_height - sampler->context_rect[level].height) /
- (gint) 8;
+ (gint) 4;
- fetch_rectangle.width = maximum_width_and_height;
+ fetch_rectangle.width = (gint) 2 * maximum_width_and_height;
fetch_rectangle.height = maximum_width_and_height;
if (sampler->sampler_buffer[level] == NULL)
@@ -457,7 +459,7 @@ gegl_sampler_get_from_mipmap (GeglSampler *const sampler,
* Always request the same amount of pixels:
*/
sampler->sampler_buffer[level] =
- g_malloc0 (( maximum_width_and_height * maximum_width_and_height )
+ g_malloc0 (( (gint) 2 * maximum_width_and_height * maximum_width_and_height )
* bpp);
}
diff --git a/gegl/buffer/gegl-sampler.h b/gegl/buffer/gegl-sampler.h
index 7b01ef3..c894067 100644
--- a/gegl/buffer/gegl-sampler.h
+++ b/gegl/buffer/gegl-sampler.h
@@ -41,7 +41,7 @@ G_BEGIN_DECLS
* The way the samplers use mipmap levels, square buffers are
* preferable to rectangular ones.
*/
-#define GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT 64
+#define GEGL_SAMPLER_MAXIMUM_WIDTH_AND_HEIGHT 32
typedef struct _GeglSamplerClass GeglSamplerClass;
diff --git a/operations/transform/transform-core.c b/operations/transform/transform-core.c
index 1723726..6b4e61b 100644
--- a/operations/transform/transform-core.c
+++ b/operations/transform/transform-core.c
@@ -839,27 +839,26 @@ transform_affine (GeglBuffer *dest,
*
* Explanation:
*
- * GEGL uses square buffer tiles in "output space", which this
- * function fills with data. Pulling a scanline (within such a
- * square tile) back to input space (with the inverse
+ * GEGL uses wider than tall rectangular buffer tiles in "output
+ * space", which this function fills with data. Pulling a scanline
+ * (within such a square tile) back to input space (with the inverse
* transformation) with an arbitrary affine transformation may make
* the scanline go from right to left in input space even though it
* goes form left to right in input space. Similarly, a scanline
* which is below the first one in output space may be above in
- * input space. Unfortunately, input buffer tiles (which are square)
- * are allocated with a bias: less elbow room around the
- * context_rect (square of data needed by the sampler) is put at the
- * left and top than at the right and bottom. (Such asymetrical
- * elbow room is beneficial when resizing, for example, since input
- * space is then traversed from left to right and top to bottom,
- * which means that the left and top elbow room is not used in this
- * situation.) When the affine transformation "flips" things,
- * however, the elbow room is "on the wrong side", and for this
- * reason such transformations run much much slower because many
- * more input buffer tiles get created. One way to make things
- * better is to traverse the output buffer tile in an appropriate
- * chosen "reverse order" so that the "short" elbow room is "behind"
- * instead of "ahead".
+ * input space. Unfortunately, input buffer tiles are allocated with
+ * a bias: less elbow room around the context_rect (square of data
+ * needed by the sampler) is put at the left and top than at the
+ * right and bottom. (Such asymetrical elbow room is beneficial when
+ * resizing, for example, since input space is then traversed from
+ * left to right and top to bottom, which means that the left and
+ * top elbow room is not used in this situation.) When the affine
+ * transformation "flips" things, however, the elbow room is "on the
+ * wrong side", and for this reason such transformations run much
+ * much slower because many more input buffer tiles get created. One
+ * way to make things better is to traverse the output buffer tile
+ * in an appropriate chosen "reverse order" so that the "short"
+ * elbow room is "behind" instead of "ahead".
*
* Things are actually a bit more complicated than that. Here is a
* terse description of what's actually done, without a full
@@ -872,13 +871,13 @@ transform_affine (GeglBuffer *dest,
* input tile? Because the input tile is square and most of the
* extra elbow room is at the bottom and right, the "best" direction
* is going down the diagonal of the square, approximately from top
- * left to bottom right.
+ * left to bottom right of the tile.
*
* Of course, we do not have control over the actual line traced by
* the output scanline in input space. But what the above tells us
* is that if the inner product of the pulled back "scanline vector"
- * with the vector (1,1) (which corresponds to going diagonally from
- * top-left to bottom-right in images) is negative, we are going
+ * with the vector (2,1) (which corresponds to going diagonally from
+ * top-left to bottom-right in the tile) is negative, we are going
* opposite to "best". This can be rectified by filling the output
* scanline in reverse order: from right to left in output space.
*
@@ -887,7 +886,7 @@ transform_affine (GeglBuffer *dest,
* likely to "stick out". Repeating the same argument used for a
* single scanline, we see that the sign of the inner product of the
* inverse image of the vector that points straight down in output
- * space with the input space vector (1,1) tells us whether we
+ * space with the input space vector (2,1) tells us whether we
* should fill the output tile from the top down or from the bottom
* up.
*
@@ -919,8 +918,14 @@ transform_affine (GeglBuffer *dest,
* coordinate axes, or a centered disc, matters, irrespective of
* orientation ("left-hand" VS "right-hand") issues.
*/
+ /*
+ * The criterion for flipping is based on tiles that are twice as
+ * wide as high. This is where the "(gdouble) 2. *" comes from:
+ * inner product with the vector (2,1).
+ */
- if (inverse.coeff [0][0] + inverse.coeff [1][0] < (gdouble) 0.0)
+ if ((gdouble) 2. * inverse.coeff [0][0] + inverse.coeff [1][0] <
+ (gdouble) 0.)
{
/*
* Flip the horizontal scan component of the inverse jacobian:
@@ -934,7 +939,8 @@ transform_affine (GeglBuffer *dest,
flip_x = (gint) 1;
}
- if (inverse.coeff [0][1] + inverse.coeff [1][1] < (gdouble) 0.0)
+ if ((gdouble) 2. * inverse.coeff [0][1] + inverse.coeff [1][1] <
+ (gdouble) 0.)
{
/*
* Flip the vertical scan component of the inverse jacobian:
@@ -1037,9 +1043,9 @@ transform_generic (GeglBuffer *dest,
/*
* 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
+ * given that these wider than tall "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.
@@ -1066,7 +1072,8 @@ transform_generic (GeglBuffer *dest,
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)
+ if (((gdouble) 2. * u_float + v_float)/w_float <
+ ((gdouble) 2. * u_start + v_start)/w_start)
{
/*
* Move to the start of the last "scanline".
@@ -1095,7 +1102,8 @@ 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);
- bflip_x = ((u_float + v_float)/w_float < (u_start + v_start)/w_start)
+ bflip_x = (((gdouble) 2. * u_float + v_float)/w_float <
+ ((gdouble) 2. * u_start + v_start)/w_start)
?
(gint) 1
:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]