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
parent 4a73661e
......@@ -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);
......
......@@ -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);
}
}
}
}
......@@ -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];
}
}
......
......@@ -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,