[prev in list] [next in list] [prev in thread] [next in thread]
List: gimp-developer
Subject: Re: [Gimp-developer] Re: Lanczos filter
From: gg () catking ! net
Date: 2006-09-26 12:53:35
Message-ID: op.tghkrlk4txpshh () linbox ! localdomain
[Download RAW message or body]
On Sun, 24 Sep 2006 20:10:01 +0200, <gg@catking.net> 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<0)
src_col = (gint) (xr+1) - 1;
else
src_col = (gint) xr;
frac = xr - src_col;
s = &src[src_col * bytes_pp];
for (b = 0; b < 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;
}
_______________________________________________
Gimp-developer mailing list
Gimp-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic