On Sun, 24 Sep 2006 20:10:01 +0200, <[EMAIL PROTECTED]> 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

Reply via email to