001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 *  image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause 
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 
006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 
007 * Visit http://imagingbook.com for additional details.
008 *******************************************************************************/
009
010package imagingbook.lib.interpolation;
011
012import imagingbook.lib.image.ImageAccessor;
013
014public class LanczosInterpolator extends PixelInterpolator {
015        
016        private final int order;        // order (tap count) of this interpolator
017        
018        public LanczosInterpolator(ImageAccessor.Scalar ia) {
019                this(2);
020        }
021        
022        public LanczosInterpolator(int N) {
023                super();
024                this.order = N; // order >= 2
025        }
026        
027        @Override
028        public float getInterpolatedValue(ImageAccessor.Scalar ia, double x, double y) {
029                final int u0 = (int) Math.floor(x);     //use floor to handle negative coordinates too
030                final int v0 = (int) Math.floor(y);
031                double q = 0;
032                for (int j = 0; j <= 2*order-1; j++) {
033                        int v = v0 + j - order + 1;
034                        double p = 0;
035                        for (int i = 0; i <= 2*order-1; i++) {
036                                int u = u0 + i - order + 1;
037                                float pixval = ia.getVal(u, v);
038                                p = p + pixval * w_Ln(x - u);
039                        }
040                        q = q + p * w_Ln(y - v);
041                }
042                return (float) q;
043        }       
044        
045        
046        static final double pi = Math.PI;
047        static final double pi2 = pi*pi;
048        
049        private double w_Ln(double x) { // 1D Lanczos interpolator of order n
050                x = Math.abs(x);
051                if (x < 0.001) return 1.0;
052                if (x < order) {
053                        return order * (Math.sin(pi*x / order) * Math.sin(pi * x)) / (pi2 * x * x);
054                }
055                else return 0.0;
056        }
057
058
059}