[gegl] buffer: samplers handling dynamic number of components
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: samplers handling dynamic number of components
- Date: Wed, 31 Oct 2018 00:24:32 +0000 (UTC)
commit 365e53a5b8f1d75f7caa05c90faddb4ea3d2fa93
Author: Øyvind Kolås <pippin gimp org>
Date: Tue Oct 30 22:03:57 2018 +0100
buffer: samplers handling dynamic number of components
All resampling for GeglBuffers used to happen in RaGaBaA float, now
grayscale formats end up using YaA float instead, which will improve
performance of scaling/rotating in GIMP as well as other tools using
GeglBuffers resampling like the sculpt tool when in grayscale mode.
buffer: add members for interpolation bpp/components
buffer: make linear sampler component generic
buffer: generalize cubic sampler
buffer: generalize lohalo innerloop
For now, assuming that input is still a premultiplied format and treat last component
differently, should sniff whether the interpolation format has alpha and only do
different treatment in that case.
buffer: generalize nohalo for components
buffer: nohalo slight simplification
foo
gegl/buffer/gegl-sampler-cubic.c | 24 ++-
gegl/buffer/gegl-sampler-linear.c | 84 +++------
gegl/buffer/gegl-sampler-lohalo.c | 123 +++++-------
gegl/buffer/gegl-sampler-nohalo.c | 386 ++++++++------------------------------
gegl/buffer/gegl-sampler.c | 51 ++++-
gegl/buffer/gegl-sampler.h | 24 +--
6 files changed, 219 insertions(+), 473 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler-cubic.c b/gegl/buffer/gegl-sampler-cubic.c
index b67a625c8..4e1997ea9 100644
--- a/gegl/buffer/gegl-sampler-cubic.c
+++ b/gegl/buffer/gegl-sampler-cubic.c
@@ -15,6 +15,7 @@
*
* Copyright 2012 Nicolas Robidoux based on earlier code
* 2012 Massimo Valentini
+ * 2018 Øyvind Kolås <pippin gimp org>
*/
#include "config.h"
@@ -164,16 +165,18 @@ gegl_sampler_cubic_get ( GeglSampler *self,
GEGL_SAMPLER_LINEAR, 5))
{
GeglSamplerCubic *cubic = (GeglSamplerCubic*)(self);
+ gint components = self->interpolate_components;
const gint offsets[16] = {
- -4-GEGL_SAMPLER_MAXIMUM_WIDTH *4, 4, 4, 4,
- (GEGL_SAMPLER_MAXIMUM_WIDTH-3)*4, 4, 4, 4,
- (GEGL_SAMPLER_MAXIMUM_WIDTH-3)*4, 4, 4, 4,
- (GEGL_SAMPLER_MAXIMUM_WIDTH-3)*4, 4, 4, 4
+ -components-GEGL_SAMPLER_MAXIMUM_WIDTH *components, components,
components, components,
+ (GEGL_SAMPLER_MAXIMUM_WIDTH-3)*components, components, components,
components,
+ (GEGL_SAMPLER_MAXIMUM_WIDTH-3)*components, components, components,
components,
+ (GEGL_SAMPLER_MAXIMUM_WIDTH-3)*components, components, components,
components
};
gfloat *sampler_bptr;
gfloat factor;
- gfloat newval[4] = {0, 0, 0, 0};
- gint i,
+ gfloat newval[components];
+ gint c,
+ i,
j,
k = 0;
@@ -204,6 +207,9 @@ gegl_sampler_cubic_get ( GeglSampler *self,
sampler_bptr = gegl_sampler_get_ptr (self, ix, iy, repeat_mode);
+ for (c = 0; c < components; c++)
+ newval[c] = 0.0f;
+
for (j=-1; j<3; j++)
for (i=-1; i<3; i++)
{
@@ -212,10 +218,8 @@ gegl_sampler_cubic_get ( GeglSampler *self,
factor = cubicKernel (y - j, cubic->b, cubic->c) *
cubicKernel (x - i, cubic->b, cubic->c);
- newval[0] += factor * sampler_bptr[0];
- newval[1] += factor * sampler_bptr[1];
- newval[2] += factor * sampler_bptr[2];
- newval[3] += factor * sampler_bptr[3];
+ for (c = 0; c < components; c++)
+ newval[c] += factor * sampler_bptr[c];
}
babl_process (self->fish, newval, output, 1);
diff --git a/gegl/buffer/gegl-sampler-linear.c b/gegl/buffer/gegl-sampler-linear.c
index a96391bb1..911992637 100644
--- a/gegl/buffer/gegl-sampler-linear.c
+++ b/gegl/buffer/gegl-sampler-linear.c
@@ -77,15 +77,15 @@ gegl_sampler_linear_get ( GeglSampler *self,
const gdouble absolute_x,
const gdouble absolute_y,
GeglBufferMatrix2 *scale,
- void *output,
- GeglAbyssPolicy repeat_mode)
+ void *output,
+ GeglAbyssPolicy repeat_mode)
{
+ gint nc = self->interpolate_components;
if (! _gegl_sampler_box_get (self, absolute_x, absolute_y, scale,
output, repeat_mode,
GEGL_SAMPLER_NEAREST, 4))
{
const gint pixels_per_buffer_row = GEGL_SAMPLER_MAXIMUM_WIDTH;
- const gint channels = 4;
/*
* The "-1/2"s are there because we want the index of the pixel to
@@ -125,16 +125,16 @@ gegl_sampler_linear_get ( GeglSampler *self,
/*
* Load top row:
*/
- const gfloat top_left_0 = *in_bptr++;
- const gfloat top_left_1 = *in_bptr++;
- const gfloat top_left_2 = *in_bptr++;
- const gfloat top_left_3 = *in_bptr++;
- const gfloat top_rite_0 = *in_bptr++;
- const gfloat top_rite_1 = *in_bptr++;
- const gfloat top_rite_2 = *in_bptr++;
- const gfloat top_rite_3 = *in_bptr;
+ gfloat top_left[nc];
+ gfloat top_rite[nc];
- in_bptr += 1 + ( pixels_per_buffer_row - 2 ) * channels;
+ for (gint c = 0; c < nc; c++)
+ top_left[c] = *in_bptr++;
+
+ for (gint c = 0; c < nc; c++)
+ top_rite[c] = *in_bptr++;
+
+ in_bptr += ( pixels_per_buffer_row - 2 ) * nc;
{
/*
@@ -148,59 +148,33 @@ gegl_sampler_linear_get ( GeglSampler *self,
/*
* Load bottom row:
*/
- const gfloat bot_left_0 = *in_bptr++;
- const gfloat bot_left_1 = *in_bptr++;
- const gfloat bot_left_2 = *in_bptr++;
- const gfloat bot_left_3 = *in_bptr++;
- const gfloat bot_rite_0 = *in_bptr++;
- const gfloat bot_rite_1 = *in_bptr++;
- const gfloat bot_rite_2 = *in_bptr++;
- const gfloat bot_rite_3 = *in_bptr;
+ gfloat bot_left[4];
+ gfloat bot_rite[4];
+ for (gint c = 0; c < nc; c++)
+ bot_left[c] = *in_bptr++;
+ for (gint c = 0; c < nc; c++)
+ bot_rite[c] = *in_bptr++;
/*
* Last bilinear weight:
*/
+ {
const gfloat w_times_z = (gfloat) 1. - ( x + w_times_y );
gfloat newval[4];
- newval[0] =
- x_times_y * bot_rite_0
- +
- w_times_y * bot_left_0
- +
- x_times_z * top_rite_0
- +
- w_times_z * top_left_0;
-
- newval[1] =
- x_times_y * bot_rite_1
- +
- w_times_y * bot_left_1
- +
- x_times_z * top_rite_1
- +
- w_times_z * top_left_1;
-
- newval[2] =
- x_times_y * bot_rite_2
- +
- w_times_y * bot_left_2
- +
- x_times_z * top_rite_2
- +
- w_times_z * top_left_2;
-
- newval[3] =
- x_times_y * bot_rite_3
- +
- w_times_y * bot_left_3
- +
- x_times_z * top_rite_3
- +
- w_times_z * top_left_3;
+ for (gint c = 0; c < nc; c++)
+ newval[c] =
+ x_times_y * bot_rite[c]
+ +
+ w_times_y * bot_left[c]
+ +
+ x_times_z * top_rite[c]
+ +
+ w_times_z * top_left[c];
babl_process (self->fish, newval, output, 1);
}
+ }
}
}
diff --git a/gegl/buffer/gegl-sampler-lohalo.c b/gegl/buffer/gegl-sampler-lohalo.c
index 8bb31f7f3..8fd35dfff 100644
--- a/gegl/buffer/gegl-sampler-lohalo.c
+++ b/gegl/buffer/gegl-sampler-lohalo.c
@@ -364,7 +364,7 @@ ewa_update (const gint j,
gfloat* restrict ewa_newval)
{
const gint skip = j * channels + i * row_skip;
-
+ gint c;
const gfloat weight = robidoux (c_major_x,
c_major_y,
c_minor_x,
@@ -373,10 +373,8 @@ ewa_update (const gint j,
y_0 - (gfloat) i);
*total_weight += weight;
- ewa_newval[0] += weight * input_ptr[ skip ];
- ewa_newval[1] += weight * input_ptr[ skip + 1 ];
- ewa_newval[2] += weight * input_ptr[ skip + 2 ];
- ewa_newval[3] += weight * input_ptr[ skip + 3 ];
+ for (c = 0; c < channels; c++)
+ ewa_newval[c] += weight * input_ptr[ skip + c ];
}
static void
@@ -392,7 +390,7 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
* provided by gegl_sampler_get_ptr (self, ix, iy). pixels_per_row
* corresponds to fetch_rectangle.width in gegl_sampler_get_ptr.
*/
- const gint channels = 4;
+ const gint channels = self->interpolate_components;
const gint pixels_per_row = GEGL_SAMPLER_MAXIMUM_WIDTH;
const gint row_skip = channels * pixels_per_row;
@@ -501,86 +499,52 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
const gfloat tre = ay - qua - yt3;
const gfloat two = xt2 - one + xt3;
const gfloat dos = yt2 - uno + yt3;
-
+ gint c;
/*
* The newval array will contain one computed resampled value per
* channel:
*/
gfloat newval[channels];
- newval[0] =
- extended_sigmoidal (
- uno * ( one * inverse_sigmoidal (input_ptr[ uno_one_shift ]) +
- two * inverse_sigmoidal (input_ptr[ uno_two_shift ]) +
- thr * inverse_sigmoidal (input_ptr[ uno_thr_shift ]) +
- fou * inverse_sigmoidal (input_ptr[ uno_fou_shift ]) ) +
- dos * ( one * inverse_sigmoidal (input_ptr[ dos_one_shift ]) +
- two * inverse_sigmoidal (input_ptr[ dos_two_shift ]) +
- thr * inverse_sigmoidal (input_ptr[ dos_thr_shift ]) +
- fou * inverse_sigmoidal (input_ptr[ dos_fou_shift ]) ) +
- tre * ( one * inverse_sigmoidal (input_ptr[ tre_one_shift ]) +
- two * inverse_sigmoidal (input_ptr[ tre_two_shift ]) +
- thr * inverse_sigmoidal (input_ptr[ tre_thr_shift ]) +
- fou * inverse_sigmoidal (input_ptr[ tre_fou_shift ]) ) +
- qua * ( one * inverse_sigmoidal (input_ptr[ qua_one_shift ]) +
- two * inverse_sigmoidal (input_ptr[ qua_two_shift ]) +
- thr * inverse_sigmoidal (input_ptr[ qua_thr_shift ]) +
- fou * inverse_sigmoidal (input_ptr[ qua_fou_shift ]) ) );
- newval[1] =
- extended_sigmoidal (
- uno * ( one * inverse_sigmoidal (input_ptr[ uno_one_shift + 1 ]) +
- two * inverse_sigmoidal (input_ptr[ uno_two_shift + 1 ]) +
- thr * inverse_sigmoidal (input_ptr[ uno_thr_shift + 1 ]) +
- fou * inverse_sigmoidal (input_ptr[ uno_fou_shift + 1 ]) ) +
- dos * ( one * inverse_sigmoidal (input_ptr[ dos_one_shift + 1 ]) +
- two * inverse_sigmoidal (input_ptr[ dos_two_shift + 1 ]) +
- thr * inverse_sigmoidal (input_ptr[ dos_thr_shift + 1 ]) +
- fou * inverse_sigmoidal (input_ptr[ dos_fou_shift + 1 ]) ) +
- tre * ( one * inverse_sigmoidal (input_ptr[ tre_one_shift + 1 ]) +
- two * inverse_sigmoidal (input_ptr[ tre_two_shift + 1 ]) +
- thr * inverse_sigmoidal (input_ptr[ tre_thr_shift + 1 ]) +
- fou * inverse_sigmoidal (input_ptr[ tre_fou_shift + 1 ]) ) +
- qua * ( one * inverse_sigmoidal (input_ptr[ qua_one_shift + 1 ]) +
- two * inverse_sigmoidal (input_ptr[ qua_two_shift + 1 ]) +
- thr * inverse_sigmoidal (input_ptr[ qua_thr_shift + 1 ]) +
- fou * inverse_sigmoidal (input_ptr[ qua_fou_shift + 1 ]) ) );
- newval[2] =
+ for (c = 0; c < channels-1; c++)
+ newval[c] =
extended_sigmoidal (
- uno * ( one * inverse_sigmoidal (input_ptr[ uno_one_shift + 2 ]) +
- two * inverse_sigmoidal (input_ptr[ uno_two_shift + 2 ]) +
- thr * inverse_sigmoidal (input_ptr[ uno_thr_shift + 2 ]) +
- fou * inverse_sigmoidal (input_ptr[ uno_fou_shift + 2 ]) ) +
- dos * ( one * inverse_sigmoidal (input_ptr[ dos_one_shift + 2 ]) +
- two * inverse_sigmoidal (input_ptr[ dos_two_shift + 2 ]) +
- thr * inverse_sigmoidal (input_ptr[ dos_thr_shift + 2 ]) +
- fou * inverse_sigmoidal (input_ptr[ dos_fou_shift + 2 ]) ) +
- tre * ( one * inverse_sigmoidal (input_ptr[ tre_one_shift + 2 ]) +
- two * inverse_sigmoidal (input_ptr[ tre_two_shift + 2 ]) +
- thr * inverse_sigmoidal (input_ptr[ tre_thr_shift + 2 ]) +
- fou * inverse_sigmoidal (input_ptr[ tre_fou_shift + 2 ]) ) +
- qua * ( one * inverse_sigmoidal (input_ptr[ qua_one_shift + 2 ]) +
- two * inverse_sigmoidal (input_ptr[ qua_two_shift + 2 ]) +
- thr * inverse_sigmoidal (input_ptr[ qua_thr_shift + 2 ]) +
- fou * inverse_sigmoidal (input_ptr[ qua_fou_shift + 2 ]) ) );
+ uno * ( one * inverse_sigmoidal (input_ptr[ uno_one_shift + c ]) +
+ two * inverse_sigmoidal (input_ptr[ uno_two_shift + c ]) +
+ thr * inverse_sigmoidal (input_ptr[ uno_thr_shift + c ]) +
+ fou * inverse_sigmoidal (input_ptr[ uno_fou_shift + c ]) ) +
+ dos * ( one * inverse_sigmoidal (input_ptr[ dos_one_shift + c ]) +
+ two * inverse_sigmoidal (input_ptr[ dos_two_shift + c ]) +
+ thr * inverse_sigmoidal (input_ptr[ dos_thr_shift + c ]) +
+ fou * inverse_sigmoidal (input_ptr[ dos_fou_shift + c ]) ) +
+ tre * ( one * inverse_sigmoidal (input_ptr[ tre_one_shift + c ]) +
+ two * inverse_sigmoidal (input_ptr[ tre_two_shift + c ]) +
+ thr * inverse_sigmoidal (input_ptr[ tre_thr_shift + c ]) +
+ fou * inverse_sigmoidal (input_ptr[ tre_fou_shift + c ]) ) +
+ qua * ( one * inverse_sigmoidal (input_ptr[ qua_one_shift + c ]) +
+ two * inverse_sigmoidal (input_ptr[ qua_two_shift + c ]) +
+ thr * inverse_sigmoidal (input_ptr[ qua_thr_shift + c ]) +
+ fou * inverse_sigmoidal (input_ptr[ qua_fou_shift + c ]) ) );
/*
* It appears that it is a bad idea to sigmoidize the transparency
* channel (in RaGaBaA, at least). So don't.
*/
- newval[3] = uno * ( one * input_ptr[ uno_one_shift + 3 ] +
- two * input_ptr[ uno_two_shift + 3 ] +
- thr * input_ptr[ uno_thr_shift + 3 ] +
- fou * input_ptr[ uno_fou_shift + 3 ] ) +
- dos * ( one * input_ptr[ dos_one_shift + 3 ] +
- two * input_ptr[ dos_two_shift + 3 ] +
- thr * input_ptr[ dos_thr_shift + 3 ] +
- fou * input_ptr[ dos_fou_shift + 3 ] ) +
- tre * ( one * input_ptr[ tre_one_shift + 3 ] +
- two * input_ptr[ tre_two_shift + 3 ] +
- thr * input_ptr[ tre_thr_shift + 3 ] +
- fou * input_ptr[ tre_fou_shift + 3 ] ) +
- qua * ( one * input_ptr[ qua_one_shift + 3 ] +
- two * input_ptr[ qua_two_shift + 3 ] +
- thr * input_ptr[ qua_thr_shift + 3 ] +
- fou * input_ptr[ qua_fou_shift + 3 ] );
+ newval[channels-1] =
+ uno * ( one * input_ptr[ uno_one_shift + channels - 1 ] +
+ two * input_ptr[ uno_two_shift + channels - 1 ] +
+ thr * input_ptr[ uno_thr_shift + channels - 1 ] +
+ fou * input_ptr[ uno_fou_shift + channels - 1 ] ) +
+ dos * ( one * input_ptr[ dos_one_shift + channels - 1 ] +
+ two * input_ptr[ dos_two_shift + channels - 1 ] +
+ thr * input_ptr[ dos_thr_shift + channels - 1 ] +
+ fou * input_ptr[ dos_fou_shift + channels - 1 ] ) +
+ tre * ( one * input_ptr[ tre_one_shift + channels - 1 ] +
+ two * input_ptr[ tre_two_shift + channels - 1 ] +
+ thr * input_ptr[ tre_thr_shift + channels - 1 ] +
+ fou * input_ptr[ tre_fou_shift + channels - 1 ] ) +
+ qua * ( one * input_ptr[ qua_one_shift + channels - 1 ] +
+ two * input_ptr[ qua_two_shift + channels - 1 ] +
+ thr * input_ptr[ qua_thr_shift + channels - 1 ] +
+ fou * input_ptr[ qua_fou_shift + channels - 1 ] );
{
/*
@@ -1025,10 +989,9 @@ gegl_sampler_lohalo_get ( GeglSampler* restrict self,
*/
const gfloat beta = twice_s1s1 > (gdouble) 2. ? (gfloat) ( ( (gdouble) 1.0 - theta ) /
total_weight ) : (gfloat) 0.;
const gfloat newtheta = twice_s1s1 > (gdouble) 2. ? theta : (gfloat) 1.;
- newval[0] = newtheta * newval[0] + beta * ewa_newval[0];
- newval[1] = newtheta * newval[1] + beta * ewa_newval[1];
- newval[2] = newtheta * newval[2] + beta * ewa_newval[2];
- newval[3] = newtheta * newval[3] + beta * ewa_newval[3];
+ gint c;
+ for (c = 0; c < channels; c++)
+ newval[c] = newtheta * newval[c] + beta * ewa_newval[c];
}
}
diff --git a/gegl/buffer/gegl-sampler-nohalo.c b/gegl/buffer/gegl-sampler-nohalo.c
index fda400318..8983bdced 100644
--- a/gegl/buffer/gegl-sampler-nohalo.c
+++ b/gegl/buffer/gegl-sampler-nohalo.c
@@ -17,6 +17,7 @@
* 2012 (c) Nicolas Robidoux
* 2009-2011 (c) Nicolas Robidoux, Adam Turcotte, Chantal Racette,
* Anthony Thyssen, John Cupitt and Øyvind Kolås.
+ * 2018 Øyvind Kolås
*/
/*
@@ -1205,12 +1206,11 @@ ewa_update (const gint j,
c_minor_y,
x_0 - (gfloat) j,
y_0 - (gfloat) i);
+ gint c;
*total_weight += weight;
- ewa_newval[0] += weight * input_ptr[ skip ];
- ewa_newval[1] += weight * input_ptr[ skip + 1 ];
- ewa_newval[2] += weight * input_ptr[ skip + 2 ];
- ewa_newval[3] += weight * input_ptr[ skip + 3 ];
+ for (c = 0; c < channels; c++)
+ ewa_newval[c] += weight * input_ptr[ skip + c ];
}
static void
@@ -1226,7 +1226,7 @@ gegl_sampler_nohalo_get ( GeglSampler* restrict self,
* provided by gegl_sampler_get_ptr (self, ix, iy). pixels_per_row
* corresponds to fetch_rectangle.width in gegl_sampler_get_ptr.
*/
- const gint channels = 4;
+ const gint channels = self->interpolate_components;
const gint pixels_per_row = GEGL_SAMPLER_MAXIMUM_WIDTH;
const gint row_skip = channels * pixels_per_row;
@@ -1311,28 +1311,6 @@ gegl_sampler_nohalo_get ( GeglSampler* restrict self,
const gint cin_thr_shift = shift_forw_2_row;
const gint cin_fou_shift = shift_forw_1_pix + shift_forw_2_row;
- /*
- * Channel by channel computation of the new pixel values:
- */
- gfloat uno_one_0, uno_two_0, uno_thr_0, uno_fou_0;
- gfloat dos_one_0, dos_two_0, dos_thr_0, dos_fou_0;
- gfloat tre_one_0, tre_two_0, tre_thr_0, tre_fou_0;
- gfloat qua_one_0, qua_two_0, qua_thr_0, qua_fou_0;
-
- gfloat uno_one_1, uno_two_1, uno_thr_1, uno_fou_1;
- gfloat dos_one_1, dos_two_1, dos_thr_1, dos_fou_1;
- gfloat tre_one_1, tre_two_1, tre_thr_1, tre_fou_1;
- gfloat qua_one_1, qua_two_1, qua_thr_1, qua_fou_1;
-
- gfloat uno_one_2, uno_two_2, uno_thr_2, uno_fou_2;
- gfloat dos_one_2, dos_two_2, dos_thr_2, dos_fou_2;
- gfloat tre_one_2, tre_two_2, tre_thr_2, tre_fou_2;
- gfloat qua_one_2, qua_two_2, qua_thr_2, qua_fou_2;
-
- gfloat uno_one_3, uno_two_3, uno_thr_3, uno_fou_3;
- gfloat dos_one_3, dos_two_3, dos_thr_3, dos_fou_3;
- gfloat tre_one_3, tre_two_3, tre_thr_3, tre_fou_3;
- gfloat qua_one_3, qua_two_3, qua_thr_3, qua_fou_3;
/*
* The newval array will contain one computed resampled value per
@@ -1340,47 +1318,6 @@ gegl_sampler_nohalo_get ( GeglSampler* restrict self,
*/
gfloat newval[channels];
- /*
- * First channel:
- */
- nohalo_subdivision (input_ptr[ uno_two_shift ],
- input_ptr[ uno_thr_shift ],
- input_ptr[ uno_fou_shift ],
- input_ptr[ dos_one_shift ],
- input_ptr[ dos_two_shift ],
- input_ptr[ dos_thr_shift ],
- input_ptr[ dos_fou_shift ],
- input_ptr[ dos_fiv_shift ],
- input_ptr[ tre_one_shift ],
- input_ptr[ tre_two_shift ],
- input_ptr[ tre_thr_shift ],
- input_ptr[ tre_fou_shift ],
- input_ptr[ tre_fiv_shift ],
- input_ptr[ qua_one_shift ],
- input_ptr[ qua_two_shift ],
- input_ptr[ qua_thr_shift ],
- input_ptr[ qua_fou_shift ],
- input_ptr[ qua_fiv_shift ],
- input_ptr[ cin_two_shift ],
- input_ptr[ cin_thr_shift ],
- input_ptr[ cin_fou_shift ],
- &uno_one_0,
- &uno_two_0,
- &uno_thr_0,
- &uno_fou_0,
- &dos_one_0,
- &dos_two_0,
- &dos_thr_0,
- &dos_fou_0,
- &tre_one_0,
- &tre_two_0,
- &tre_thr_0,
- &tre_fou_0,
- &qua_one_0,
- &qua_two_0,
- &qua_thr_0,
- &qua_fou_0);
-
{
/*
* Computation of the needed weights (coefficients).
@@ -1466,223 +1403,54 @@ gegl_sampler_nohalo_get ( GeglSampler* restrict self,
const gfloat c11dxdy =
xm1over2_times_ym1over2 * xp1over2sq_times_yp1over2sq;
- newval[0] = lbb (c00,
- c10,
- c01,
- c11,
- c00dx,
- c10dx,
- c01dx,
- c11dx,
- c00dy,
- c10dy,
- c01dy,
- c11dy,
- c00dxdy,
- c10dxdy,
- c01dxdy,
- c11dxdy,
- uno_one_0,
- uno_two_0,
- uno_thr_0,
- uno_fou_0,
- dos_one_0,
- dos_two_0,
- dos_thr_0,
- dos_fou_0,
- tre_one_0,
- tre_two_0,
- tre_thr_0,
- tre_fou_0,
- qua_one_0,
- qua_two_0,
- qua_thr_0,
- qua_fou_0);
- /*
- * Second channel:
- */
- nohalo_subdivision (input_ptr[ uno_two_shift + 1 ],
- input_ptr[ uno_thr_shift + 1 ],
- input_ptr[ uno_fou_shift + 1 ],
- input_ptr[ dos_one_shift + 1 ],
- input_ptr[ dos_two_shift + 1 ],
- input_ptr[ dos_thr_shift + 1 ],
- input_ptr[ dos_fou_shift + 1 ],
- input_ptr[ dos_fiv_shift + 1 ],
- input_ptr[ tre_one_shift + 1 ],
- input_ptr[ tre_two_shift + 1 ],
- input_ptr[ tre_thr_shift + 1 ],
- input_ptr[ tre_fou_shift + 1 ],
- input_ptr[ tre_fiv_shift + 1 ],
- input_ptr[ qua_one_shift + 1 ],
- input_ptr[ qua_two_shift + 1 ],
- input_ptr[ qua_thr_shift + 1 ],
- input_ptr[ qua_fou_shift + 1 ],
- input_ptr[ qua_fiv_shift + 1 ],
- input_ptr[ cin_two_shift + 1 ],
- input_ptr[ cin_thr_shift + 1 ],
- input_ptr[ cin_fou_shift + 1 ],
- &uno_one_1,
- &uno_two_1,
- &uno_thr_1,
- &uno_fou_1,
- &dos_one_1,
- &dos_two_1,
- &dos_thr_1,
- &dos_fou_1,
- &tre_one_1,
- &tre_two_1,
- &tre_thr_1,
- &tre_fou_1,
- &qua_one_1,
- &qua_two_1,
- &qua_thr_1,
- &qua_fou_1);
- newval[1] = lbb (c00,
- c10,
- c01,
- c11,
- c00dx,
- c10dx,
- c01dx,
- c11dx,
- c00dy,
- c10dy,
- c01dy,
- c11dy,
- c00dxdy,
- c10dxdy,
- c01dxdy,
- c11dxdy,
- uno_one_1,
- uno_two_1,
- uno_thr_1,
- uno_fou_1,
- dos_one_1,
- dos_two_1,
- dos_thr_1,
- dos_fou_1,
- tre_one_1,
- tre_two_1,
- tre_thr_1,
- tre_fou_1,
- qua_one_1,
- qua_two_1,
- qua_thr_1,
- qua_fou_1);
- /*
- * Third channel:
- */
- nohalo_subdivision (input_ptr[ uno_two_shift + 2 ],
- input_ptr[ uno_thr_shift + 2 ],
- input_ptr[ uno_fou_shift + 2 ],
- input_ptr[ dos_one_shift + 2 ],
- input_ptr[ dos_two_shift + 2 ],
- input_ptr[ dos_thr_shift + 2 ],
- input_ptr[ dos_fou_shift + 2 ],
- input_ptr[ dos_fiv_shift + 2 ],
- input_ptr[ tre_one_shift + 2 ],
- input_ptr[ tre_two_shift + 2 ],
- input_ptr[ tre_thr_shift + 2 ],
- input_ptr[ tre_fou_shift + 2 ],
- input_ptr[ tre_fiv_shift + 2 ],
- input_ptr[ qua_one_shift + 2 ],
- input_ptr[ qua_two_shift + 2 ],
- input_ptr[ qua_thr_shift + 2 ],
- input_ptr[ qua_fou_shift + 2 ],
- input_ptr[ qua_fiv_shift + 2 ],
- input_ptr[ cin_two_shift + 2 ],
- input_ptr[ cin_thr_shift + 2 ],
- input_ptr[ cin_fou_shift + 2 ],
- &uno_one_2,
- &uno_two_2,
- &uno_thr_2,
- &uno_fou_2,
- &dos_one_2,
- &dos_two_2,
- &dos_thr_2,
- &dos_fou_2,
- &tre_one_2,
- &tre_two_2,
- &tre_thr_2,
- &tre_fou_2,
- &qua_one_2,
- &qua_two_2,
- &qua_thr_2,
- &qua_fou_2);
- newval[2] = lbb (c00,
- c10,
- c01,
- c11,
- c00dx,
- c10dx,
- c01dx,
- c11dx,
- c00dy,
- c10dy,
- c01dy,
- c11dy,
- c00dxdy,
- c10dxdy,
- c01dxdy,
- c11dxdy,
- uno_one_2,
- uno_two_2,
- uno_thr_2,
- uno_fou_2,
- dos_one_2,
- dos_two_2,
- dos_thr_2,
- dos_fou_2,
- tre_one_2,
- tre_two_2,
- tre_thr_2,
- tre_fou_2,
- qua_one_2,
- qua_two_2,
- qua_thr_2,
- qua_fou_2);
- /*
- * Fourth channel:
- */
- nohalo_subdivision (input_ptr[ uno_two_shift + 3 ],
- input_ptr[ uno_thr_shift + 3 ],
- input_ptr[ uno_fou_shift + 3 ],
- input_ptr[ dos_one_shift + 3 ],
- input_ptr[ dos_two_shift + 3 ],
- input_ptr[ dos_thr_shift + 3 ],
- input_ptr[ dos_fou_shift + 3 ],
- input_ptr[ dos_fiv_shift + 3 ],
- input_ptr[ tre_one_shift + 3 ],
- input_ptr[ tre_two_shift + 3 ],
- input_ptr[ tre_thr_shift + 3 ],
- input_ptr[ tre_fou_shift + 3 ],
- input_ptr[ tre_fiv_shift + 3 ],
- input_ptr[ qua_one_shift + 3 ],
- input_ptr[ qua_two_shift + 3 ],
- input_ptr[ qua_thr_shift + 3 ],
- input_ptr[ qua_fou_shift + 3 ],
- input_ptr[ qua_fiv_shift + 3 ],
- input_ptr[ cin_two_shift + 3 ],
- input_ptr[ cin_thr_shift + 3 ],
- input_ptr[ cin_fou_shift + 3 ],
- &uno_one_3,
- &uno_two_3,
- &uno_thr_3,
- &uno_fou_3,
- &dos_one_3,
- &dos_two_3,
- &dos_thr_3,
- &dos_fou_3,
- &tre_one_3,
- &tre_two_3,
- &tre_thr_3,
- &tre_fou_3,
- &qua_one_3,
- &qua_two_3,
- &qua_thr_3,
- &qua_fou_3);
- newval[3] = lbb (c00,
+ for (gint c = 0; c < channels; c++)
+ {
+ /*
+ * Channel by channel computation of the new pixel values:
+ */
+ gfloat uno_one, uno_two, uno_thr, uno_fou;
+ gfloat dos_one, dos_two, dos_thr, dos_fou;
+ gfloat tre_one, tre_two, tre_thr, tre_fou;
+ gfloat qua_one, qua_two, qua_thr, qua_fou;
+ nohalo_subdivision (input_ptr[ uno_two_shift + c],
+ input_ptr[ uno_thr_shift + c],
+ input_ptr[ uno_fou_shift + c],
+ input_ptr[ dos_one_shift + c],
+ input_ptr[ dos_two_shift + c],
+ input_ptr[ dos_thr_shift + c],
+ input_ptr[ dos_fou_shift + c],
+ input_ptr[ dos_fiv_shift + c],
+ input_ptr[ tre_one_shift + c],
+ input_ptr[ tre_two_shift + c],
+ input_ptr[ tre_thr_shift + c],
+ input_ptr[ tre_fou_shift + c],
+ input_ptr[ tre_fiv_shift + c],
+ input_ptr[ qua_one_shift + c],
+ input_ptr[ qua_two_shift + c],
+ input_ptr[ qua_thr_shift + c],
+ input_ptr[ qua_fou_shift + c],
+ input_ptr[ qua_fiv_shift + c],
+ input_ptr[ cin_two_shift + c],
+ input_ptr[ cin_thr_shift + c],
+ input_ptr[ cin_fou_shift + c],
+ &uno_one,
+ &uno_two,
+ &uno_thr,
+ &uno_fou,
+ &dos_one,
+ &dos_two,
+ &dos_thr,
+ &dos_fou,
+ &tre_one,
+ &tre_two,
+ &tre_thr,
+ &tre_fou,
+ &qua_one,
+ &qua_two,
+ &qua_thr,
+ &qua_fou);
+
+ newval[c] = lbb (c00,
c10,
c01,
c11,
@@ -1698,22 +1466,24 @@ gegl_sampler_nohalo_get ( GeglSampler* restrict self,
c10dxdy,
c01dxdy,
c11dxdy,
- uno_one_3,
- uno_two_3,
- uno_thr_3,
- uno_fou_3,
- dos_one_3,
- dos_two_3,
- dos_thr_3,
- dos_fou_3,
- tre_one_3,
- tre_two_3,
- tre_thr_3,
- tre_fou_3,
- qua_one_3,
- qua_two_3,
- qua_thr_3,
- qua_fou_3);
+ uno_one,
+ uno_two,
+ uno_thr,
+ uno_fou,
+ dos_one,
+ dos_two,
+ dos_thr,
+ dos_fou,
+ tre_one,
+ tre_two,
+ tre_thr,
+ tre_fou,
+ qua_one,
+ qua_two,
+ qua_thr,
+ qua_fou);
+ }
+
{
/*
@@ -1925,7 +1695,7 @@ gegl_sampler_nohalo_get ( GeglSampler* restrict self,
* ImageMagick (now fixed, thanks to Cristy, the lead dev).
*/
const double sqrt_discriminant =
- sqrt (discriminant > 0. ? discriminant : 0.);
+ discriminant > 0. ? sqrt (discriminant) : 0.;
/*
* Initially, we only compute the squares of the singular
@@ -2109,10 +1879,8 @@ gegl_sampler_nohalo_get ( GeglSampler* restrict self,
* Storage for the EWA contribution:
*/
gfloat ewa_newval[channels];
- ewa_newval[0] = (gfloat) 0;
- ewa_newval[1] = (gfloat) 0;
- ewa_newval[2] = (gfloat) 0;
- ewa_newval[3] = (gfloat) 0;
+ for (gint c = 0; c < channels; c++)
+ ewa_newval[c] = (gfloat) 0;
{
gint i = out_top_0;
@@ -2143,10 +1911,8 @@ gegl_sampler_nohalo_get ( GeglSampler* restrict self,
*/
const gfloat beta =
(gfloat) ( ( (gdouble) 1.0 - 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];
+ for (gint c = 0; c < channels; c++)
+ newval[c] = theta * newval[c] + beta * ewa_newval[c];
}
}
}
diff --git a/gegl/buffer/gegl-sampler.c b/gegl/buffer/gegl-sampler.c
index 89e7ddeb8..fd7d52b02 100644
--- a/gegl/buffer/gegl-sampler.c
+++ b/gegl/buffer/gegl-sampler.c
@@ -135,7 +135,7 @@ gegl_sampler_init (GeglSampler *sampler)
sampler->level[0].sampler_buffer =
g_malloc (GEGL_SAMPLER_MAXIMUM_WIDTH *
- GEGL_SAMPLER_MAXIMUM_HEIGHT * GEGL_SAMPLER_BPP);
+ GEGL_SAMPLER_MAXIMUM_HEIGHT * 5 * 4); // XXX : maxes out at 5 components
}
static void
@@ -192,8 +192,46 @@ gegl_sampler_prepare (GeglSampler *self)
if (klass->prepare)
klass->prepare (self);
- self->interpolate_format = babl_format_with_space ("RaGaBaA float",
- gegl_buffer_get_format(self->buffer));
+ {
+ const Babl *model = babl_format_get_model (gegl_buffer_get_format (self->buffer));
+
+ if (babl_model_is (model, "Y")||
+ babl_model_is (model, "Y'")||
+ babl_model_is (model, "Y~")||
+ babl_model_is (model, "YA")||
+ babl_model_is (model, "YaA")||
+ babl_model_is (model, "Y'aA")||
+ babl_model_is (model, "Y'A")||
+ babl_model_is (model, "Y~A"))
+ {
+ self->interpolate_format = babl_format_with_space ("YaA float",
+ gegl_buffer_get_format(self->buffer));
+ }
+#if 0
+ else if (babl_model_is (model, "RGB")||
+ babl_model_is (model, "R'G'B'")||
+ babl_model_is (model, "R~G~B~") ||
+ babl_model_is (model, "RGBA")||
+ babl_model_is (model, "R'G'B'A")||
+ babl_model_is (model, "R~G~B~A")||
+ babl_model_is (model, "RaGaBaA")||
+ babl_model_is (model, "R'aG'aB'aA")||
+ babl_model_is (model, "R~aG~aB~aA"))
+ {
+ self->interpolate_format = babl_format_with_space ("RaGaBaA float",
+ gegl_buffer_get_format(self->buffer));
+ }
+#endif
+ else
+ {
+ self->interpolate_format = babl_format_with_space ("RaGaBaA float",
+ gegl_buffer_get_format(self->buffer));
+ }
+
+ self->interpolate_bpp = babl_format_get_bytes_per_pixel (self->interpolate_format);
+ self->interpolate_components = babl_format_get_n_components (self->interpolate_format);
+ }
+
if (!self->fish)
self->fish = babl_fish (self->interpolate_format, self->format);
@@ -203,7 +241,6 @@ gegl_sampler_prepare (GeglSampler *self)
*/
self->level[0].sampler_rectangle.width = 0;
self->level[0].sampler_rectangle.height = 0;
-
}
void
@@ -292,21 +329,21 @@ gegl_sampler_get_from_mipmap (GeglSampler *sampler,
level_no);
if (!level->sampler_buffer)
level->sampler_buffer =
- g_malloc (GEGL_SAMPLER_ROWSTRIDE * GEGL_SAMPLER_MAXIMUM_HEIGHT);
+ g_malloc (GEGL_SAMPLER_MAXIMUM_WIDTH * sampler->interpolate_bpp * GEGL_SAMPLER_MAXIMUM_HEIGHT);
gegl_buffer_get (sampler->buffer,
&level->sampler_rectangle,
scale,
sampler->interpolate_format,
level->sampler_buffer,
- GEGL_SAMPLER_ROWSTRIDE,
+ GEGL_SAMPLER_MAXIMUM_WIDTH * sampler->interpolate_bpp,
repeat_mode);
}
dx = x - level->sampler_rectangle.x;
dy = y - level->sampler_rectangle.y;
buffer_ptr = (guchar *) level->sampler_buffer;
- sof = (dx + dy * GEGL_SAMPLER_MAXIMUM_WIDTH) * GEGL_SAMPLER_BPP;
+ sof = (dx + dy * GEGL_SAMPLER_MAXIMUM_WIDTH) * sampler->interpolate_bpp;
return (gfloat*) (buffer_ptr + sof);
}
diff --git a/gegl/buffer/gegl-sampler.h b/gegl/buffer/gegl-sampler.h
index ea86eb5ee..a3f11bbe2 100644
--- a/gegl/buffer/gegl-sampler.h
+++ b/gegl/buffer/gegl-sampler.h
@@ -43,8 +43,6 @@ G_BEGIN_DECLS
#define GEGL_SAMPLER_MAXIMUM_HEIGHT 64
#define GEGL_SAMPLER_MAXIMUM_WIDTH (GEGL_SAMPLER_MAXIMUM_HEIGHT)
-#define GEGL_SAMPLER_BPP 16
-#define GEGL_SAMPLER_ROWSTRIDE (GEGL_SAMPLER_MAXIMUM_WIDTH * GEGL_SAMPLER_BPP)
typedef struct _GeglSamplerClass GeglSamplerClass;
@@ -70,6 +68,8 @@ struct _GeglSampler
const Babl *format;
const Babl *interpolate_format;
const Babl *fish;
+ gint interpolate_bpp;
+ gint interpolate_components;
GeglSampler *point_sampler;
GeglSamplerGetFun point_sampler_get_fun;
@@ -196,7 +196,7 @@ gegl_sampler_get_ptr (GeglSampler *sampler,
1.0,
sampler->interpolate_format,
level->sampler_buffer,
- GEGL_SAMPLER_MAXIMUM_WIDTH * GEGL_SAMPLER_BPP,
+ GEGL_SAMPLER_MAXIMUM_WIDTH * sampler->interpolate_bpp,
repeat_mode);
level->last_x = x;
level->last_y = y;
@@ -206,7 +206,7 @@ gegl_sampler_get_ptr (GeglSampler *sampler,
dx = x - level->sampler_rectangle.x;
dy = y - level->sampler_rectangle.y;
- sof = (dx + dy * GEGL_SAMPLER_MAXIMUM_WIDTH) * GEGL_SAMPLER_BPP;
+ sof = (dx + dy * GEGL_SAMPLER_MAXIMUM_WIDTH) * sampler->interpolate_bpp;
buffer_ptr = (guchar *) level->sampler_buffer;
delta_x = level->last_x - x;
@@ -229,11 +229,15 @@ _gegl_sampler_box_get (GeglSampler* restrict self,
GeglSamplerType point_sampler_type,
gint n_samples)
{
+ gint channels = self->interpolate_components;
if (scale && fabs (gegl_buffer_matrix2_determinant (scale)) >= 4.0)
{
- gfloat result[4] = {0,0,0,0};
+ gfloat result[channels];
gdouble uv_samples_inv;
+ for (gint c = 0; c < channels; c++)
+ result[c] = 0.0f;
+
if (! self->point_sampler)
{
self->point_sampler = gegl_buffer_sampler_new (self->buffer,
@@ -315,10 +319,10 @@ _gegl_sampler_box_get (GeglSampler* restrict self,
for (u = 0; u < u_samples; u++)
{
int c;
- gfloat input[4];
+ gfloat input[channels];
self->point_sampler_get_fun (self->point_sampler,
x, y, NULL, input, repeat_mode);
- for (c = 0; c < 4; c++)
+ for (c = 0; c < channels; c++)
result[c] += input[c];
x += u_dx;
@@ -330,10 +334,8 @@ _gegl_sampler_box_get (GeglSampler* restrict self,
}
}
- result[0] *= uv_samples_inv;
- result[1] *= uv_samples_inv;
- result[2] *= uv_samples_inv;
- result[3] *= uv_samples_inv;
+ for (gint c = 0; c < channels; c++)
+ result[c] *= uv_samples_inv;
babl_process (self->fish, result, output, 1);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]