[gegl] buffer: use calling sampler for sub-sampling during box filtering
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: use calling sampler for sub-sampling during box filtering
- Date: Sat, 17 Nov 2018 17:03:21 +0000 (UTC)
commit 37a1f5774f01f142f3bddd620383975aca0e860a
Author: Ell <ell_se yahoo com>
Date: Sat Nov 17 11:53:30 2018 -0500
buffer: use calling sampler for sub-sampling during box filtering
When performing box filtering, in the linear and cubic samplers,
use the calling sampler to sub-sample the buffer, instead of using
a separate sampler of a different type. This allows us to perform
box filtering even when downscaling only along one direction,
without loss of quality or discontinuity, undoing
commit 662b9c35f5e052f94268ea0aea59923ed23b10bb.
Note that this can make box filtering slower, since we used to use
a cheaper sampler for sub-sampling. This is somewhat countered by
reducing the number of sub-samples.
gegl/buffer/gegl-sampler-cubic.c | 3 +-
gegl/buffer/gegl-sampler-linear.c | 3 +-
gegl/buffer/gegl-sampler.c | 2 --
gegl/buffer/gegl-sampler.h | 43 +++++++++-----------------
tests/compositions/reference/clones.png | Bin 724878 -> 729480 bytes
tests/compositions/reference/simple-scale.png | Bin 463 -> 758 bytes
6 files changed, 16 insertions(+), 35 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler-cubic.c b/gegl/buffer/gegl-sampler-cubic.c
index 4e1997ea9..f9f9c6ad7 100644
--- a/gegl/buffer/gegl-sampler-cubic.c
+++ b/gegl/buffer/gegl-sampler-cubic.c
@@ -161,8 +161,7 @@ gegl_sampler_cubic_get ( GeglSampler *self,
GeglAbyssPolicy repeat_mode)
{
if (! _gegl_sampler_box_get (self, absolute_x, absolute_y, scale,
- output, repeat_mode,
- GEGL_SAMPLER_LINEAR, 5))
+ output, repeat_mode, 5))
{
GeglSamplerCubic *cubic = (GeglSamplerCubic*)(self);
gint components = self->interpolate_components;
diff --git a/gegl/buffer/gegl-sampler-linear.c b/gegl/buffer/gegl-sampler-linear.c
index 911992637..fa3b46701 100644
--- a/gegl/buffer/gegl-sampler-linear.c
+++ b/gegl/buffer/gegl-sampler-linear.c
@@ -82,8 +82,7 @@ gegl_sampler_linear_get ( GeglSampler *self,
{
gint nc = self->interpolate_components;
if (! _gegl_sampler_box_get (self, absolute_x, absolute_y, scale,
- output, repeat_mode,
- GEGL_SAMPLER_NEAREST, 4))
+ output, repeat_mode, 4))
{
const gint pixels_per_buffer_row = GEGL_SAMPLER_MAXIMUM_WIDTH;
diff --git a/gegl/buffer/gegl-sampler.c b/gegl/buffer/gegl-sampler.c
index fd7d52b02..8d569a2a0 100644
--- a/gegl/buffer/gegl-sampler.c
+++ b/gegl/buffer/gegl-sampler.c
@@ -279,8 +279,6 @@ dispose (GObject *gobject)
/* This call handles unreffing the buffer and disconnecting signals */
set_buffer (sampler, NULL);
- g_clear_object (&sampler->point_sampler);
-
G_OBJECT_CLASS (gegl_sampler_parent_class)->dispose (gobject);
}
diff --git a/gegl/buffer/gegl-sampler.h b/gegl/buffer/gegl-sampler.h
index 40091eae8..e2d399318 100644
--- a/gegl/buffer/gegl-sampler.h
+++ b/gegl/buffer/gegl-sampler.h
@@ -59,8 +59,8 @@ typedef struct GeglSamplerLevel
struct _GeglSampler
{
- GObject parent_instance;
- GeglSamplerGetFun get;
+ GObject parent_instance;
+ GeglSamplerGetFun get;
/*< private >*/
GeglBuffer *buffer;
@@ -70,8 +70,6 @@ struct _GeglSampler
const Babl *fish;
gint interpolate_bpp;
gint interpolate_components;
- GeglSampler *point_sampler;
- GeglSamplerGetFun point_sampler_get_fun;
GeglSamplerLevel level[GEGL_SAMPLER_MIPMAP_LEVELS];
};
@@ -226,8 +224,7 @@ _gegl_sampler_box_get (GeglSampler* restrict self,
GeglBufferMatrix2 *scale,
void* restrict output,
GeglAbyssPolicy repeat_mode,
- GeglSamplerType point_sampler_type,
- gint n_samples)
+ gint max_n_samples)
{
gint channels = self->interpolate_components;
if (scale)
@@ -237,8 +234,7 @@ _gegl_sampler_box_get (GeglSampler* restrict self,
const gdouble v_norm2 = scale->coeff[0][1] * scale->coeff[0][1] +
scale->coeff[1][1] * scale->coeff[1][1];
- if ((u_norm2 >= 4.0 && v_norm2 >= 1.0) ||
- (v_norm2 >= 4.0 && u_norm2 >= 1.0))
+ if (u_norm2 >= 4.0 || v_norm2 >= 4.0)
{
gfloat result[channels];
gdouble uv_samples_inv;
@@ -246,23 +242,14 @@ _gegl_sampler_box_get (GeglSampler* restrict self,
for (gint c = 0; c < channels; c++)
result[c] = 0.0f;
- if (! self->point_sampler)
- {
- self->point_sampler = gegl_buffer_sampler_new (self->buffer,
- self->format,
- point_sampler_type);
- self->point_sampler_get_fun =
- gegl_sampler_get_fun (self->point_sampler);
- }
-
if (gegl_buffer_matrix2_is_scale (scale))
{
const gdouble u_norm = fabs (scale->coeff[0][0]);
const gdouble v_norm = fabs (scale->coeff[1][1]);
- const gint u_norm_i = ceil (u_norm);
- const gint v_norm_i = ceil (v_norm);
- const gint u_samples = MIN (u_norm_i, n_samples);
- const gint v_samples = MIN (v_norm_i, n_samples);
+ const gint u_norm_i = floor (u_norm);
+ const gint v_norm_i = floor (v_norm);
+ const gint u_samples = CLAMP (u_norm_i, 1, max_n_samples);
+ const gint v_samples = CLAMP (v_norm_i, 1, max_n_samples);
const gdouble u_samples_inv = 1.0 / u_samples;
const gdouble v_samples_inv = 1.0 / v_samples;
const gdouble u_dx = scale->coeff[0][0] * u_samples_inv;
@@ -285,8 +272,7 @@ _gegl_sampler_box_get (GeglSampler* restrict self,
{
int c;
gfloat input[4];
- self->point_sampler_get_fun (self->point_sampler,
- x, y, NULL, input, repeat_mode);
+ self->get (self, x, y, NULL, input, repeat_mode);
for (c = 0; c < 4; c++)
result[c] += input[c];
@@ -300,10 +286,10 @@ _gegl_sampler_box_get (GeglSampler* restrict self,
{
const gdouble u_norm = sqrt (u_norm2);
const gdouble v_norm = sqrt (v_norm2);
- const gint u_norm_i = ceil (u_norm);
- const gint v_norm_i = ceil (v_norm);
- const gint u_samples = MIN (u_norm_i, n_samples);
- const gint v_samples = MIN (v_norm_i, n_samples);
+ const gint u_norm_i = floor (u_norm);
+ const gint v_norm_i = floor (v_norm);
+ const gint u_samples = CLAMP (u_norm_i, 1, max_n_samples);
+ const gint v_samples = CLAMP (v_norm_i, 1, max_n_samples);
const gdouble u_samples_inv = 1.0 / u_samples;
const gdouble v_samples_inv = 1.0 / v_samples;
const gdouble u_dx = scale->coeff[0][0] * u_samples_inv;
@@ -330,8 +316,7 @@ _gegl_sampler_box_get (GeglSampler* restrict self,
{
int c;
gfloat input[channels];
- self->point_sampler_get_fun (self->point_sampler,
- x, y, NULL, input, repeat_mode);
+ self->get (self, x, y, NULL, input, repeat_mode);
for (c = 0; c < channels; c++)
result[c] += input[c];
diff --git a/tests/compositions/reference/clones.png b/tests/compositions/reference/clones.png
index 67c8f7dc0..1d82808d0 100644
Binary files a/tests/compositions/reference/clones.png and b/tests/compositions/reference/clones.png differ
diff --git a/tests/compositions/reference/simple-scale.png b/tests/compositions/reference/simple-scale.png
index 0da98a527..f0243e88b 100644
Binary files a/tests/compositions/reference/simple-scale.png and
b/tests/compositions/reference/simple-scale.png differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]