001: /*
002: * $RCSfile: InterpolationBicubic2.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:57:10 $
010: * $State: Exp $
011: */
012: package javax.media.jai;
013:
014: /**
015: * A class representing bicubic interpolation using a different
016: * polynomial than InterpolationBicubic.
017: *
018: * <p> InterpolationBicubic2 is a subclass of Interpolation that
019: * performs interpolation using the piecewise cubic polynomial:
020: *
021: * <pre>
022: * r(x) = (a + 2)|x|^3 - (a + 3)|x|^2 + 1 , 0 <= |x| < 1
023: * r(x) = a|x|^3 - 5a|x|^2 + 8a|x| - 4a , 1 <= |x| < 2
024: * r(x) = 0 , otherwise
025: * </pre>
026: *
027: * with 'a' set to -1.0.
028: *
029: * This definition is also sometimes known as "cubic convolution",
030: * using the parameter 'a' recommended by Keys. This interpolator
031: * may produce somewhat sharper results than InterpolationBicubic,
032: * but that result is image dependent.
033: * (Reference: Digital Image Warping, George Wolberg, 1990, pp 129-131,
034: * IEEE Computer Society Press, ISBN 0-8186-8944-7)
035: *
036: * <p> A neighborhood extending one sample to the left of and above the
037: * central sample, and two samples to the right of and below the central
038: * sample is required to perform bicubic interpolation.
039: *
040: * <p> This implementation creates an <code>InterpolationTable</code>
041: * whose integer coefficients have eight bits of precision to the
042: * right of the binary point.
043: *
044: * <p> The diagrams below illustrate the pixels involved in one-dimensional
045: * interpolation. Point s0 is the interpolation kernel key position.
046: * xfrac and yfrac, indicated by the dots, represent the point of interpolation
047: * between two pixels. This value lies between 0.0 and 1.0 exclusive for
048: * floating point and 0 and 2<sup>subsampleBits</sup> exclusive for integer
049: * interpolations.
050: *
051: * <pre>
052: * <b>
053: * Horizontal Vertical
054: *
055: * s_ s0 . s1 s2 s_
056: * ^
057: * xfrac s0
058: * .< yfrac
059: * s1
060: *
061: * s2
062: * </b>
063: * </pre>
064: *
065: * <p> The diagram below illustrates the pixels involved in
066: * two-dimensional interpolation.
067: *
068: * <pre>
069: * <b>
070: * s__ s_0 s_1 s_2
071: *
072: *
073: *
074: * s0_ s00 s01 s02
075: *
076: * . < yfrac
077: *
078: * s1_ s10 s11 s12
079: *
080: *
081: *
082: * s2_ s20 s21 s22
083: * ^
084: * xfrac
085: * </b>
086: * </pre>
087: * <p> The class is marked 'final' so that it may be more easily inlined.
088: *
089: */
090: public final class InterpolationBicubic2 extends InterpolationTable {
091:
092: private static final int PRECISION_BITS = 8;
093:
094: private static float[] dataHelper(int subsampleBits) {
095:
096: int one = 1 << subsampleBits;
097: int arrayLength = one * 4;
098: float tableValues[] = new float[arrayLength];
099: float f;
100:
101: float onef = (float) one;
102: float t;
103: int count = 0;
104: for (int i = 0; i < one; i++) {
105: t = (float) i;
106: f = (i / onef);
107:
108: tableValues[count++] = bicubic(f + 1.0F);
109: tableValues[count++] = bicubic(f);
110: tableValues[count++] = bicubic(f - 1.0F);
111: tableValues[count++] = bicubic(f - 2.0F);
112:
113: }
114:
115: return tableValues;
116: }
117:
118: // The parameter "a" for the bicubic2 polynomial
119: private static final float A = -1.0F;
120:
121: // Define all of the polynomial coefficients in terms of "a"
122: private static final float A3 = A + 2.0F;
123: private static final float A2 = -(A + 3.0F);
124: private static final float A0 = 1.0F;
125:
126: private static final float B3 = A;
127: private static final float B2 = -(5.0F * A);
128: private static final float B1 = 8.0F * A;
129: private static final float B0 = -(4.0F * A);
130:
131: /** Returns the bicubic polynomial value at a certain value of x. */
132: private static float bicubic(float x) {
133: if (x < 0) {
134: x = -x;
135: }
136:
137: // Evaluate with Horner's rule
138: if (x >= 1) {
139: return (((B3 * x) + B2) * x + B1) * x + B0;
140: } else {
141: return ((A3 * x) + A2) * x * x + A0;
142: }
143:
144: }
145:
146: /**
147: * Constructs an InterpolationBicubic2 with a given subsample
148: * precision, in bits. This precision is applied to both axes.
149: *
150: * <p> This implementation creates an <code>InterpolationTable</code>
151: * whose integer coefficients have eight bits of precision to the
152: * right of the binary point.
153: *
154: * @param subsampleBits the subsample precision.
155: *
156: */
157: public InterpolationBicubic2(int subsampleBits) {
158: super (1, 1, 4, 4, subsampleBits, subsampleBits, PRECISION_BITS,
159: dataHelper(subsampleBits), null);
160: }
161:
162: }
|