0001: /*
0002: * $RCSfile: Interpolation.java,v $
0003: *
0004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * Use is subject to license terms.
0007: *
0008: * $Revision: 1.1 $
0009: * $Date: 2005/02/11 04:57:10 $
0010: * $State: Exp $
0011: */
0012: package javax.media.jai;
0013:
0014: import java.io.Serializable;
0015:
0016: /**
0017: * An object encapsulating a particular algorithm for image
0018: * interpolation (resampling). An Interpolation captures the notion
0019: * of performing sampling on a regular grid of pixels using a local
0020: * neighborhood. It is intended to be used by operations that
0021: * resample their sources, including affine mapping and warping.
0022: *
0023: * <p> Resampling is the action of computing a pixel value at a
0024: * possibly non-integral position of an image. The image defines
0025: * pixel values at integer lattice points, and it is up to the
0026: * resampler to produce a reasonable value for positions not falling
0027: * on the lattice. A number of techniques are used in practice, the
0028: * most common being nearest-neighbor, which simply takes the value of
0029: * the closest lattice point; bilinear, which interpolates linearly
0030: * between the four closest lattice points; and bicubic, which applies
0031: * a piecewise polynomial function to a 4x4 neighborhood of nearby
0032: * points. The area over which a resampling function needs to be
0033: * computed is referred to as its support; thus the standard
0034: * resampling functions have supports of 1, 4, and 16 pixels
0035: * respectively. Mathematically, the ideal resampling function for a
0036: * band-limited image (one containing no energy above a given
0037: * frequency) is the sinc function, equal to sin(x)/x. This has
0038: * practical limitations, in particular its infinite support, which
0039: * lead to the use of the standard approximations described above.
0040: *
0041: * <p> Other interpolation functions may be required to solve problems
0042: * other than the resampling of band-limited image data. When
0043: * shrinking an image, it is common to use a function that combines
0044: * area averaging with resampling in order to remove undesirable high
0045: * frequencies as part of the interpolation process. Other
0046: * application areas may use interpolating functions that operate under
0047: * other assumptions about image data, such as taking the maximum
0048: * value of a 2x2 neighborhood. The interpolation class provides a
0049: * framework in which a variety of interpolation schemes may be
0050: * expressed.
0051: *
0052: * <p> Many interpolations are separable, that is, they may be
0053: * equivalently rewritten as a horizontal interpolation followed
0054: * by a vertical one (or vice versa). In practice, some precision
0055: * may be lost by the rounding and truncation that takes place
0056: * between the passes. The Interpolation class assumes separability
0057: * and implements all vertical interpolation methods in terms of
0058: * corresponding horizontal methods, and defines isSeparable() to
0059: * return true. A subclass may override these methods to provide
0060: * distinct implementations of horizontal and vertical interpolation.
0061: * Some subclasses may implement the two-dimensional interpolation
0062: * methods directly, yielding more precise results, while others
0063: * may implement these using a two-pass approach.
0064: *
0065: * <p> A minimal Interpolation subclass must call the Interpolation
0066: * constructor (super()) and then set at least the following fields.
0067: * <pre>
0068: * leftPadding
0069: * rightPadding
0070: * topPadding
0071: * bottomPadding
0072: * width
0073: * height
0074: * subsampleBitsH
0075: * subsampleBitsV
0076: * </pre>
0077: * <p> It must also implement at least the following methods.
0078: * <pre>
0079: * int interpolateH(int[] samples, int xfrac)
0080: * float interpolateH(float[] samples, float xfrac)
0081: * double interpolateH(double[] samples, float xfrac)
0082: * </pre>
0083: * All other methods are defined in terms of these methods for ease of
0084: * implementation of new Interpolation subclasses.
0085: *
0086: * <p> Since interpolation is generally performed for every pixel of a
0087: * destination image, efficiency is important. In particular, passing
0088: * source samples by means of arrays is likely to be unacceptably
0089: * slow. Accordingly, methods are provided for the common cases of
0090: * 2x1, 1x2, 4x1, 1x4, 2x2, and 4x4 input grids. These methods are
0091: * defined in the superclass to package their arguments into arrays
0092: * and forward the call to the array versions, in order to simplify
0093: * implementation. They should be called only on Interpolation objects
0094: * with the correct width and height. In other words, an implementor
0095: * of an Interpolation subclass may implement "interpolateH(int s0, int s1,
0096: * int xfrac)" assuming that the interpolation width is in fact equal to
0097: * 2, and does not need to enforce this constraint.
0098: *
0099: * <p> The fractional position of interpolation (xfrac, yfrac) is always
0100: * between 0.0 and 1.0 (not including 1.0). For integral image data,
0101: * the fraction is represented as a scaled integer between 0 and
0102: * 2<sup>n</sup> - 1, where n is a small integer. The value of n
0103: * in the horizontal and vertical directions may be
0104: * obtained by calling getSubsampleBitsH() and getSubsampleBitsV().
0105: * In general, code that makes use of an externally-provided
0106: * Interpolation object must query that object to determine its
0107: * desired positional precision.
0108: *
0109: * <p> For float and double images, a float between 0.0F and 1.0F
0110: * (not including 1.0F) is used as a positional specifier in the interest of
0111: * greater accuracy.
0112: *
0113: * <p> It is important to understand that the subsampleBits precision
0114: * is used only to indicate the scaling implicit in the fractional locations
0115: * (xfrac, yfrac) for integral image data types. For example, for
0116: * subsampleBitsH=8, xfrac must lie between 0 and 255 inclusive.
0117: * An implementation is not required to actually quantize its interpolation
0118: * coefficients to match the specified subsampling precision.
0119: *
0120: * <p> The diagrams below illustrate the pixels involved in one-dimensional
0121: * interpolation. Point s0 is the interpolation kernel key position.
0122: * xfrac and yfrac, indicated by the dots, represent the point of interpolation
0123: * between two pixels. This value lies between 0.0 and 1.0 exclusive for
0124: * floating point and 0 and 2<sup>subsampleBits</sup> exclusive for integer
0125: * interpolations.
0126: *
0127: * <pre>
0128: * <b>
0129: * Horizontal Vertical
0130: *
0131: * s_ s0 . s1 s2 s_
0132: * ^
0133: * xfrac s0
0134: * .< yfrac
0135: * s1
0136: *
0137: * s2
0138: *
0139: *
0140: * </b>
0141: * </pre>
0142: *
0143: * <p> The diagram below illustrates the pixels involved in
0144: * two-dimensional interpolation. Point s00 is the interpolation kernel
0145: * key position.
0146: *
0147: * <pre>
0148: * <b>
0149: *
0150: * s__ s_0 s_1 s_2
0151: *
0152: *
0153: *
0154: * s0_ s00 s01 s02
0155: *
0156: * . < yfrac
0157: *
0158: * s1_ s10 s11 s12
0159: *
0160: *
0161: *
0162: * s2_ s20 s21 s22
0163: * ^
0164: * xfrac
0165: *
0166: * </b>
0167: * </pre>
0168: *
0169: * <p> The subclasses of Interpolation include InterpolationNearest,
0170: * InterpolationBilinear, InterpolationBicubic, and
0171: * InterpolationBicubic2 (a variant defined by a different polynomial
0172: * function). These subclasses are marked 'final,' so users may
0173: * identify them by name (using 'instanceof') and write specialized
0174: * code for them. This may also allow inlining to occur on some virtual
0175: * machines. These classes do provide correct, if less than
0176: * optimal code for performing their interpolations, so it is
0177: * possible to use any Interpolation object in a generic manner.
0178: * The Sun-provided InterpolationBilinear and InterpolationBicubic
0179: * classes provide a more optimal implementation while using the same semantics.
0180: *
0181: * <p> The InterpolationTable class is a subclass of Interpolation
0182: * that divides the set of subsample positions into a fixed number of
0183: * "bins" and stores a kernel for each bin. InterpolationBicubic and
0184: * InterpolationBicubic2 are implemented in terms of
0185: * InterpolationTable since a direct implementation is very expensive.
0186: *
0187: * @see InterpolationNearest
0188: * @see InterpolationBilinear
0189: * @see InterpolationBicubic
0190: * @see InterpolationBicubic2
0191: * @see InterpolationTable
0192: *
0193: */
0194: public abstract class Interpolation extends Object implements
0195: Serializable {
0196:
0197: /**
0198: * A constant specifying interpolation by the InterpolationNearest class.
0199: */
0200: public static final int INTERP_NEAREST = 0;
0201:
0202: /**
0203: * A constant specifying interpolation by the InterpolationBilinear class.
0204: */
0205: public static final int INTERP_BILINEAR = 1;
0206:
0207: /**
0208: * A constant specifying interpolation by the InterpolationBicubic class.
0209: */
0210: public static final int INTERP_BICUBIC = 2;
0211:
0212: /**
0213: * A constant specifying interpolation by the InterpolationBicubic2 class.
0214: */
0215: public static final int INTERP_BICUBIC_2 = 3;
0216:
0217: private static Interpolation nearestInstance = null;
0218:
0219: private static Interpolation bilinearInstance = null;
0220:
0221: private static Interpolation bicubicInstance = null;
0222:
0223: private static Interpolation bicubic2Instance = null;
0224:
0225: /**
0226: * The number of pixels lying to the left
0227: * of the interpolation kernel key position.
0228: */
0229: protected int leftPadding;
0230:
0231: /**
0232: * The number of pixels lying to the right
0233: * of the interpolation kernel key position.
0234: */
0235: protected int rightPadding;
0236:
0237: /**
0238: * The number of pixels lying above the interpolation kernel key position.
0239: */
0240: protected int topPadding;
0241:
0242: /**
0243: * The number of pixels lying below the interpolation kernel key position.
0244: */
0245: protected int bottomPadding;
0246:
0247: /**
0248: * The numbers of bits used for the horizontal subsample position.
0249: * This value determines how integer fractional positons are
0250: * to be interpreted.
0251: */
0252: protected int subsampleBitsH;
0253:
0254: /**
0255: * The number of bits used for the vertical subsample position.
0256: * This value determines how integer fractional positons are
0257: * to be interpreted.
0258: */
0259: protected int subsampleBitsV;
0260:
0261: /**
0262: * The width of the interpolation kernel in pixels.
0263: */
0264: protected int width;
0265:
0266: /**
0267: * The height of the interpolation kernel in pixels.
0268: */
0269: protected int height;
0270:
0271: /**
0272: * Creates an interpolation of one of the standard types.
0273: * This is intended strictly as a convenience method.
0274: * The resulting static object is cached for later reuse.
0275: *
0276: * @param type one of:
0277: * INTERP_NEAREST,
0278: * INTERP_BILINEAR,
0279: * INTERP_BICUBIC, or
0280: * INTERP_BICUBIC_2
0281: * @return an appropriate Interpolation object.
0282: * @throws IllegalArgumentException if an unrecognized type is supplied.
0283: */
0284: public synchronized static Interpolation getInstance(int type) {
0285: Interpolation interp = null;
0286:
0287: switch (type) {
0288: case INTERP_NEAREST:
0289: if (nearestInstance == null) {
0290: interp = nearestInstance = new InterpolationNearest();
0291: } else {
0292: interp = nearestInstance;
0293: }
0294: break;
0295: case INTERP_BILINEAR:
0296: if (bilinearInstance == null) {
0297: interp = bilinearInstance = new InterpolationBilinear();
0298: } else {
0299: interp = bilinearInstance;
0300: }
0301: break;
0302: case INTERP_BICUBIC:
0303: if (bicubicInstance == null) {
0304: interp = bicubicInstance = new InterpolationBicubic(8);
0305: } else {
0306: interp = bicubicInstance;
0307: }
0308: break;
0309: case INTERP_BICUBIC_2:
0310: if (bicubic2Instance == null) {
0311: interp = bicubic2Instance = new InterpolationBicubic2(8);
0312: } else {
0313: interp = bicubic2Instance;
0314: }
0315: break;
0316: default:
0317: throw new IllegalArgumentException(JaiI18N
0318: .getString("Interpolation0"));
0319: }
0320:
0321: return interp;
0322: }
0323:
0324: /**
0325: * Constructs an Interpolation object with no fields set.
0326: * This constructor is only invoked by subclasses which
0327: * will subsequently set all fields themselves.
0328: */
0329: protected Interpolation() {
0330: }
0331:
0332: /**
0333: * Construct interpolation object with all parameters set.
0334: * Subclasses must supply all parameters.
0335: */
0336: public Interpolation(int width, int height, int leftPadding,
0337: int rightPadding, int topPadding, int bottomPadding,
0338: int subsampleBitsH, int subsampleBitsV) {
0339:
0340: this .width = width;
0341: this .height = height;
0342: this .leftPadding = leftPadding;
0343: this .rightPadding = rightPadding;
0344: this .topPadding = topPadding;
0345: this .bottomPadding = bottomPadding;
0346: this .subsampleBitsH = subsampleBitsH;
0347: this .subsampleBitsV = subsampleBitsV;
0348: }
0349:
0350: /** Returns the number of samples required to the left of the key element. */
0351: public int getLeftPadding() {
0352: return leftPadding;
0353: }
0354:
0355: /** Returns the number of samples required to the right of the key element.
0356: */
0357: public int getRightPadding() {
0358: return rightPadding;
0359: }
0360:
0361: /** Returns the number of samples required above the key element. */
0362: public int getTopPadding() {
0363: return topPadding;
0364: }
0365:
0366: /** Returns the number of samples required below the key element.
0367: */
0368: public int getBottomPadding() {
0369: return bottomPadding;
0370: }
0371:
0372: /** Returns the number of samples required for horizontal resampling. */
0373: public int getWidth() {
0374: return width;
0375: }
0376:
0377: /** Returns the number of samples required for vertical resampling.
0378: */
0379: public int getHeight() {
0380: return height;
0381: }
0382:
0383: /**
0384: * Returns true if the interpolation can be performed in a separable
0385: * manner, that is, by performing a separate pass in each dimension.
0386: * It is the caller's responsibility to deal with issues of precision.
0387: * By default, true is returned.
0388: */
0389: public boolean isSeparable() {
0390: return true;
0391: }
0392:
0393: /**
0394: * Returns the number of bits used to index subsample positions in
0395: * the horizontal direction. All integral 'xfrac' parameters
0396: * should range between 0 and 2<sup>(getSubsampleBitsH())</sup> - 1.
0397: *
0398: * <p> In general, the caller is responsible for determining the
0399: * number of subsample bits of any Interpolation object it
0400: * receives and setting up its position variables accordingly.
0401: * Some Interpolation objects allow the number of bits to be set
0402: * at construction time.
0403: */
0404: public int getSubsampleBitsH() {
0405: return subsampleBitsH;
0406: }
0407:
0408: /**
0409: * Returns the number of bits used to index subsample positions in
0410: * the vertical direction. All integral 'yfrac' parameters
0411: * should range between 0 and 2<sup>(getSubsampleBitsV())</sup> - 1.
0412: */
0413: public int getSubsampleBitsV() {
0414: return subsampleBitsV;
0415: }
0416:
0417: /**
0418: * Performs horizontal interpolation on a 1-dimensional array of
0419: * integral samples.
0420: * <p>An implementation is not required to actually quantize its
0421: * interpolation coefficients to match the specified subsampling precision.
0422: * However, the supplied value of xfrac (or yfrac) must match the precision
0423: * of its corresponding subsampleBits. For example, with a subsampleBitsH
0424: * value of 8, xfrac must lie between 0 and 255.
0425: *
0426: * @param samples an array of ints.
0427: * @param xfrac the subsample position, multiplied by 2<sup>(subsampleBitsH)</sup>.
0428: * @return the interpolated value as an int.
0429: */
0430: public abstract int interpolateH(int[] samples, int xfrac);
0431:
0432: /**
0433: * Performs vertical interpolation on a 1-dimensional array of
0434: * integral samples.
0435: *
0436: * <p> By default, vertical interpolation is defined to be the
0437: * same as horizontal interpolation. Subclasses may choose to
0438: * implement them differently.
0439: *
0440: * @param samples an array of ints.
0441: * @param yfrac the Y subsample position, multiplied by 2<sup>(subsampleBitsV)</sup>.
0442: * @return the interpolated value as an int.
0443: * @see #interpolateH(int[], int)
0444: */
0445: public int interpolateV(int[] samples, int yfrac) {
0446: return interpolateH(samples, yfrac);
0447: }
0448:
0449: /**
0450: * Performs interpolation on a 2-dimensional array of integral samples.
0451: * By default, this is implemented using a two-pass approach.
0452: *
0453: * @param samples a two-dimensional array of ints.
0454: * @param xfrac the X subsample position, multiplied by 2<sup>(subsampleBitsH)</sup>.
0455: * @param yfrac the Y subsample position, multiplied by 2<sup>(subsampleBitsV)</sup>.
0456: * @return the interpolated value as an int.
0457: * @see #interpolateH(int[], int)
0458: */
0459: public int interpolate(int[][] samples, int xfrac, int yfrac) {
0460: int[] interpH = new int[height];
0461:
0462: for (int i = 0; i < height; i++) {
0463: interpH[i] = interpolateH(samples[i], xfrac);
0464: }
0465: return interpolateV(interpH, yfrac);
0466: }
0467:
0468: /**
0469: * Performs horizontal interpolation on a pair of integral samples.
0470: * Subclasses may implement this method to provide a speed improvement
0471: * over the array method. This base class method merely calls the
0472: * array method. It should only be called if width == 2 and
0473: * leftPadding == 0.
0474: *
0475: * @param s0 the central sample.
0476: * @param s1 the sample to the right of the central sample.
0477: * @param xfrac the subsample position, ranging from zero to
0478: * 2<sup>(subsampleBitsH)</sup> - 1.
0479: * @return the interpolated value as an int.
0480: * @see #interpolateH(int[], int)
0481: */
0482: public int interpolateH(int s0, int s1, int xfrac) {
0483: int[] s = new int[2];
0484: s[0] = s0;
0485: s[1] = s1;
0486: return interpolateH(s, xfrac);
0487: }
0488:
0489: /**
0490: * Performs horizontal interpolation on a quadruple of integral samples.
0491: * Subclasses may implement this method to provide a speed improvement
0492: * over the array method. This base class method merely calls the
0493: * array method.
0494: * It should only be called if width == 4 and leftPadding == 1.
0495: *
0496: * @param s_ the sample to the left of the central sample.
0497: * @param s0 the central sample.
0498: * @param s1 the sample to the right of the central sample.
0499: * @param s2 the sample to the right of s1.
0500: * @param xfrac the subsample position, multiplied by 2<sup>(subsampleBitsH)</sup>.
0501: * @return the interpolated value as an int.
0502: * @see #interpolateH(int[], int)
0503: */
0504: public int interpolateH(int s_, int s0, int s1, int s2, int xfrac) {
0505: int[] s = new int[4];
0506: s[0] = s_;
0507: s[1] = s0;
0508: s[2] = s1;
0509: s[3] = s2;
0510: return interpolateH(s, xfrac);
0511: }
0512:
0513: /**
0514: * Performs vertical interpolation on a pair of integral samples.
0515: * Subclasses may implement this method to provide a speed improvement
0516: * over the array method. This base class method merely calls the
0517: * array method.
0518: * It should only be called if height == 2 and topPadding == 0.
0519: *
0520: * <p> By default, vertical interpolation is identical to
0521: * horizontal interpolation. Subclasses may choose to implement
0522: * them differently.
0523: *
0524: * @param s0 the central sample.
0525: * @param s1 the sample below the central sample.
0526: * @param yfrac the Y subsample position, multiplied by 2<sup>(subsampleBitsV)</sup>.
0527: * @return the interpolated value as an int.
0528: * @see #interpolateH(int[], int)
0529: */
0530: public int interpolateV(int s0, int s1, int yfrac) {
0531: int[] s = new int[2];
0532: s[0] = s0;
0533: s[1] = s1;
0534: return interpolateV(s, yfrac);
0535: }
0536:
0537: /**
0538: * Performs vertical interpolation on a quadruple of integral samples.
0539: * Subclasses may implement this method to provide a speed improvement
0540: * over the array method. This base class method merely calls the
0541: * array method.
0542: * It should only be called if height == 4 and topPadding == 1.
0543: *
0544: * <p> By default, vertical interpolation is identical to
0545: * horizontal interpolation. Subclasses may choose to implement
0546: * them differently.
0547: *
0548: * @param s_ the sample above the central sample.
0549: * @param s0 the central sample.
0550: * @param s1 the sample below the central sample.
0551: * @param s2 the sample below s1.
0552: * @param yfrac the Y subsample position, multiplied by 2<sup>(subsampleBitsV)</sup>.
0553: * @return the interpolated value as an int.
0554: * @see #interpolateH(int[], int)
0555: */
0556: public int interpolateV(int s_, int s0, int s1, int s2, int yfrac) {
0557: int[] s = new int[4];
0558: s[0] = s_;
0559: s[1] = s0;
0560: s[2] = s1;
0561: s[3] = s2;
0562: return interpolateV(s, yfrac);
0563: }
0564:
0565: /**
0566: * Performs interpolation on a 2x2 grid of integral samples.
0567: * Subclasses may implement this method to provide a speed improvement
0568: * over the array method. This base class method merely calls the
0569: * array method.
0570: * It should only be called if width == height == 2 and
0571: * leftPadding == topPadding == 0.
0572: *
0573: * @param s00 the central sample.
0574: * @param s01 the sample to the right of the central sample.
0575: * @param s10 the sample below the central sample.
0576: * @param s11 the sample below and to the right of the central sample.
0577: * @param xfrac the X subsample position, multiplied by 2<sup>(subsampleBitsH)</sup>.
0578: * @param yfrac the Y subsample position, multiplied by 2<sup>(subsampleBitsV)</sup>.
0579: * @return the interpolated value as an int.
0580: * @see #interpolateH(int[], int)
0581: */
0582: public int interpolate(int s00, int s01, int s10, int s11,
0583: int xfrac, int yfrac) {
0584: int[][] s = new int[4][4];
0585: s[0][0] = s00;
0586: s[0][1] = s01;
0587: s[1][0] = s10;
0588: s[1][1] = s11;
0589: return interpolate(s, xfrac, yfrac);
0590: }
0591:
0592: /**
0593: * Performs interpolation on a 4x4 grid of integral samples.
0594: * Subclasses may implement this method to provide a speed improvement
0595: * over the array method. This base class method merely calls the
0596: * array method.
0597: * It should only be called if width == height == 4 and
0598: * leftPadding == topPadding == 1.
0599: *
0600: * @param s__ the sample above and to the left of the central sample.
0601: * @param s_0 the sample above the central sample.
0602: * @param s_1 the sample above and one to the right of the central sample.
0603: * @param s_2 the sample above and two to the right of the central sample.
0604: * @param s0_ the sample to the left of the central sample.
0605: * @param s00 the central sample.
0606: * @param s01 the sample to the right of the central sample.
0607: * @param s02 the sample two to the right of the central sample.
0608: * @param s1_ the sample below and one to the left of the central sample.
0609: * @param s10 the sample below the central sample.
0610: * @param s11 the sample below and one to the right of the central sample.
0611: * @param s12 the sample below and two to the right of the central sample.
0612: * @param s2_ the sample two below and one to the left of the central sample.
0613: * @param s20 the sample two below the central sample.
0614: * @param s21 the sample two below and one to the right of the central sample.
0615: * @param s22 the sample two below and two to the right of the central sample.
0616: * @param xfrac the X subsample position, multiplied by 2<sup>(subsampleBitsH)</sup>.
0617: * @param yfrac the Y subsample position, multiplied by 2<sup>(subsampleBitsV)</sup>.
0618: * @return the interpolated value as an int.
0619: * @see #interpolateH(int[], int)
0620: */
0621: public int interpolate(int s__, int s_0, int s_1, int s_2, int s0_,
0622: int s00, int s01, int s02, int s1_, int s10, int s11,
0623: int s12, int s2_, int s20, int s21, int s22, int xfrac,
0624: int yfrac) {
0625: int[][] s = new int[4][4];
0626: s[0][0] = s__;
0627: s[0][1] = s_0;
0628: s[0][2] = s_1;
0629: s[0][3] = s_2;
0630: s[1][0] = s0_;
0631: s[1][1] = s00;
0632: s[1][2] = s01;
0633: s[1][3] = s02;
0634: s[2][0] = s1_;
0635: s[2][1] = s10;
0636: s[2][2] = s11;
0637: s[2][3] = s12;
0638: s[3][0] = s2_;
0639: s[3][1] = s20;
0640: s[3][2] = s21;
0641: s[3][3] = s22;
0642: return interpolate(s, xfrac, yfrac);
0643: }
0644:
0645: /**
0646: * Performs horizontal interpolation on a 1-dimensional array of
0647: * floating-point samples representing a row of samples.
0648: * The setting of subsampleBits need not have any effect on the
0649: * interpolation accuracy of an implementation of this method.
0650: *
0651: * @param samples an array of floats.
0652: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
0653: * @return the interpolated value as a float.
0654: */
0655: public abstract float interpolateH(float[] samples, float xfrac);
0656:
0657: /**
0658: * Performs vertical interpolation on a 1-dimensional array of
0659: * floating-point samples representing a column of samples.
0660: * The setting of subsampleBits need not have any effect on the
0661: * interpolation accuracy of an implementation of this method.
0662: *
0663: * <p> By default, vertical interpolation is identical to
0664: * horizontal interpolation. Subclasses may choose to implement
0665: * them differently.
0666: *
0667: * @param samples an array of floats.
0668: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
0669: * @return the interpolated value as a float.
0670:
0671: */
0672: public float interpolateV(float[] samples, float yfrac) {
0673: return interpolateH(samples, yfrac);
0674: }
0675:
0676: /**
0677: * Performs interpolation on a 2-dimensional array of
0678: * floating-point samples. By default, this is implemented using
0679: * a two-pass approach.
0680: * The setting of subsampleBits need not have any effect on the
0681: * interpolation accuracy of an implementation of this method.
0682: *
0683: *
0684: * @param samples an array of floats.
0685: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
0686: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
0687: * @return the interpolated value as a float.
0688: */
0689: public float interpolate(float[][] samples, float xfrac, float yfrac) {
0690: float[] interpH = new float[height];
0691:
0692: for (int i = 0; i < height; i++) {
0693: interpH[i] = interpolateH(samples[i], xfrac);
0694: }
0695: return interpolateV(interpH, yfrac);
0696: }
0697:
0698: /**
0699: * Performs horizontal interpolation on a pair of floating-point
0700: * samples. Subclasses may implement this method to provide a
0701: * speed improvement over the array method. This base class method
0702: * merely calls the array method.
0703: * It should only be called if width == 2 and leftPadding == 0.
0704: * The setting of subsampleBits need not have any effect on the
0705: * interpolation accuracy of an implementation of this method.
0706: *
0707: * @param s0 the central sample.
0708: * @param s1 the sample to the right of the central sample.
0709: * @param xfrac the subsample position, in the range [0.0F, 1.0F).
0710: * @return the interpolated value as a float.
0711: */
0712: public float interpolateH(float s0, float s1, float xfrac) {
0713: float[] s = new float[2];
0714: s[0] = s0;
0715: s[1] = s1;
0716: return interpolateH(s, xfrac);
0717: }
0718:
0719: /**
0720: * Performs horizontal interpolation on a quadruple of floating-point samples.
0721: * Subclasses may implement this method to provide a speed improvement
0722: * over the array method. This base class method merely calls the
0723: * array method. It should only be called if width == 4 and
0724: * leftPadding == 1.
0725: * The setting of subsampleBits need not have any effect on the
0726: * interpolation accuracy of an implementation of this method.
0727: *
0728: * @param s_ the sample to the left of the central sample.
0729: * @param s0 the central sample.
0730: * @param s1 the sample to the right of the central sample.
0731: * @param s2 the sample to the right of s1.
0732: * @param xfrac the subsample position, in the range [0.0F, 1.0F).
0733: * @return the interpolated value as a float.
0734: */
0735: public float interpolateH(float s_, float s0, float s1, float s2,
0736: float xfrac) {
0737: float[] s = new float[4];
0738: s[0] = s_;
0739: s[1] = s0;
0740: s[2] = s1;
0741: s[3] = s2;
0742: return interpolateH(s, xfrac);
0743: }
0744:
0745: /**
0746: * Performs vertical interpolation on a pair of floating-point samples.
0747: * Subclasses may implement this method to provide a speed improvement
0748: * over the array method. This base class method merely calls the
0749: * array method.
0750: * It should only be called if height == 2 and topPadding == 0.
0751: * The setting of subsampleBits need not have any effect on the
0752: * interpolation accuracy of an implementation of this method.
0753: *
0754: * <p> By default, vertical interpolation is identical to
0755: * horizontal interpolation. Subclasses may choose to implement
0756: * them differently.
0757: *
0758: * @param s0 the central sample.
0759: * @param s1 the sample below the central sample.
0760: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
0761: * @return the interpolated value as a float.
0762: */
0763: public float interpolateV(float s0, float s1, float yfrac) {
0764: float[] s = new float[2];
0765: s[0] = s0;
0766: s[1] = s1;
0767: return interpolateV(s, yfrac);
0768: }
0769:
0770: /**
0771: * Performs vertical interpolation on a quadruple of floating-point
0772: * samples.
0773: * Subclasses may implement this method to provide a speed improvement
0774: * over the array method. This base class method merely calls the
0775: * array method.
0776: * It should only be called if height == 4 and topPadding == 1.
0777: * The setting of subsampleBits need not have any effect on the
0778: * interpolation accuracy of an implementation of this method.
0779: *
0780: * <p> By default, vertical interpolation is identical to
0781: * horizontal interpolation. Subclasses may choose to implement
0782: * them differently.
0783: *
0784: * @param s_ the sample above the central sample.
0785: * @param s0 the central sample.
0786: * @param s1 the sample below the central sample.
0787: * @param s2 the sample below s1.
0788: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
0789: * @return the interpolated value as a float.
0790: */
0791: public float interpolateV(float s_, float s0, float s1, float s2,
0792: float yfrac) {
0793: float[] s = new float[4];
0794: s[0] = s_;
0795: s[1] = s0;
0796: s[2] = s1;
0797: s[3] = s2;
0798: return interpolateV(s, yfrac);
0799: }
0800:
0801: /**
0802: * Performs interpolation on a 2x2 grid of floating-point samples.
0803: * Subclasses may implement this method to provide a speed improvement
0804: * over the array method. This base class method merely calls the
0805: * array method.
0806: * It should only be called if width == height == 2 and
0807: * leftPadding == topPadding == 0.
0808: * The setting of subsampleBits need not have any effect on the
0809: * interpolation accuracy of an implementation of this method.
0810: *
0811: * @param s00 the central sample.
0812: * @param s01 the sample to the right of the central sample.
0813: * @param s10 the sample below the central sample.
0814: * @param s11 the sample below and to the right of the central sample.
0815: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
0816: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
0817: * @return the interpolated value as a float.
0818: */
0819: public float interpolate(float s00, float s01, float s10,
0820: float s11, float xfrac, float yfrac) {
0821: float[][] s = new float[4][4];
0822: s[0][0] = s00;
0823: s[0][1] = s01;
0824: s[1][0] = s10;
0825: s[1][1] = s11;
0826: return interpolate(s, xfrac, yfrac);
0827: }
0828:
0829: /**
0830: * Performs interpolation on a 4x4 grid of floating-point samples.
0831: * Subclasses may implement this method to provide a speed improvement
0832: * over the array method. This base class method merely calls the
0833: * array method.
0834: * It should only be called if width == height == 4 and
0835: * leftPadding == topPadding == 1.
0836: * The setting of subsampleBits need not have any effect on the
0837: * interpolation accuracy of an implementation of this method.
0838: *
0839: * @param s__ the sample above and to the left of the central sample.
0840: * @param s_0 the sample above the central sample.
0841: * @param s_1 the sample above and one to the right of the central sample.
0842: * @param s_2 the sample above and two to the right of the central sample.
0843: * @param s0_ the sample to the left of the central sample.
0844: * @param s00 the central sample.
0845: * @param s01 the sample to the right of the central sample.
0846: * @param s02 the sample two to the right of the central sample.
0847: * @param s1_ the sample below and one to the left of the central sample.
0848: * @param s10 the sample below the central sample.
0849: * @param s11 the sample below and one to the right of the central sample.
0850: * @param s12 the sample below and two to the right of the central sample.
0851: * @param s2_ the sample two below and one to the left of the central sample.
0852: * @param s20 the sample two below the central sample.
0853: * @param s21 the sample two below and one to the right of the central sample.
0854: * @param s22 the sample two below and two to the right of the central sample.
0855: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
0856: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
0857: * @return the interpolated value as a float.
0858: */
0859: public float interpolate(float s__, float s_0, float s_1,
0860: float s_2, float s0_, float s00, float s01, float s02,
0861: float s1_, float s10, float s11, float s12, float s2_,
0862: float s20, float s21, float s22, float xfrac, float yfrac) {
0863: float[][] s = new float[4][4];
0864: s[0][0] = s__;
0865: s[0][1] = s_0;
0866: s[0][2] = s_1;
0867: s[0][3] = s_2;
0868: s[1][0] = s0_;
0869: s[1][1] = s00;
0870: s[1][2] = s01;
0871: s[1][3] = s02;
0872: s[2][0] = s1_;
0873: s[2][1] = s10;
0874: s[2][2] = s11;
0875: s[2][3] = s12;
0876: s[3][0] = s2_;
0877: s[3][1] = s20;
0878: s[3][2] = s21;
0879: s[3][3] = s22;
0880: return interpolate(s, xfrac, yfrac);
0881: }
0882:
0883: /**
0884: * Performs horizontal interpolation on a 1-dimensional array of
0885: * double samples representing a row of samples.
0886: * The setting of subsampleBits need not have any effect on the
0887: * interpolation accuracy of an implementation of this method.
0888: *
0889: * @param samples an array of doubles.
0890: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
0891: * @return the interpolated value as a double.
0892: */
0893: public abstract double interpolateH(double[] samples, float xfrac);
0894:
0895: /**
0896: * Performs vertical interpolation on a 1-dimensional array of
0897: * double samples representing a column of samples.
0898: * The setting of subsampleBits need not have any effect on the
0899: * interpolation accuracy of an implementation of this method.
0900: *
0901: * <p> By default, vertical interpolation is identical to
0902: * horizontal interpolation. Subclasses may choose to implement
0903: * them differently.
0904: *
0905: * @param samples an array of doubles.
0906: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
0907: * @return the interpolated value as a double.
0908: */
0909: public double interpolateV(double[] samples, float yfrac) {
0910: return interpolateH(samples, yfrac);
0911: }
0912:
0913: /**
0914: * Performs interpolation on a 2-dimensional array of
0915: * double samples. By default, this is implemented using
0916: * a two-pass approach.
0917: * The setting of subsampleBits need not have any effect on the
0918: * interpolation accuracy of an implementation of this method.
0919: *
0920: * @param samples an array of doubles.
0921: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
0922: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
0923: * @return the interpolated value as a double.
0924: */
0925: public double interpolate(double[][] samples, float xfrac,
0926: float yfrac) {
0927: double[] interpH = new double[height];
0928:
0929: for (int i = 0; i < height; i++) {
0930: interpH[i] = interpolateH(samples[i], xfrac);
0931: }
0932: return interpolateV(interpH, yfrac);
0933: }
0934:
0935: /**
0936: * Performs horizontal interpolation on a pair of double samples.
0937: * Subclasses may implement this method to provide a speed improvement
0938: * over the array method. This base class method merely calls the
0939: * array method.
0940: * It should only be called if width == 2 and leftPadding == 0.
0941: * The setting of subsampleBits need not have any effect on the
0942: * interpolation accuracy of an implementation of this method.
0943: *
0944: * @param s0 the central sample.
0945: * @param s1 the sample to the right of the central sample.
0946: * @param xfrac the subsample position, in the range [0.0F, 1.0F).
0947: * @return the interpolated value as a double.
0948: */
0949: public double interpolateH(double s0, double s1, float xfrac) {
0950: double[] s = new double[2];
0951: s[0] = s0;
0952: s[1] = s1;
0953: return interpolateH(s, xfrac);
0954: }
0955:
0956: /**
0957: * Performs horizontal interpolation on a quadruple of double samples.
0958: * Subclasses may implement this method to provide a speed improvement
0959: * over the array method. This base class method merely calls the
0960: * array method.
0961: * It should only be called if width == 4 and leftPadding == 1.
0962: * The setting of subsampleBits need not have any effect on the
0963: * interpolation accuracy of an implementation of this method.
0964: *
0965: * @param s_ the sample to the left of the central sample.
0966: * @param s0 the central sample.
0967: * @param s1 the sample to the right of the central sample.
0968: * @param s2 the sample to the right of s1.
0969: * @param xfrac the subsample position, in the range [0.0F, 1.0F).
0970: * @return the interpolated value as a double.
0971: */
0972: public double interpolateH(double s_, double s0, double s1,
0973: double s2, float xfrac) {
0974: double[] s = new double[4];
0975: s[0] = s_;
0976: s[1] = s0;
0977: s[2] = s1;
0978: s[3] = s2;
0979: return interpolateH(s, xfrac);
0980: }
0981:
0982: /**
0983: * Performs vertical interpolation on a pair of double samples.
0984: * Subclasses may implement this method to provide a speed improvement
0985: * over the array method. This base class method merely calls the
0986: * array method.
0987: * It should only be called if height == 2 and topPadding == 0.
0988: * The setting of subsampleBits need not have any effect on the
0989: * interpolation accuracy of an implementation of this method.
0990: *
0991: * <p> By default, vertical interpolation is identical to
0992: * horizontal interpolation. Subclasses may choose to implement
0993: * them differently.
0994: *
0995: * @param s0 the central sample.
0996: * @param s1 the sample below the central sample.
0997: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
0998: * @return the interpolated value as a double.
0999: */
1000: public double interpolateV(double s0, double s1, float yfrac) {
1001: double[] s = new double[2];
1002: s[0] = s0;
1003: s[1] = s1;
1004: return interpolateV(s, yfrac);
1005: }
1006:
1007: /**
1008: * Performs vertical interpolation on a quadruple of double samples.
1009: * Subclasses may implement this method to provide a speed improvement
1010: * over the array method. This base class method merely calls the
1011: * array method.
1012: * It should only be called if height == 4 and topPadding == 1.
1013: * The setting of subsampleBits need not have any effect on the
1014: * interpolation accuracy of an implementation of this method.
1015: *
1016: * <p> By default, vertical interpolation is identical to
1017: * horizontal interpolation. Subclasses may choose to implement
1018: * them differently.
1019: *
1020: * @param s_ the sample above the central sample.
1021: * @param s0 the central sample.
1022: * @param s1 the sample below the central sample.
1023: * @param s2 the sample below s1.
1024: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1025: * @return the interpolated value as a double.
1026: */
1027: public double interpolateV(double s_, double s0, double s1,
1028: double s2, float yfrac) {
1029: double[] s = new double[4];
1030: s[0] = s_;
1031: s[1] = s0;
1032: s[2] = s1;
1033: s[3] = s2;
1034: return interpolateV(s, yfrac);
1035: }
1036:
1037: /**
1038: * Performs interpolation on a 2x2 grid of double samples.
1039: * Subclasses may implement this method to provide a speed improvement
1040: * over the array method. This base class method merely calls the
1041: * array method.
1042: * It should only be called if width == height == 2 and
1043: * leftPadding == topPadding == 0.
1044: * The setting of subsampleBits need not have any effect on the
1045: * interpolation accuracy of an implementation of this method.
1046: *
1047: * @param s00 the central sample.
1048: * @param s01 the sample to the right of the central sample.
1049: * @param s10 the sample below the central sample.
1050: * @param s11 the sample below and to the right of the central sample.
1051: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1052: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1053: * @return the interpolated value as a double.
1054: */
1055: public double interpolate(double s00, double s01, double s10,
1056: double s11, float xfrac, float yfrac) {
1057: double[][] s = new double[4][4];
1058: s[0][0] = s00;
1059: s[0][1] = s01;
1060: s[1][0] = s10;
1061: s[1][1] = s11;
1062: return interpolate(s, xfrac, yfrac);
1063: }
1064:
1065: /**
1066: * Performs interpolation on a 4x4 grid of double samples.
1067: * It should only be called if width == height == 4 and
1068: * leftPadding == topPadding == 1.
1069: * The setting of subsampleBits need not have any effect on the
1070: * interpolation accuracy of an implementation of this method.
1071: *
1072: * @param s__ the sample above and to the left of the central sample.
1073: * @param s_0 the sample above the central sample.
1074: * @param s_1 the sample above and one to the right of the central sample.
1075: * @param s_2 the sample above and two to the right of the central sample.
1076: * @param s0_ the sample to the left of the central sample.
1077: * @param s00 the central sample.
1078: * @param s01 the sample to the right of the central sample.
1079: * @param s02 the sample two to the right of the central sample.
1080: * @param s1_ the sample below and one to the left of the central sample.
1081: * @param s10 the sample below the central sample.
1082: * @param s11 the sample below and one to the right of the central sample.
1083: * @param s12 the sample below and two to the right of the central sample.
1084: * @param s2_ the sample two below and one to the left of the central sample.
1085: * @param s20 the sample two below the central sample.
1086: * @param s21 the sample two below and one to the right of the central sample.
1087: * @param s22 the sample two below and two to the right of the central sample.
1088: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1089: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1090: * @return the interpolated value as a double.
1091: */
1092: public double interpolate(double s__, double s_0, double s_1,
1093: double s_2, double s0_, double s00, double s01, double s02,
1094: double s1_, double s10, double s11, double s12, double s2_,
1095: double s20, double s21, double s22, float xfrac, float yfrac) {
1096: double[][] s = new double[4][4];
1097: s[0][0] = s__;
1098: s[0][1] = s_0;
1099: s[0][2] = s_1;
1100: s[0][3] = s_2;
1101: s[1][0] = s0_;
1102: s[1][1] = s00;
1103: s[1][2] = s01;
1104: s[1][3] = s02;
1105: s[2][0] = s1_;
1106: s[2][1] = s10;
1107: s[2][2] = s11;
1108: s[2][3] = s12;
1109: s[3][0] = s2_;
1110: s[3][1] = s20;
1111: s[3][2] = s21;
1112: s[3][3] = s22;
1113: return interpolate(s, xfrac, yfrac);
1114: }
1115: }
|