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 BicubicInterpolator extends PixelInterpolator { 015 016 private final double a; // sharpness value 017 018 public BicubicInterpolator() { 019 this(0.5); 020 } 021 022 public BicubicInterpolator(double a) { 023 this.a = a; 024 } 025 026 @Override 027 public float getInterpolatedValue(ImageAccessor.Scalar ia, double x, double y) { 028 final int u0 = (int) Math.floor(x); //use floor to handle negative coordinates too 029 final int v0 = (int) Math.floor(y); 030 double q = 0; 031 for (int j = 0; j <= 3; j++) { 032 int v = v0 - 1 + j; 033 double p = 0; 034 for (int i = 0; i <= 3; i++) { 035 int u = u0 - 1 + i; 036 float pixval = ia.getVal(u, v); 037 p = p + pixval * w_cub(x - u, a); 038 } 039 q = q + p * w_cub(y - v, a); 040 } 041 return (float) q; 042 } 043 044 private final double w_cub(double x, double a) { 045 if (x < 0) 046 x = -x; 047 double z = 0; 048 if (x < 1) 049 z = (-a + 2) * x * x * x + (a - 3) * x * x + 1; 050 else if (x < 2) 051 z = -a * x * x * x + 5 * a * x * x - 8 * a * x + 4 * a; 052 return z; 053 } 054 055 056}