On Sun, 24 Sep 2006 20:10:01 +0200, wrote:
Hi,
I'm trying to iron out some of the anomolies here and there are several
interpolations using a frig factor I dont understand. I'm probably
missing the point but I get the feeling this has been done impirically
to overcome a problem that has not been identified and may well be the
root cause of some of the glitches that are being seen.
If I'm just being dumb, please explain and accept my appologies.
src_col = ((gint) (x * ratio + 2.0 - 0.5)) - 2;
/* +2, -2 is there because (int) rounds towards 0 and we need
to round down */
now it seems to me that
src_col = ((gint) (x * ratio + 2.0 - 0.5)) - 2;
is no different to
src_col = ((gint) (x * ratio + 1.0 - 0.5)) - 1;
which is the same as
src_col = ((gint) (x * ratio + 0.5)) - 1;
now I would normally expect something like (gint) (x * ratio + 0.5) to
overcome the truncation error, so why is the -1 necessary afterwards.
This occurs on linear , cubic and earlier lanczos ; this suggests to me
that there is a bug somewhere out side the unit where this code resides.
Why is this adjustment needed?
thx.
Reply to my own question.
I've rationalised the +2 -2 senario and added comments to clearly explain
the -0.5 adjustment. Hopefully this will save the time I lost figuring all
this out for any poor sole that needs to look at this code in the future.
The resulting code should be slightly more efficient as well.
I will shortly submit a patch for scale-funcs.c to include this in CVS.
I suggest a similar tidy up of any parallel uses of
GIMP_INTERPOLATION_CUBIC et al. since this applies to all interpolation
types.
case GIMP_INTERPOLATION_CUBIC:
for (x = 0; x < width; x++)
{
/* -0.5 is because cubic() interpolates a position between 2nd
and 3rd data points
* we are assigning to 2nd in dest, hence mean shift of +0.5
* +1, -1 ensures we dont (int) a negative; first src col only.
*/
gdouble xr = x * ratio - 0.5;
if (xr< bytes_pp; b++)
dest[b] = cubic_spline_fit (frac, s[b - bytes_pp], s[b], s[b
+ bytes_pp],
s[b + bytes_pp * 2]);
dest += bytes_pp;
}
break;
static inline gdouble
cubic_spline_fit (gdouble dx,
gint pt0,
gint pt1,
gint pt2,
gint pt3)
{
/* Catmull-Rom spline - not bad
* basic intro http://www.mvps.org/directx/articles/catmull/
* This formula will calculate an interpolated point between pt1 and pt2
* dx=0 returns pt1; dx=1 returns pt2
*/
return (gdouble) ((( ( - pt0 + 3 * pt1 - 3 * pt2 + pt3 ) * dx +
( 2 * pt0 - 5 * pt1 + 4 * pt2 - pt3 ) ) * dx +
( - pt0 + pt2 ) ) * dx + (pt1 + pt1) ) / 2.0;
}