001: /*
002: * $RCSfile: InterpolationBilinear.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 bilinear interpolation. The class is marked
016: * 'final' so it may be either automatically or manually inlined.
017: *
018: * <p> Bilinear interpolation requires a neighborhood extending one
019: * pixel to the right and below the central sample. If the fractional
020: * subsample position is given by (xfrac, yfrac), the resampled pixel value
021: * will be:
022: *
023: * <pre>
024: * (1 - yfrac) * [(1 - xfrac)*s00 + xfrac*s01] +
025: * yfrac * [(1 - xfrac)*s10 + xfrac*s11]
026: * </pre>
027: *
028: * <p> A neighborhood extending one sample to the right of, and one
029: * sample below the central sample is required to perform bilinear
030: * interpolation. This implementation maintains equal subsampleBits in x and y.
031: *
032: * <p> The diagrams below illustrate the pixels involved in one-dimensional
033: * bilinear interpolation. Point s0 is the interpolation kernel key position.
034: * xfrac and yfrac, indicated by the dots, represent the point of interpolation
035: * between two pixels. This value lies between 0.0 and 1.0 exclusive for
036: * floating point and 0 and 2<sup>subsampleBits</sup> exclusive for integer
037: * interpolations.
038: *
039: * <pre>
040: * <b>
041: * Horizontal Vertical
042: *
043: * s0 . s1 s0
044: * ^ .< yfrac
045: * xfrac s1
046: * </b>
047: * </pre>
048: *
049: * <p> The diagram below illustrates the pixels involved in
050: * two-dimensional bilinear interpolation.
051: *
052: * <pre>
053: * <b>
054: * s00 s01
055: *
056: * . < yfrac
057: *
058: * s10 s11
059: * ^
060: * xfrac
061: * </b>
062: * </pre>
063: *
064: * <p> The class is marked 'final' so that it may be more easily inlined.
065: */
066: public final class InterpolationBilinear extends Interpolation {
067:
068: /** The value of 1.0 scaled by 2^subsampleBits */
069: private int one;
070:
071: /** The value of 0.5 scaled by 2^subsampleBits */
072: private int round;
073:
074: /** The number of bits to shift integer pixels to account for
075: * subsampleBits
076: */
077: private int shift;
078:
079: /** Twice the value of 'shift'. Accounts for accumulated
080: * scaling shifts in two-axis interpolation
081: */
082: private int shift2;
083:
084: /** The value of 0.5 scaled by 2^shift2 */
085: private int round2;
086:
087: static final int DEFAULT_SUBSAMPLE_BITS = 8;
088:
089: /**
090: * Constructs an InterpolationBilinear with a given subsample
091: * precision, in bits. This precision is applied to both axes.
092: *
093: * @param subsampleBits the subsample precision.
094: */
095: public InterpolationBilinear(int subsampleBits) {
096:
097: super (2, 2, 0, 1, 0, 1, subsampleBits, subsampleBits);
098:
099: shift = subsampleBits;
100: one = 1 << shift;
101: round = 1 << (shift - 1);
102:
103: shift2 = 2 * subsampleBits;
104: round2 = 1 << (shift2 - 1);
105: }
106:
107: /**
108: * Constructs an InterpolationBilinear with the default subsample
109: * precision 0f 8 bits.
110: */
111: public InterpolationBilinear() {
112: this (DEFAULT_SUBSAMPLE_BITS);
113: }
114:
115: /**
116: * Performs horizontal interpolation on a one-dimensional array of integral samples.
117: *
118: * @param samples an array of ints.
119: * @param xfrac the subsample position, multiplied by 2^(subsampleBits).
120: * @return the interpolated value as an int.
121: */
122: public final int interpolateH(int[] samples, int xfrac) {
123: return interpolateH(samples[0], samples[1], xfrac);
124: }
125:
126: /**
127: * Performs vertical interpolation on a one-dimensional array of integral samples.
128: *
129: * @param samples an array of ints.
130: * @param yfrac the Y subsample position, multiplied by 2^(subsampleBits).
131: * @return the interpolated value as an int.
132: */
133: public final int interpolateV(int[] samples, int yfrac) {
134: return interpolateV(samples[0], samples[1], yfrac);
135: }
136:
137: /**
138: * Performs interpolation on a two-dimensional array of integral samples.
139: *
140: * @param samples a two-dimensional array of ints.
141: * @param xfrac the X subsample position, multiplied by 2^(subsampleBits).
142: * @param yfrac the Y subsample position, multiplied by 2^(subsampleBits).
143: * @return the interpolated value as an int.
144: */
145: public final int interpolate(int[][] samples, int xfrac, int yfrac) {
146: return interpolate(samples[0][0], samples[0][1], samples[1][0],
147: samples[1][1], xfrac, yfrac);
148: }
149:
150: /**
151: * Performs horizontal interpolation on a pair of integral samples.
152: * This method may be used instead of the array version for speed.
153: *
154: * @param s0 the central sample.
155: * @param s1 the sample to the right of the central sample.
156: * @param xfrac the subsample position, multiplied by 2^(subsampleBits).
157: * @return the interpolated value as an int.
158: */
159: public final int interpolateH(int s0, int s1, int xfrac) {
160: return ((s1 - s0) * xfrac + (s0 << shift) + round) >> shift;
161: }
162:
163: /**
164: * Performs vertical interpolation on a pair of integral samples.
165: * This method may be used instead of the array version for speed.
166: *
167: * @param s0 the central sample.
168: * @param s1 the sample below the central sample.
169: * @param yfrac the Y subsample position, multiplied by 2^(subsampleBits).
170: * @return the interpolated value as an int.
171: */
172: public final int interpolateV(int s0, int s1, int yfrac) {
173: return ((s1 - s0) * yfrac + (s0 << shift) + round) >> shift;
174: }
175:
176: /**
177: * Performs horizontal interpolation on a quadruple of integral samples.
178: * The outlying samples are ignored.
179: */
180: public final int interpolateH(int s_, int s0, int s1, int s2,
181: int xfrac) {
182: return interpolateH(s0, s1, xfrac);
183: }
184:
185: /**
186: * Performs vertical interpolation on a quadruple of integral samples.
187: * The outlying samples are ignored.
188: */
189: public final int interpolateV(int s_, int s0, int s1, int s2,
190: int yfrac) {
191: return interpolateV(s0, s1, yfrac);
192: }
193:
194: /**
195: * Performs interpolation on a 2x2 grid of integral samples.
196: *
197: * @param s00 the central sample.
198: * @param s01 the sample to the right of the central sample.
199: * @param s10 the sample below the central sample.
200: * @param s11 the sample below and to the right of the central sample.
201: * @param xfrac the X subsample position, multiplied by 2^(subsampleBits).
202: * @param yfrac the Y subsample position, multiplied by 2^(subsampleBits).
203: * @return the interpolated value as an int.
204: */
205: public final int interpolate(int s00, int s01, int s10, int s11,
206: int xfrac, int yfrac) {
207: int s0 = (s01 - s00) * xfrac + (s00 << shift);
208: int s1 = (s11 - s10) * xfrac + (s10 << shift);
209: return ((s1 - s0) * yfrac + (s0 << shift) + round2) >> shift2;
210: }
211:
212: /**
213: * Performs interpolation on a 4x4 grid of integral samples.
214: * The outlying samples are ignored.
215: */
216: public final int interpolate(int s__, int s_0, int s_1, int s_2,
217: int s0_, int s00, int s01, int s02, int s1_, int s10,
218: int s11, int s12, int s2_, int s20, int s21, int s22,
219: int xfrac, int yfrac) {
220: return interpolate(s00, s01, s10, s11, xfrac, yfrac);
221: }
222:
223: /**
224: * Performs horizontal interpolation on a one-dimensional array of
225: * floating-point samples.
226: *
227: * @param samples an array of floats.
228: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
229: * @return the interpolated value as a float.
230: */
231: public final float interpolateH(float[] samples, float xfrac) {
232: return interpolateH(samples[0], samples[1], xfrac);
233: }
234:
235: /**
236: * Performs vertical interpolation on a one-dimensional array of
237: * floating-point samples.
238: *
239: * @param samples an array of floats.
240: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
241: * @return the interpolated value as a float.
242: */
243: public final float interpolateV(float[] samples, float yfrac) {
244: return interpolateV(samples[0], samples[1], yfrac);
245: }
246:
247: /**
248: * Performs interpolation on a two-dimensional array of
249: * floating-point samples.
250: *
251: * @param samples an array of floats.
252: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
253: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
254: * @return the interpolated value as a float.
255: */
256: public final float interpolate(float[][] samples, float xfrac,
257: float yfrac) {
258: return interpolate(samples[0][0], samples[0][1], samples[1][0],
259: samples[1][1], xfrac, yfrac);
260: }
261:
262: /**
263: * Performs horizontal interpolation on a horizontal pair of floating-point
264: * samples. This method may be used instead of the array version
265: * for speed.
266: *
267: * @param s0 the central sample.
268: * @param s1 the sample to the right of the central sample.
269: * @param xfrac the subsample position, in the range [0.0F, 1.0F).
270: * @return the interpolated value as a float.
271: */
272: public final float interpolateH(float s0, float s1, float xfrac) {
273: return (s1 - s0) * xfrac + s0;
274: }
275:
276: /**
277: * Performs vertical interpolation on a vertical pair of floating-point
278: * samples. This method may be used instead of the array version
279: * for speed.
280: *
281: * @param s0 the central sample.
282: * @param s1 the sample below the central sample.
283: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
284: * @return the interpolated value as a float.
285: */
286: public final float interpolateV(float s0, float s1, float yfrac) {
287: return (s1 - s0) * yfrac + s0;
288: }
289:
290: /**
291: * Performs horizontal interpolation on a horizontal quad of floating-point
292: * samples. The outlying samples are ignored.
293: */
294: public final float interpolateH(float s_, float s0, float s1,
295: float s2, float frac) {
296: return interpolateH(s0, s1, frac);
297: }
298:
299: /**
300: * Performs vertical interpolation on a horizontal quad of floating-point
301: * samples. The outlying samples are ignored.
302: */
303: public final float interpolateV(float s_, float s0, float s1,
304: float s2, float frac) {
305: return interpolateV(s0, s1, frac);
306: }
307:
308: /**
309: * Performs interpolation on a 2x2 grid of floating-point samples.
310: *
311: * @param s00 the central sample.
312: * @param s01 the sample to the right of the central sample.
313: * @param s10 the sample below the central sample.
314: * @param s11 the sample below and to the right of the central sample.
315: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
316: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
317: * @return the interpolated value as a float.
318: */
319: public final float interpolate(float s00, float s01, float s10,
320: float s11, float xfrac, float yfrac) {
321: float s0 = (s01 - s00) * xfrac + s00;
322: float s1 = (s11 - s10) * xfrac + s10;
323: return (s1 - s0) * yfrac + s0;
324: }
325:
326: /**
327: * Performs interpolation on a 4x4 grid. The outlying samples
328: * are ignored.
329: */
330: public final float interpolate(float s__, float s_0, float s_1,
331: float s_2, float s0_, float s00, float s01, float s02,
332: float s1_, float s10, float s11, float s12, float s2_,
333: float s20, float s21, float s22, float xfrac, float yfrac) {
334: return interpolate(s00, s01, s10, s11, xfrac, yfrac);
335: }
336:
337: /**
338: * Performs horizontal interpolation on a one-dimensional array of
339: * double samples.
340: *
341: * @param samples an array of doubles.
342: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
343: * @return the interpolated value as a double.
344: */
345: public final double interpolateH(double[] samples, float xfrac) {
346: return interpolateH(samples[0], samples[1], xfrac);
347: }
348:
349: /**
350: * Performs vertical interpolation on a one-dimensional array of
351: * double samples.
352: *
353: * @param samples an array of doubles.
354: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
355: * @return the interpolated value as a double.
356: */
357: public final double interpolateV(double[] samples, float yfrac) {
358: return interpolateV(samples[0], samples[1], yfrac);
359: }
360:
361: /**
362: * Performs interpolation on a two-dimensional array of
363: * double samples.
364: *
365: * @param samples an array of doubles.
366: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
367: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
368: * @return the interpolated value as a double.
369: */
370: public final double interpolate(double[][] samples, float xfrac,
371: float yfrac) {
372: return interpolate(samples[0][0], samples[0][1], samples[1][0],
373: samples[1][1], xfrac, yfrac);
374: }
375:
376: /**
377: * Performs horizontal interpolation on a horizontal pair of double
378: * samples. This method may be used instead of the array version
379: * for speed.
380: *
381: * @param s0 the central sample.
382: * @param s1 the sample to the right of the central sample.
383: * @param xfrac the subsample position, in the range [0.0F, 1.0F).
384: * @return the interpolated value as a double.
385: */
386: public final double interpolateH(double s0, double s1, float xfrac) {
387: return (s1 - s0) * xfrac + s0;
388: }
389:
390: /**
391: * Performs vertical interpolation on a vertical pair of double
392: * samples. This method may be used instead of the array version
393: * for speed.
394: *
395: * @param s0 the central sample.
396: * @param s1 the sample below the central sample.
397: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
398: * @return the interpolated value as a double.
399: */
400: public final double interpolateV(double s0, double s1, float yfrac) {
401: return (s1 - s0) * yfrac + s0;
402: }
403:
404: /**
405: * Performs interpolation on a horizontal quad of double
406: * samples. The outlying samples are ignored.
407: */
408: public final double interpolateH(double s_, double s0, double s1,
409: double s2, float xfrac) {
410: return interpolateH(s0, s1, xfrac);
411: }
412:
413: /**
414: * Performs vertical interpolation on a vertical quad of double
415: * samples. The outlying samples are ignored.
416: */
417: public final double interpolateV(double s_, double s0, double s1,
418: double s2, float yfrac) {
419: return interpolateV(s0, s1, yfrac);
420: }
421:
422: /**
423: * Performs interpolation on a 2x2 grid of double samples.
424: *
425: * @param s00 the central sample.
426: * @param s01 the sample to the right of the central sample.
427: * @param s10 the sample below the central sample.
428: * @param s11 the sample below and to the right of the central sample.
429: * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
430: * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
431: * @return the interpolated value as a double.
432: */
433: public final double interpolate(double s00, double s01, double s10,
434: double s11, float xfrac, float yfrac) {
435: double s0 = (s01 - s00) * xfrac + s00;
436: double s1 = (s11 - s10) * xfrac + s10;
437: return (s1 - s0) * yfrac + s0;
438: }
439:
440: /**
441: * Performs interpolation on a 4x4 grid. The outlying samples
442: * are ignored.
443: */
444: public final double interpolate(double s__, double s_0, double s_1,
445: double s_2, double s0_, double s00, double s01, double s02,
446: double s1_, double s10, double s11, double s12, double s2_,
447: double s20, double s21, double s22, float xfrac, float yfrac) {
448: return interpolate(s00, s01, s10, s11, xfrac, yfrac);
449: }
450: }
|