RSS/Atom feed Twitter
Site is read-only, email is disabled

Lanczos filter

This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.

This is a read-only list on gimpusers.com so this discussion thread is read-only, too.

2 of 6 messages available
Toggle history

Please log in to manage your subscriptions.

4511A6AA.1010006@telenet.be 07 Oct 20:24
  Lanczos filter gg@catking.net 24 Sep 20:10
   Lanczos filter gg@catking.net 26 Sep 14:53
op.tf6c59artxpshh@linbox.lo... 07 Oct 20:24
4511A3D6.9060308@telenet.be 07 Oct 20:24
op.tf6tqhzjtxpshh@linbox.lo... 07 Oct 20:24
gg@catking.net
2006-09-24 20:10:01 UTC (about 18 years ago)

Lanczos filter

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.

gg@catking.net
2006-09-26 14:53:35 UTC (about 18 years ago)

Lanczos filter

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; }