Source Code Cross Referenced for InterpolationTable.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » javax » media » jai » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » Java Advanced Imaging » javax.media.jai 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $RCSfile: InterpolationTable.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:11 $
0010:         * $State: Exp $
0011:         */
0012:        package javax.media.jai;
0013:
0014:        /**
0015:         * A subclass of Interpolation that uses tables to store the
0016:         * interpolation kernels.  The set of subpixel positions is broken up
0017:         * into a fixed number of "bins" and a distinct kernel is used for
0018:         * each bin.  The number of bins must be a power of two.
0019:         *
0020:         * <p> An InterpolationTable defines a separable interpolation, with a
0021:         * set of kernels for each dimension.  The number of bins may vary
0022:         * between the two dimensions. Both the horizontal and vertical
0023:         * interpolation kernels have a "key" element. This element is positioned
0024:         * over the 
0025:         which The kernels are stored in double precision,
0026:         * floating- and fixed-point form.  The fixed point representation has
0027:         * a user-specified fractional precision.  It is the user's
0028:         * responsibility to specify an appropriate level of precision that
0029:         * will not cause overflow when accumulating the results of a
0030:         * convolution against a set of source pixels, using 32-bit integer
0031:         * arithmetic.
0032:         */
0033:        public class InterpolationTable extends Interpolation {
0034:
0035:            /** The number of fractional bits used to describe filter coefficients. */
0036:            protected int precisionBits;
0037:
0038:            /** The scaled (by 2<sup>precisionBits</sup>) value of 0.5 for rounding */
0039:            private int round;
0040:
0041:            /** The number of horizontal subpixel positions within a pixel. */
0042:            private int numSubsamplesH;
0043:
0044:            /** The number of vertical subpixel positions within a pixel. */
0045:            private int numSubsamplesV;
0046:
0047:            /** The horizontal coefficient data in double format. */
0048:            protected double[] dataHd;
0049:
0050:            /** The vertical coefficient data in double format. */
0051:            protected double[] dataVd;
0052:
0053:            /** The horizontal coefficient data in floating-point format. */
0054:            protected float[] dataHf;
0055:
0056:            /** The vertical coefficient data in floating-point format. */
0057:            protected float[] dataVf;
0058:
0059:            /** The horizontal coefficient data in fixed-point format. */
0060:            protected int[] dataHi;
0061:
0062:            /** The vertical coefficient data in fixed-point format. */
0063:            protected int[] dataVi;
0064:
0065:            /**
0066:             * Constructs an InterpolationTable with specified horizontal and
0067:             * vertical extents (support), number of horizontal and vertical
0068:             * bins, fixed-point fractional precision, and int kernel entries.
0069:             * The kernel data values are organized as 
0070:             * <code>2<sup>subsampleBits</sup></code> entries each
0071:             * containing width ints.
0072:             *
0073:             * <p> dataH and dataV are required to contain width * <code>2<sup>subsampleBitsH</sup></code>
0074:             * and height * <code>2<sup>subsampleBitsV</sup></code> entries respectively, otherwise
0075:             * an IllegalArgumentException will be thrown.
0076:             *
0077:             * <p> If dataV is null, it is assumed to be a copy of dataH
0078:             * and the keyY, height, and subsampleBitsV parameters
0079:             * are ignored.
0080:             *
0081:             * @param keyX The array offset of the horizontal resampling kernel center
0082:             * @param keyY The array offset of the vertical resampling kernel center
0083:             * @param width the width of a horizontal resampling kernel.
0084:             * @param height the height of a vertical resampling kernel.  Ignored
0085:             *        if dataV is null.
0086:             * @param subsampleBitsH the log (base 2) of the number of horizontal
0087:             *        subsample positions. Must be positive.
0088:             * @param subsampleBitsV the log (base 2) of the number of vertical
0089:             *        subsample positions. Must be positive. Ignored if dataV is null. 
0090:             * @param precisionBits the number of bits of fractional precision
0091:             *        to be used when resampling integral sample values. Must be positive.
0092:             *        The same value is used for both horizontal and vertical
0093:             *        resampling.
0094:             * @param dataH the horizontal table entries, as an int array of
0095:             *        <code>2<sup>subsampleBitsH</sup></code> entries each of length width. The array is cloned internally.
0096:             * @param dataV the vertical table entries, as an int array of
0097:             *        <code>2<sup>subsampleBitsV</sup></code> entries each of length height, or null. The array is cloned internally.
0098:             *        If null, the dataH table is used for vertical interpolation
0099:             *        as well and the keyY, height, and subsampleBitsV
0100:             *        parameters are ignored.
0101:             * @throws IllegalArgumentException if the size of the data arrays
0102:             *         are incorrect.
0103:             */
0104:            public InterpolationTable(int keyX, int keyY, int width,
0105:                    int height, int subsampleBitsH, int subsampleBitsV,
0106:                    int precisionBits, int[] dataH, int[] dataV) {
0107:                // dataH has width*2^subsampleBitsH entries
0108:                // dataV has height*2^subsampleBitsV entries
0109:
0110:                super ();
0111:
0112:                this .leftPadding = keyX;
0113:                this .topPadding = keyY;
0114:                this .width = width;
0115:                this .rightPadding = width - keyX - 1;
0116:
0117:                this .precisionBits = precisionBits;
0118:                if (precisionBits > 0) {
0119:                    round = 1 << (precisionBits - 1);
0120:                }
0121:
0122:                this .subsampleBitsH = subsampleBitsH;
0123:                this .numSubsamplesH = (1 << subsampleBitsH);
0124:                int entriesH = width * numSubsamplesH;
0125:                if (dataH.length != entriesH) {
0126:                    throw new IllegalArgumentException(JaiI18N
0127:                            .getString("InterpolationTable0"));
0128:                }
0129:
0130:                double prec = (double) (1 << precisionBits);
0131:                int i;
0132:
0133:                this .dataHi = (int[]) dataH.clone();
0134:                this .dataHf = new float[entriesH];
0135:                this .dataHd = new double[entriesH];
0136:
0137:                for (i = 0; i < entriesH; i++) {
0138:                    double d = (double) dataHi[i] / prec;
0139:                    this .dataHf[i] = (float) d;
0140:                    this .dataHd[i] = d;
0141:                }
0142:
0143:                if (dataV != null) {
0144:                    this .height = height;
0145:                    this .subsampleBitsV = subsampleBitsV;
0146:                    this .numSubsamplesV = (1 << subsampleBitsV);
0147:                    int entriesV = height * numSubsamplesV;
0148:                    if (dataV.length != entriesV) {
0149:                        throw new IllegalArgumentException(JaiI18N
0150:                                .getString("InterpolationTable1"));
0151:                    }
0152:
0153:                    this .dataVi = (int[]) dataV.clone();
0154:                    this .dataVf = new float[entriesV];
0155:                    this .dataVd = new double[entriesV];
0156:                    for (i = 0; i < entriesV; i++) {
0157:                        double d = (double) dataVi[i] / prec;
0158:                        this .dataVf[i] = (float) d;
0159:                        this .dataVd[i] = d;
0160:                    }
0161:                } else {
0162:                    this .height = width;
0163:                    this .subsampleBitsV = subsampleBitsH;
0164:                    this .numSubsamplesV = numSubsamplesH;
0165:                    this .dataVf = dataHf;
0166:                    this .dataVi = dataHi;
0167:                    this .dataVd = dataHd;
0168:                }
0169:                this .bottomPadding = this .height - keyY - 1;
0170:            }
0171:
0172:            /**
0173:             * Constructs an InterpolationTable with identical horizontal and
0174:             * vertical resampling kernels.
0175:             *
0176:             * @param key The array offset of the central sample to be used during resampling.
0177:             * @param width the width or height of a resampling kernel.
0178:             * @param subsampleBits the log (base 2) of the number of
0179:             *        subsample positions. Must be positive. 
0180:             * @param precisionBits the number of bits of fractional precision
0181:             *        to be used when resampling integral sample values. Must be positive. 
0182:             * @param data the kernel entries, as an int array of
0183:             *        width*<code>2<sup>subsampleBits</sup></code> entries
0184:             */
0185:            public InterpolationTable(int key, int width, int subsampleBits,
0186:                    int precisionBits, int[] data) {
0187:
0188:                this (key, key, width, width, subsampleBits, subsampleBits,
0189:                        precisionBits, data, null);
0190:            }
0191:
0192:            /**
0193:             * Constructs an InterpolationTable with specified horizontal and
0194:             * vertical extents (support), number of horizontal and vertical
0195:             * bins, fixed-point fractional precision, and float kernel entries.
0196:             * The kernel data values are organized as <code>2<sup>subsampleBits</sup></code> entries each
0197:             * containing width floats.
0198:             *
0199:             * <p> dataH and dataV are required to contain width * <code>2<sup>subsampleBitsH</sup></code>
0200:             * and height * <code>2<sup>subsampleBitsV</sup></code> entries respectively, otherwise
0201:             * an IllegalArgumentException will be thrown.
0202:             *
0203:             * <p> If dataV is null, it is assumed to be a copy of dataH
0204:             * and the keyY, height, and subsampleBitsV parameters
0205:             * are ignored.
0206:             *
0207:             * @param keyX The array offset of the horizontal resampling kernel center
0208:             * @param keyY The array offset of the vertical resampling kernel center
0209:             * @param width the width of a horizontal resampling kernel.
0210:             * @param height the height of a vertical resampling kernel.  Ignored
0211:             *        if dataV is null.
0212:             * @param subsampleBitsH the log (base 2) of the number of horizontal
0213:             *        subsample positions. Must be positive. 
0214:             * @param subsampleBitsV the log (base 2) of the number of vertical
0215:             *        subsample positions. Must be positive.   Ignored if dataV is null.
0216:             * @param precisionBits the number of bits of fractional precision
0217:             *        to be used when resampling integral sample values.
0218:             *        The same value is used for both horizontal and vertical
0219:             *        resampling. Must be positive. 
0220:             * @param dataH the horizontal table entries, as a float array of
0221:             *        <code>2<sup>subsampleBitsH</sup></code> entries each of length width.
0222:             * @param dataV the vertical table entries, as a float array of
0223:             *        <code>2<sup>subsampleBitsV</sup></code> entries each of length height, or null.
0224:             *        If null, the dataH table is used for vertical interpolation
0225:             *        as well and the keyY, height, and subsampleBitsV
0226:             *        parameters are ignored.
0227:             * @throws IllegalArgumentException if the size of the data arrays
0228:             *         are incorrect.
0229:             */
0230:            public InterpolationTable(int keyX, int keyY, int width,
0231:                    int height, int subsampleBitsH, int subsampleBitsV,
0232:                    int precisionBits, float[] dataH, float[] dataV) {
0233:                // dataH has width*2^subsampleBitsH entries
0234:                // dataV has height*2^subsampleBitsV entries
0235:
0236:                super ();
0237:
0238:                this .leftPadding = keyX;
0239:                this .topPadding = keyY;
0240:                this .width = width;
0241:                this .rightPadding = width - keyX - 1;
0242:
0243:                this .precisionBits = precisionBits;
0244:                if (precisionBits > 0) {
0245:                    round = 1 << (precisionBits - 1);
0246:                }
0247:
0248:                this .subsampleBitsH = subsampleBitsH;
0249:                this .numSubsamplesH = (1 << subsampleBitsH);
0250:                int entriesH = width * numSubsamplesH;
0251:                if (dataH.length != entriesH) {
0252:                    throw new IllegalArgumentException(JaiI18N
0253:                            .getString("InterpolationTable0"));
0254:                }
0255:
0256:                float prec = (float) (1 << precisionBits);
0257:                int i;
0258:
0259:                this .dataHf = (float[]) dataH.clone();
0260:                this .dataHi = new int[entriesH];
0261:                this .dataHd = new double[entriesH];
0262:
0263:                for (i = 0; i < entriesH; i++) {
0264:                    float f = dataHf[i];
0265:                    this .dataHi[i] = Math.round(f * prec);
0266:                    this .dataHd[i] = f;
0267:                }
0268:
0269:                if (dataV != null) {
0270:                    this .height = height;
0271:                    this .subsampleBitsV = subsampleBitsV;
0272:                    this .numSubsamplesV = (1 << subsampleBitsV);
0273:                    int entriesV = height * numSubsamplesV;
0274:                    if (dataV.length != entriesV) {
0275:                        throw new IllegalArgumentException(JaiI18N
0276:                                .getString("InterpolationTable1"));
0277:                    }
0278:
0279:                    this .dataVf = (float[]) dataV.clone();
0280:                    this .dataVi = new int[entriesV];
0281:                    this .dataVd = new double[entriesV];
0282:                    for (i = 0; i < entriesV; i++) {
0283:                        float f = dataVf[i];
0284:                        this .dataVi[i] = Math.round(f * prec);
0285:                        this .dataVd[i] = f;
0286:                    }
0287:                } else {
0288:                    this .height = width;
0289:                    this .subsampleBitsV = subsampleBitsH;
0290:                    this .numSubsamplesV = numSubsamplesH;
0291:                    this .dataVf = dataHf;
0292:                    this .dataVi = dataHi;
0293:                    this .dataVd = dataHd;
0294:                }
0295:                this .bottomPadding = this .height - keyY - 1;
0296:            }
0297:
0298:            /**
0299:             * Constructs an InterpolationTable with identical horizontal and
0300:             * vertical resampling kernels.
0301:             *
0302:             * @param key The number of samples to the left or above the
0303:             *                    central sample to be used during resampling.
0304:             * @param width the width or height of a resampling kernel.
0305:             * @param subsampleBits the log (base 2) of the number of
0306:             *        subsample positions. Must be positive. 
0307:             * @param precisionBits the number of bits of fractional precision
0308:             *        to be used when resampling integral sample values. Must be positive. 
0309:             * @param data the kernel entries, as a float array of
0310:             *        width*<code>2<sup>subsampleBits</sup></code> entries
0311:             */
0312:            public InterpolationTable(int key, int width, int subsampleBits,
0313:                    int precisionBits, float[] data) {
0314:
0315:                this (key, key, width, width, subsampleBits, subsampleBits,
0316:                        precisionBits, data, null);
0317:            }
0318:
0319:            /**
0320:             * Constructs an InterpolationTable with specified horizontal and
0321:             * vertical extents (support), number of horizontal and vertical
0322:             * bins, fixed-point fractional precision, and double kernel entries.
0323:             * The kernel data values are organized as <code>2<sup>subsampleBits</sup></code> entries each
0324:             * containing width doubles.
0325:             *
0326:             * <p> dataH and dataV are required to contain width * <code>2<sup>subsampleBitsH</sup></code>
0327:             * and height * <code>2<sup>subsampleBitsV</sup></code> entries respectively, otherwise
0328:             * an IllegalArgumentException will be thrown.
0329:             *
0330:             * <p> If dataV is null, it is assumed to be a copy of dataH
0331:             * and the keyY, height, and subsampleBitsV parameters
0332:             * are ignored.
0333:             *
0334:             * @param keyX The array offset of the horizontal resampling kernel center
0335:             * @param keyY The array offset of the vertical resampling kernel center
0336:             * @param width the width of a horizontal resampling kernel.
0337:             * @param height the height of a vertical resampling kernel.  Ignored
0338:             *        if dataV is null.
0339:             * @param subsampleBitsH the log (base 2) of the number of horizontal
0340:             *        subsample positions. Must be positive. 
0341:             * @param subsampleBitsV the log (base 2) of the number of vertical
0342:             *        subsample positions. Must be positive.   Ignored if dataV is null.
0343:             * @param precisionBits the number of bits of fractional precision
0344:             *        to be used when resampling integral sample values.
0345:             *        The same value is used for both horizontal and vertical
0346:             *        resampling. Must be positive. 
0347:             * @param dataH the horizontal table entries, as a double array of
0348:             *        <code>2<sup>subsampleBitsH</sup></code> entries each of length width.
0349:             * @param dataV the vertical table entries, as a double array of
0350:             *        <code>2<sup>subsampleBitsV</sup></code> entries each of length height, or null.
0351:             *        If null, the dataH table is used for vertical interpolation
0352:             *        as well and the keyY, height, and subsampleBitsV
0353:             *        parameters are ignored.
0354:             */
0355:            public InterpolationTable(int keyX, int keyY, int width,
0356:                    int height, int subsampleBitsH, int subsampleBitsV,
0357:                    int precisionBits, double[] dataH, double[] dataV) {
0358:                // dataH has width*2^subsampleBitsH entries
0359:                // dataV has height*2^subsampleBitsV entries
0360:
0361:                super ();
0362:
0363:                this .leftPadding = keyX;
0364:                this .topPadding = keyY;
0365:                this .width = width;
0366:                this .rightPadding = width - keyX - 1;
0367:
0368:                this .precisionBits = precisionBits;
0369:                if (precisionBits > 0) {
0370:                    round = 1 << (precisionBits - 1);
0371:                }
0372:
0373:                this .subsampleBitsH = subsampleBitsH;
0374:                this .numSubsamplesH = (1 << subsampleBitsH);
0375:                int entriesH = width * numSubsamplesH;
0376:                if (dataH.length != entriesH) {
0377:                    throw new IllegalArgumentException(JaiI18N
0378:                            .getString("InterpolationTable0"));
0379:                }
0380:
0381:                double prec = (double) (1 << precisionBits);
0382:                int i;
0383:
0384:                this .dataHd = (double[]) dataH.clone();
0385:                this .dataHi = new int[entriesH];
0386:                this .dataHf = new float[entriesH];
0387:                for (i = 0; i < entriesH; i++) {
0388:                    double d = dataHd[i];
0389:                    this .dataHi[i] = (int) Math.round(d * prec);
0390:                    this .dataHf[i] = (float) d;
0391:                }
0392:
0393:                if (dataV != null) {
0394:                    this .height = height;
0395:                    this .subsampleBitsV = subsampleBitsV;
0396:                    this .numSubsamplesV = (1 << subsampleBitsV);
0397:                    int entriesV = height * numSubsamplesV;
0398:                    if (dataV.length != entriesV) {
0399:                        throw new IllegalArgumentException(JaiI18N
0400:                                .getString("InterpolationTable1"));
0401:                    }
0402:
0403:                    this .dataVd = (double[]) dataV.clone();
0404:                    this .dataVi = new int[entriesV];
0405:                    this .dataVf = new float[entriesV];
0406:                    for (i = 0; i < entriesV; i++) {
0407:                        double d = dataVd[i];
0408:                        this .dataVi[i] = (int) Math.round(d * prec);
0409:                        this .dataVf[i] = (float) d;
0410:                    }
0411:                } else {
0412:                    this .height = width;
0413:                    this .subsampleBitsV = subsampleBitsH;
0414:                    this .numSubsamplesV = numSubsamplesH;
0415:                    this .dataVd = dataHd;
0416:                    this .dataVf = dataHf;
0417:                    this .dataVi = dataHi;
0418:                }
0419:                this .bottomPadding = this .height - keyY - 1;
0420:            }
0421:
0422:            /**
0423:             * Constructs an InterpolationTable with identical horizontal and
0424:             * vertical resampling kernels.
0425:             *
0426:             * @param key The number of samples to the left or above the
0427:             *                    central sample to be used during resampling.
0428:             * @param width the width or height of a resampling kernel.
0429:             * @param subsampleBits the log (base 2) of the number of
0430:             *        subsample positions. Must be positive. 
0431:             * @param precisionBits the number of bits of fractional precision
0432:             *        to be used when resampling integral sample values. Must be positive. 
0433:             * @param data the kernel entries, as a double array of
0434:             *        width*<code>2<sup>subsampleBitsH</sup></code> entries
0435:             */
0436:            public InterpolationTable(int key, int width, int subsampleBits,
0437:                    int precisionBits, double[] data) {
0438:
0439:                this (key, key, width, width, subsampleBits, subsampleBits,
0440:                        precisionBits, data, null);
0441:            }
0442:
0443:            /**
0444:             * Returns the number of bits of fractional precision used to
0445:             * store the fixed-point table entries.
0446:             */
0447:            public int getPrecisionBits() {
0448:                return precisionBits;
0449:            }
0450:
0451:            /**
0452:             * Returns the integer (fixed-point) horizontal table data.  The
0453:             * output is an <code>int</code> array of length
0454:             * <code>getWidth() * 2<sup>getSubsampleBitsH()</sup></code>.
0455:             * 
0456:             * <p> The following code, given an instance <code>interp</code>
0457:             * of class <code>InterpolationTable</code>, will perform
0458:             * interpolation of a set of <code>getWidth()</code> samples
0459:             * at a given fractional position (bin) <code>xfrac</code>
0460:             * between <code>0</code> and <code>2<sup>getSubsampleBitsH() - 1</sup></code>:
0461:             *
0462:             * <pre>
0463:             * int interpolateH(InterpolationTable interp, int[] samples, int xfrac) {
0464:             *     int[] dataH = interp.getHorizontalTableData();
0465:             *     int precisionBits = interp.getPrecisionBits();
0466:             *     int round = 1 << (precisionBits - 1);
0467:             *     int width = interp.getWidth();
0468:             *     int offset = width*xfrac;
0469:             *
0470:             *     int sum = 0;
0471:             *     for (int i = 0; i < width; i++) {
0472:             *         sum += dataH[offset + i]*samples[i];
0473:             *     }
0474:             *     return (sum + round) >> precisionBits;
0475:             * }
0476:             * </pre>
0477:             *
0478:             * <p> In practice, the values <code>dataH</code>,
0479:             * <code>precisionBits</code>, etc., may be extracted once and
0480:             * reused to interpolate multiple output pixels.
0481:             *
0482:             * @return An array of <code>int</code>s.
0483:             */
0484:            public int[] getHorizontalTableData() {
0485:                return dataHi;
0486:            }
0487:
0488:            /**
0489:             * Returns the integer (fixed-point) vertical table data.  The
0490:             * output is an <code>int</code> array of length
0491:             * <code>getHeight() * 2<sup>getSubsampleBitsV()</sup></code>.
0492:             * 
0493:             * <p> The following code, given an instance <code>interp</code>
0494:             * of class <code>InterpolationTable</code>, will perform
0495:             * interpolation of a set of <code>getHeight()</code> samples
0496:             * at a given fractional position (bin) <code>yfrac</code>
0497:             * between <code>0</code> and <code>2<sup>getSubsampleBitsV() - 1</sup></code>:
0498:             *
0499:             * <pre>
0500:             * int interpolateV(InterpolationTable interp, int[] samples, int yfrac) {
0501:             *     int[] dataV = interp.getVerticalTableData();
0502:             *     int precisionBits = interp.getPrecisionBits();
0503:             *     int round = 1 << (precisionBits - 1);
0504:             *     int height = interp.getHeight();
0505:             *     int offset = height*yfrac;
0506:             *
0507:             *     int sum = 0;
0508:             *     for (int i = 0; i < height; i++) {
0509:             *         sum += dataV[offset + i]*samples[i];
0510:             *     }
0511:             *     return (sum + round) >> precisionBits;
0512:             * }
0513:             * </pre>
0514:             *
0515:             * <p> In practice, the values <code>dataV</code>,
0516:             * <code>precisionBits</code>, etc., may be extracted once and
0517:             * reused to interpolate multiple output pixels.
0518:             *
0519:             * @return An array of <code>int</code>s.
0520:             */
0521:            public int[] getVerticalTableData() {
0522:                return dataVi;
0523:            }
0524:
0525:            /**
0526:             * Returns the floating-point horizontal table data.  The output is a
0527:             * <code>float</code> array of length
0528:             * <code>getWidth() * 2<sup>getSubsampleBitsH()</sup></code>.
0529:             * 
0530:             * <p> The following code, given an instance <code>interp</code>
0531:             * of class <code>InterpolationTable</code>, will perform
0532:             * interpolation of a set of <code>getWidth()</code>
0533:             * floating-point samples at a given fractional position
0534:             * <code>xfrac</code> between <code>0.0F</code> and <code>1.0F</code>:
0535:             *
0536:             * <pre>
0537:             * float interpolateH(InterpolationTable interp,
0538:             *                    float[] samples, float xfrac) {
0539:             *     float[] dataH = interp.getHorizontalTableDataFloat();
0540:             *     int width = interp.getWidth();
0541:             *     int numSubsamplesH = 1 << getSubsampleBitsH();
0542:             *     int ifrac = (int)(xfrac*numSubsamplesH);
0543:             *     int offset = width*ifrac;
0544:             *
0545:             *     float sum = 0.0F;
0546:             *     for (int i = 0; i < width; i++) {
0547:             *         sum += dataH[offset + i]*samples[i];
0548:             *     }
0549:             *     return sum;
0550:             * }
0551:             * </pre>
0552:             *
0553:             * <p> In practice, the values <code>dataH</code>,
0554:             * <code>numSubsamplesH</code>, etc., may be extracted once and
0555:             * reused to interpolate multiple output pixels.
0556:             *
0557:             * @return An array of <code>float</code>s.
0558:             */
0559:            public float[] getHorizontalTableDataFloat() {
0560:                return dataHf;
0561:            }
0562:
0563:            /**
0564:             * Returns the floating-point vertical table data.  The output is a
0565:             * <code>float</code> array of length
0566:             * <code>getWidth() * 2<sup>getSubsampleBitsV()</sup></code>.
0567:             * 
0568:             * <p> The following code, given an instance <code>interp</code>
0569:             * of class <code>InterpolationTable</code>, will perform
0570:             * interpolation of a set of <code>getHeight()</code>
0571:             * floating-point samples at a given fractional position
0572:             * <code>yfrac</code> between <code>0.0F</code> and <code>1.0F</code>:
0573:             *
0574:             * <pre>
0575:             * float interpolateV(InterpolationTable interp,
0576:             *                    float[] samples, float yfrac) {
0577:             *     float[] dataV = interp.getVerticalTableDataFloat();
0578:             *     int height = interp.getHeight();
0579:             *     int numSubsamplesV = 1 << getSubsampleBitsV();
0580:             *     int ifrac = (int)(yfrac*numSubsamplesV);
0581:             *     int offset = height*ifrac;
0582:             *
0583:             *     float sum = 0.0F;
0584:             *     for (int i = 0; i < height; i++) {
0585:             *         sum += dataV[offset + i]*samples[i];
0586:             *     }
0587:             *     return sum;
0588:             * }
0589:             * </pre>
0590:             *
0591:             * <p> In practice, the values <code>dataV</code>,
0592:             * <code>numSubsamplesV</code>, etc., may be extracted once and
0593:             * reused to interpolate multiple output pixels.
0594:             *
0595:             * @return An array of <code>float</code>s.
0596:             */
0597:            public float[] getVerticalTableDataFloat() {
0598:                return dataVf;
0599:            }
0600:
0601:            /**
0602:             * Returns the double horizontal table data.  The output is a
0603:             * <code>double</code> array of length
0604:             * <code>getWidth() * 2<sup>getSubsampleBitsH()</sup></code>.
0605:             * 
0606:             * <p> The following code, given an instance <code>interp</code>
0607:             * of class <code>InterpolationTable</code>, will perform
0608:             * interpolation of a set of <code>getWidth()</code>
0609:             * double samples at a given fractional position
0610:             * <code>xfrac</code> between <code>0.0F</code> and <code>1.0F</code>:
0611:             *
0612:             * <pre>
0613:             * double interpolateH(InterpolationTable interp,
0614:             *                     double[] samples, float xfrac) {
0615:             *     double[] dataH = interp.getHorizontalTableDataDouble();
0616:             *     int width = interp.getWidth();
0617:             *     int numSubsamplesH = 1 << getSubsampleBitsH();
0618:             *     int ifrac = (int)(xfrac*numSubsamplesH);
0619:             *     int offset = width*ifrac;
0620:             *
0621:             *     double sum = 0.0;
0622:             *     for (int i = 0; i < width; i++) {
0623:             *         sum += dataH[offset + i]*samples[i];
0624:             *     }
0625:             *     return sum;
0626:             * }
0627:             * </pre>
0628:             *
0629:             * <p> In practice, the values <code>dataH</code>,
0630:             * <code>numSubsamplesH</code>, etc., may be extracted once and
0631:             * reused to interpolate multiple output pixels.
0632:             *
0633:             * @return An array of <code>double</code>s.
0634:             */
0635:            public double[] getHorizontalTableDataDouble() {
0636:                return dataHd;
0637:            }
0638:
0639:            /**
0640:             * Returns the double vertical table data.  The output is a
0641:             * <code>double</code> array of length
0642:             * <code>getHeight() * 2<sup>getSubsampleBitsV()</sup></code>).
0643:             * 
0644:             * <p> The following code, given an instance <code>interp</code>
0645:             * of class <code>InterpolationTable</code>, will perform
0646:             * interpolation of a set of <code>getHeight()</code>
0647:             * double samples at a given fractional position
0648:             * <code>yfrac</code> between <code>0.0F</code> and <code>1.0F</code>:
0649:             *
0650:             * <pre>
0651:             * double interpolateV(InterpolationTable interp,
0652:             *                     double[] samples, float yfrac) {
0653:             *     double[] dataV = interp.getVerticalTableDataDouble();
0654:             *     int height = interp.getHeight();
0655:             *     int numSubsamplesV = 1 << getSubsampleBitsV();
0656:             *     int ifrac = (int)(yfrac*numSubsamplesV);
0657:             *     int offset = height*ifrac;
0658:             *
0659:             *     double sum = 0.0;
0660:             *     for (int i = 0; i < height; i++) {
0661:             *         sum += dataV[offset + i]*samples[i];
0662:             *     }
0663:             *     return sum;
0664:             * }
0665:             * </pre>
0666:             *
0667:             * <p> In practice, the values <code>dataV</code>,
0668:             * <code>numSubsamplesV</code>, etc., may be extracted once and
0669:             * reused to interpolate multiple output pixels.
0670:             *
0671:             * @return An array of <code>double</code>s.
0672:             */
0673:            public double[] getVerticalTableDataDouble() {
0674:                return dataVd;
0675:            }
0676:
0677:            /**
0678:             * Performs horizontal interpolation on a one-dimensional array of
0679:             * integral samples.
0680:             *
0681:             * If xfrac does not lie between 0 and <code>2<sup>subsampleBitsH-1</sup></code>, an
0682:             * ArrayIndexOutOfBoundsException may occur, where width is the width 
0683:             * of the horizontal resampling kernel.
0684:             *
0685:             * @param samples an array of ints.
0686:             * @param xfrac the subsample position, multiplied by <code>2<sup>subsampleBitsH</sup></code>.
0687:             * @return the interpolated value as an int.
0688:             * @throws ArrayIndexOutOfBoundsException if xfrac is out of bounds.
0689:             */
0690:            public int interpolateH(int[] samples, int xfrac) {
0691:                int sum = 0;
0692:                int offset = width * xfrac;
0693:
0694:                for (int i = 0; i < width; i++) {
0695:                    sum += dataHi[offset + i] * samples[i];
0696:                }
0697:                return (sum + round) >> precisionBits;
0698:            }
0699:
0700:            /**
0701:             * Performs vertical interpolation on a one-dimensional array of
0702:             * integral samples.
0703:             *
0704:             * If yfrac does not lie between 0 and <code>2<sup>subsampleBitsV-1</sup></code>, an
0705:             * ArrayIndexOutOfBoundsException may occur, where height is the 
0706:             * height of the vertical resampling kernel.
0707:             *
0708:             * @param samples an array of ints.
0709:             * @param yfrac the Y subsample position, multiplied by <code>2<sup>subsampleBitsV</sup></code>.
0710:             * @return the interpolated value as an int.
0711:             * @throws ArrayIndexOutOfBoundsException if yfrac is out of bounds.
0712:             */
0713:            public int interpolateV(int[] samples, int yfrac) {
0714:                int sum = 0;
0715:                int offset = width * yfrac;
0716:
0717:                for (int i = 0; i < width; i++) {
0718:                    sum += dataVi[offset + i] * samples[i];
0719:                }
0720:                return (sum + round) >> precisionBits;
0721:            }
0722:
0723:            /**
0724:             * Performs horizontal interpolation on a pair of integral samples.
0725:             * This method may be used instead of the array version for speed.
0726:             * It should only be called if width == 2.
0727:             *
0728:             * If xfrac does not lie between 0 and <code>2<sup>subsampleBitsH-1</sup></code>, an
0729:             * ArrayIndexOutOfBoundsException may occur, where width is the width 
0730:             * of the horizontal resampling kernel.
0731:             *
0732:             * @param s0 the central sample.
0733:             * @param s1 the sample to the right of the central sample.
0734:             * @param xfrac the subsample position, multiplied by <code>2<sup>subsampleBitsH</sup></code>.
0735:             * @return the interpolated value as an int.
0736:             * @throws ArrayIndexOutOfBoundsException if xfrac is out of bounds.
0737:             */
0738:            public int interpolateH(int s0, int s1, int xfrac) {
0739:                // Assume width == 2
0740:                int offset = 2 * xfrac;
0741:                int sum = dataHi[offset] * s0;
0742:                sum += dataHi[offset + 1] * s1;
0743:                return (sum + round) >> precisionBits;
0744:            }
0745:
0746:            /**
0747:             * Performs horizontal interpolation on a quadruple of integral samples.
0748:             * This method may be used instead of the array version for speed.
0749:             * It should only be called if width == 4 and keyX == 1.
0750:             *
0751:             * If xfrac does not lie between 0 and <code>2<sup>subsampleBitsH-1</sup></code>, an
0752:             * ArrayIndexOutOfBoundsException may occur, where width is the width 
0753:             * of the horizontal resampling kernel.
0754:             *
0755:             * @param s_ the sample to the left of the central sample.
0756:             * @param s0 the central sample.
0757:             * @param s1 the sample to the right of the central sample.
0758:             * @param s2 the sample to the right of s1.
0759:             * @param xfrac the subsample position, multiplied by <code>2<sup>subsampleBitsH</sup></code>.
0760:             * @return the interpolated value as an int.
0761:             * @throws ArrayIndexOutOfBoundsException if xfrac is out of bounds.
0762:             */
0763:            public int interpolateH(int s_, int s0, int s1, int s2, int xfrac) {
0764:                // Assume width == 4
0765:                int offset = 4 * xfrac;
0766:                int sum = dataHi[offset] * s_;
0767:                sum += dataHi[offset + 1] * s0;
0768:                sum += dataHi[offset + 2] * s1;
0769:                sum += dataHi[offset + 3] * s2;
0770:                return (sum + round) >> precisionBits;
0771:            }
0772:
0773:            /**
0774:             * Performs vertical interpolation on a pair of integral samples.
0775:             * This method may be used instead of the array version for speed.
0776:             * It should only be called if height == 2 and keyY == 0.
0777:             *
0778:             * If yfrac does not lie between 0 and <code>2<sup>subsampleBitsV-1</sup></code>, an
0779:             * ArrayIndexOutOfBoundsException may occur, where height is the  
0780:             * height of the vertical resampling kernel.
0781:             *
0782:             * @param s0 the central sample.
0783:             * @param s1 the sample below the central sample.
0784:             * @param yfrac the Y subsample position, multiplied by <code>2<sup>subsampleBitsV</sup></code>.
0785:             * @return the interpolated value as an int.
0786:             * @throws ArrayIndexOutOfBoundsException if yfrac is out of bounds.
0787:             */
0788:            public int interpolateV(int s0, int s1, int yfrac) {
0789:                // Assume width == 2
0790:                int offset = 2 * yfrac;
0791:                int sum = dataVi[offset] * s0;
0792:                sum += dataVi[offset + 1] * s1;
0793:                return (sum + round) >> precisionBits;
0794:            }
0795:
0796:            /**
0797:             * Performs vertical interpolation on a quadruple of integral samples.
0798:             * This method may be used instead of the array version for speed.
0799:             * It should only be called if height == 4 and keyY == 1.
0800:             *
0801:             * If yfrac does not lie between 0 and <code>2<sup>subsampleBitsV-1</sup></code>, an
0802:             * ArrayIndexOutOfBoundsException may occur, where height is the 
0803:             * height of the vertical resampling kernel.
0804:             *
0805:             * @param s_ the sample above the central sample.
0806:             * @param s0 the central sample.
0807:             * @param s1 the sample below the central sample.
0808:             * @param s2 the sample below s1.
0809:             * @param yfrac the Y subsample position, multiplied by <code>2<sup>subsampleBitsV</sup></code>.
0810:             * @return the interpolated value as an int.
0811:             * @throws ArrayIndexOutOfBoundsException if yfrac is out of bounds.
0812:             */
0813:            public int interpolateV(int s_, int s0, int s1, int s2, int yfrac) {
0814:                // Assume width == 4
0815:                int offset = 4 * yfrac;
0816:                int sum = dataVi[offset] * s_;
0817:                sum += dataVi[offset + 1] * s0;
0818:                sum += dataVi[offset + 2] * s1;
0819:                sum += dataVi[offset + 3] * s2;
0820:                return (sum + round) >> precisionBits;
0821:            }
0822:
0823:            /**
0824:             * Performs interpolation on a 2x2 grid of integral samples.
0825:             * It should only be called if width == height == 2 and
0826:             * keyX == keyY == 0.
0827:             *
0828:             * If xfrac does not lie between 0 and <code>2<sup>subsampleBitsH-1</sup></code>, or
0829:             * yfrac does not lie between 0 and <code>2<sup>subsampleBitsV-1</sup></code>, an 
0830:             * ArrayIndexOutOfBoundsException may occur, where width and height 
0831:             * are the width and height of the horizontal and vertical resampling
0832:             * kernels respectively.
0833:             *
0834:             * @param s00 the central sample.
0835:             * @param s01 the sample to the right of the central sample.
0836:             * @param s10 the sample below the central sample.
0837:             * @param s11 the sample below and to the right of the central sample.
0838:             * @param xfrac the X subsample position, multiplied by <code>2<sup>subsampleBitsH</sup></code>.
0839:             * @param yfrac the Y subsample position, multiplied by <code>2<sup>subsampleBitsV</sup></code>.
0840:             * @return the interpolated value as an int.
0841:             * @throws ArrayIndexOutOfBoundsException if xfrac or yfrac are out of bounds.
0842:             */
0843:            public int interpolate(int s00, int s01, int s10, int s11,
0844:                    int xfrac, int yfrac) {
0845:                // Interpolate in X
0846:                int offsetX = 2 * xfrac;
0847:                int sum0 = dataHi[offsetX] * s00 + dataHi[offsetX + 1] * s01;
0848:                int sum1 = dataHi[offsetX] * s10 + dataHi[offsetX + 1] * s11;
0849:
0850:                // Intermediate rounding
0851:                sum0 = (sum0 + round) >> precisionBits;
0852:                sum1 = (sum1 + round) >> precisionBits;
0853:
0854:                // Interpolate in Y
0855:                int offsetY = 2 * yfrac;
0856:                int sum = dataVi[offsetY] * sum0 + dataVi[offsetY + 1] * sum1;
0857:
0858:                return (sum + round) >> precisionBits;
0859:            }
0860:
0861:            /**
0862:             * Performs interpolation on a 4x4 grid of integral samples.
0863:             * It should only be called if width == height == 4 and
0864:             * keyX == keyY == 1.
0865:             *
0866:             * If xfrac does not lie between 0 and <code>2<sup>subsampleBitsH-1</sup></code>, or
0867:             * yfrac does not lie between 0 and <code>2<sup>subsampleBitsV-1</sup></code>, an
0868:             * ArrayIndexOutOfBoundsException may occur, where width and height 
0869:             * are the the width and height of the horizontal and vertical 
0870:             * resampling kernels respectively.
0871:             *
0872:             * @param s__ the sample above and to the left of the central sample.
0873:             * @param s_0 the sample above the central sample.
0874:             * @param s_1 the sample above and one to the right of the central sample.
0875:             * @param s_2 the sample above and two to the right of the central sample.
0876:             * @param s0_ the sample to the left of the central sample.
0877:             * @param s00 the central sample.
0878:             * @param s01 the sample to the right of the central sample.
0879:             * @param s02 the sample two to the right of the central sample.
0880:             * @param s1_ the sample below and one to the left of the central sample.
0881:             * @param s10 the sample below the central sample.
0882:             * @param s11 the sample below and one to the right of the central sample.
0883:             * @param s12 the sample below and two to the right of the central sample.
0884:             * @param s2_ the sample two below and one to the left of the central sample.
0885:             * @param s20 the sample two below the central sample.
0886:             * @param s21 the sample two below and one to the right of the central sample.
0887:             * @param s22 the sample two below and two to the right of the central sample.
0888:             * @param xfrac the X subsample position, multiplied by <code>2<sup>subsampleBitsH</sup></code>.
0889:             * @param yfrac the Y subsample position, multiplied by <code>2<sup>subsampleBitsV</sup></code>.
0890:             * @return the interpolated value as an int.
0891:             * @throws ArrayIndexOutOfBoundsException if xfrac or yfrac are out of bounds.
0892:             */
0893:            public int interpolate(int s__, int s_0, int s_1, int s_2, int s0_,
0894:                    int s00, int s01, int s02, int s1_, int s10, int s11,
0895:                    int s12, int s2_, int s20, int s21, int s22, int xfrac,
0896:                    int yfrac) {
0897:
0898:                // Interpolate in X
0899:                int offsetX = 4 * xfrac;
0900:                int offsetX1 = offsetX + 1;
0901:                int offsetX2 = offsetX + 2;
0902:                int offsetX3 = offsetX + 3;
0903:
0904:                long sum_ = (long) dataHi[offsetX] * s__;
0905:                sum_ += (long) dataHi[offsetX1] * s_0;
0906:                sum_ += (long) dataHi[offsetX2] * s_1;
0907:                sum_ += (long) dataHi[offsetX3] * s_2;
0908:
0909:                long sum0 = (long) dataHi[offsetX] * s0_;
0910:                sum0 += (long) dataHi[offsetX1] * s00;
0911:                sum0 += (long) dataHi[offsetX2] * s01;
0912:                sum0 += (long) dataHi[offsetX3] * s02;
0913:
0914:                long sum1 = (long) dataHi[offsetX] * s1_;
0915:                sum1 += (long) dataHi[offsetX1] * s10;
0916:                sum1 += (long) dataHi[offsetX2] * s11;
0917:                sum1 += (long) dataHi[offsetX3] * s12;
0918:
0919:                long sum2 = (long) dataHi[offsetX] * s2_;
0920:                sum2 += (long) dataHi[offsetX1] * s20;
0921:                sum2 += (long) dataHi[offsetX2] * s21;
0922:                sum2 += (long) dataHi[offsetX3] * s22;
0923:
0924:                // Intermediate rounding
0925:                sum_ = (sum_ + round) >> precisionBits;
0926:                sum0 = (sum0 + round) >> precisionBits;
0927:                sum1 = (sum1 + round) >> precisionBits;
0928:                sum2 = (sum2 + round) >> precisionBits;
0929:
0930:                // Interpolate in Y
0931:                int offsetY = 4 * yfrac;
0932:                long sum = (long) dataVi[offsetY] * sum_;
0933:                sum += (long) dataVi[offsetY + 1] * sum0;
0934:                sum += (long) dataVi[offsetY + 2] * sum1;
0935:                sum += (long) dataVi[offsetY + 3] * sum2;
0936:
0937:                return (int) ((sum + round) >> precisionBits);
0938:            }
0939:
0940:            /**
0941:             * Performs interpolation on a 4x4 grid of integral samples. All
0942:             * internal calculations are performed in floating-point.
0943:             * It should only be called if width == height == 4 and
0944:             * keyX == keyY == 1.
0945:             *
0946:             * If xfrac does not lie between 0 and <code>2<sup>subsampleBitsH-1</sup></code>, or
0947:             * yfrac does not lie between 0 and <code>2<sup>subsampleBitsV-1</sup></code>, an
0948:             * ArrayIndexOutOfBoundsException may occur, where width and height 
0949:             * are the width and height of horizontal and vertical resampling
0950:             * kernels respectively.
0951:             *
0952:             * @param s__ the sample above and to the left of the central sample.
0953:             * @param s_0 the sample above the central sample.
0954:             * @param s_1 the sample above and one to the right of the central sample.
0955:             * @param s_2 the sample above and two to the right of the central sample.
0956:             * @param s0_ the sample to the left of the central sample.
0957:             * @param s00 the central sample.
0958:             * @param s01 the sample to the right of the central sample.
0959:             * @param s02 the sample two to the right of the central sample.
0960:             * @param s1_ the sample below and one to the left of the central sample.
0961:             * @param s10 the sample below the central sample.
0962:             * @param s11 the sample below and one to the right of the central sample.
0963:             * @param s12 the sample below and two to the right of the central sample.
0964:             * @param s2_ the sample two below and one to the left of the central sample.
0965:             * @param s20 the sample two below the central sample.
0966:             * @param s21 the sample two below and one to the right of the central sample.
0967:             * @param s22 the sample two below and two to the right of the central sample.
0968:             * @param xfrac the X subsample position, multiplied by <code>2<sup>subsampleBitsH</sup></code>.
0969:             * @param yfrac the Y subsample position, multiplied by <code>2<sup>subsampleBitsV</sup></code>.
0970:             * @return the interpolated value as an int.
0971:             * @throws ArrayIndexOutOfBoundsException if xfrac or yfrac are out of bounds.
0972:             */
0973:            public int interpolateF(int s__, int s_0, int s_1, int s_2,
0974:                    int s0_, int s00, int s01, int s02, int s1_, int s10,
0975:                    int s11, int s12, int s2_, int s20, int s21, int s22,
0976:                    int xfrac, int yfrac) {
0977:
0978:                // Interpolate in X
0979:                int offsetX = 4 * xfrac;
0980:
0981:                float sum_ = dataHf[offsetX] * s__;
0982:                sum_ += dataHf[offsetX + 1] * s_0;
0983:                sum_ += dataHf[offsetX + 2] * s_1;
0984:                sum_ += dataHf[offsetX + 3] * s_2;
0985:
0986:                float sum0 = dataHf[offsetX] * s0_;
0987:                sum0 += dataHf[offsetX + 1] * s00;
0988:                sum0 += dataHf[offsetX + 2] * s01;
0989:                sum0 += dataHf[offsetX + 3] * s02;
0990:
0991:                float sum1 = dataHf[offsetX] * s1_;
0992:                sum1 += dataHf[offsetX + 1] * s10;
0993:                sum1 += dataHf[offsetX + 2] * s11;
0994:                sum1 += dataHf[offsetX + 3] * s12;
0995:
0996:                float sum2 = dataHf[offsetX] * s2_;
0997:                sum2 += dataHf[offsetX + 1] * s20;
0998:                sum2 += dataHf[offsetX + 2] * s21;
0999:                sum2 += dataHf[offsetX + 3] * s22;
1000:
1001:                // Interpolate in Y
1002:                int offsetY = 4 * yfrac;
1003:                float sum = dataVf[offsetY] * sum_;
1004:                sum += dataVf[offsetY + 1] * sum0;
1005:                sum += dataVf[offsetY + 2] * sum1;
1006:                sum += dataVf[offsetY + 3] * sum2;
1007:
1008:                int isum = (int) sum;
1009:
1010:                return isum;
1011:            }
1012:
1013:            /**
1014:             * Performs horizontal interpolation on a one-dimensional array of
1015:             * floating-point samples representing a row of samples.
1016:             *
1017:             * If xfrac does not lie between the range [0.0, 1.0F), an
1018:             * ArrayIndexOutOfBoundsException may occur.
1019:             *
1020:             * @param samples an array of floats.
1021:             * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1022:             * @return the interpolated value as a float.
1023:             * @throws ArrayIndexOutOfBoundsException if xfrac is out of bounds.
1024:             */
1025:            public float interpolateH(float[] samples, float xfrac) {
1026:                float sum = 0.0F;
1027:                int ifrac = (int) (xfrac * numSubsamplesH);
1028:                int offset = width * ifrac;
1029:
1030:                for (int i = 0; i < width; i++) {
1031:                    sum += dataHf[offset + i] * samples[i];
1032:                }
1033:                return sum;
1034:            }
1035:
1036:            /**
1037:             * Performs vertical interpolation on a one-dimensional array of
1038:             * floating-point samples representing a column of samples.
1039:             *
1040:             * If yfrac does not lie between the range [0.0, 1.0F), an
1041:             * ArrayIndexOutOfBoundsException may occur.
1042:             *
1043:             * @param samples an array of floats.
1044:             * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1045:             * @return the interpolated value as a float.
1046:             * @throws ArrayIndexOutOfBoundsException if yfrac is out of bounds.
1047:             */
1048:            public float interpolateV(float[] samples, float yfrac) {
1049:                float sum = 0.0F;
1050:                int ifrac = (int) (yfrac * numSubsamplesV);
1051:                int offset = width * ifrac;
1052:
1053:                for (int i = 0; i < width; i++) {
1054:                    sum += dataVf[offset + i] * samples[i];
1055:                }
1056:                return sum;
1057:            }
1058:
1059:            /**
1060:             * Performs horizontal interpolation on a pair of floating-point samples.
1061:             * This method may be used instead of the array version for speed.
1062:             * It should only be called if width == 2.
1063:             *
1064:             * If xfrac does not lie between the range [0.0, 1.0F), an
1065:             * ArrayIndexOutOfBoundsException may occur.
1066:             *
1067:             * @param s0 the central sample.
1068:             * @param s1 the sample to the right of the central sample.
1069:             * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1070:             * @return the interpolated value as a float.
1071:             * @throws ArrayIndexOutOfBoundsException if xfrac is out of bounds.
1072:             */
1073:            public float interpolateH(float s0, float s1, float xfrac) {
1074:                float sum = 0.0F;
1075:                int ifrac = (int) (xfrac * numSubsamplesH);
1076:                // Assume width == 2
1077:                int offset = 2 * ifrac;
1078:
1079:                sum = dataHf[offset] * s0 + dataHf[offset + 1] * s1;
1080:                return sum;
1081:            }
1082:
1083:            /**
1084:             * Performs horizontal interpolation on a quadruple of floating-point
1085:             * samples. This method may be used instead of the array version for
1086:             * speed. It should only be called if width == 4 and keyX == 1.
1087:             *
1088:             * If xfrac does not lie between the range [0.0, 1.0F), an
1089:             * ArrayIndexOutOfBoundsException may occur.
1090:             *
1091:             * @param s_ the sample to the left of the central sample.
1092:             * @param s0 the central sample.
1093:             * @param s1 the sample to the right of the central sample.
1094:             * @param s2 the sample to the right of s1.
1095:             * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1096:             * @return the interpolated value as a float.
1097:             * @throws ArrayIndexOutOfBoundsException if xfrac is out of bounds.
1098:             */
1099:            public float interpolateH(float s_, float s0, float s1, float s2,
1100:                    float xfrac) {
1101:                int ifrac = (int) (xfrac * numSubsamplesH);
1102:                // Assume width == 4
1103:                int offset = 4 * ifrac;
1104:
1105:                float sum = dataHf[offset] * s_;
1106:                sum += dataHf[offset + 1] * s0;
1107:                sum += dataHf[offset + 2] * s1;
1108:                sum += dataHf[offset + 3] * s2;
1109:                return sum;
1110:            }
1111:
1112:            /**
1113:             * Performs vertical interpolation on a pair of floating-point samples.
1114:             * This method may be used instead of the array version for speed.
1115:             * It should only be called if height == 2 and keyY == 0.
1116:             *
1117:             * If yfrac does not lie between the range [0.0, 1.0F), an
1118:             * ArrayIndexOutOfBoundsException may occur.
1119:             *
1120:             * @param s0 the central sample.
1121:             * @param s1 the sample below the central sample.
1122:             * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1123:             * @return the interpolated value as a float.
1124:             * @throws ArrayIndexOutOfBoundsException if yfrac is out of bounds.
1125:             */
1126:            public float interpolateV(float s0, float s1, float yfrac) {
1127:                int ifrac = (int) (yfrac * numSubsamplesV);
1128:                // Assume width == 2
1129:                int offset = 2 * ifrac;
1130:                float sum = dataVf[offset] * s0;
1131:                sum += dataVf[offset + 1] * s1;
1132:                return sum;
1133:            }
1134:
1135:            /**
1136:             * Performs vertical interpolation on a quadruple of floating-point
1137:             * samples. This method may be used instead of the array version for
1138:             * speed. It should only be called if height == 4 and keyY == 1.
1139:             *
1140:             * If yfrac does not lie between the range [0.0, 1.0F), an
1141:             * ArrayIndexOutOfBoundsException may occur.
1142:             *
1143:             * @param s_ the sample above the central sample.
1144:             * @param s0 the central sample.
1145:             * @param s1 the sample below the central sample.
1146:             * @param s2 the sample below s1.
1147:             * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1148:             * @return the interpolated value as a float.
1149:             * @throws ArrayIndexOutOfBoundsException if yfrac is out of bounds.
1150:             */
1151:            public float interpolateV(float s_, float s0, float s1, float s2,
1152:                    float yfrac) {
1153:                int ifrac = (int) (yfrac * numSubsamplesV);
1154:                // Assume width == 4
1155:                int offset = 4 * ifrac;
1156:                float sum = dataVf[offset] * s_;
1157:                sum += dataVf[offset + 1] * s0;
1158:                sum += dataVf[offset + 2] * s1;
1159:                sum += dataVf[offset + 3] * s2;
1160:                return sum;
1161:            }
1162:
1163:            /**
1164:             * Performs interpolation on a 2x2 grid of floating-point samples.
1165:             * It should only be called if width == height == 2 and
1166:             * keyX == keyY == 0.
1167:             *
1168:             * If either xfrac or yfrac does not lie between the range [0.0, 1.0F), an
1169:             * ArrayIndexOutOfBoundsException may occur.
1170:             *
1171:             * @param s00 the central sample.
1172:             * @param s01 the sample to the right of the central sample.
1173:             * @param s10 the sample below the central sample.
1174:             * @param s11 the sample below and to the right of the central sample.
1175:             * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1176:             * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1177:             * @return the interpolated value as a float.
1178:             * @throws ArrayIndexOutOfBoundsException if xfrac or yfrac are out of bounds.
1179:             */
1180:            public float interpolate(float s00, float s01, float s10,
1181:                    float s11, float xfrac, float yfrac) {
1182:                int ifrac = (int) (xfrac * numSubsamplesH);
1183:                // Interpolate in X
1184:                int offsetX = 2 * ifrac;
1185:                float sum0 = dataHf[offsetX] * s00 + dataHf[offsetX + 1] * s01;
1186:                float sum1 = dataHf[offsetX] * s10 + dataHf[offsetX + 1] * s11;
1187:
1188:                // Interpolate in Y
1189:                ifrac = (int) (yfrac * numSubsamplesV);
1190:                int offsetY = 2 * ifrac;
1191:                float sum = dataVf[offsetY] * sum0 + dataVf[offsetY + 1] * sum1;
1192:
1193:                return sum;
1194:            }
1195:
1196:            /**
1197:             * Performs interpolation on a 4x4 grid of floating-point samples.
1198:             * It should only be called if width == height == 4 and
1199:             * keyX == keyY == 1.
1200:             *
1201:             * If either xfrac or yfrac does not lie between the range [0.0, 1.0F), an
1202:             * ArrayIndexOutOfBoundsException may occur.
1203:             *
1204:             * @param s__ the sample above and to the left of the central sample.
1205:             * @param s_0 the sample above the central sample.
1206:             * @param s_1 the sample above and one to the right of the central sample.
1207:             * @param s_2 the sample above and two to the right of the central sample.
1208:             * @param s0_ the sample to the left of the central sample.
1209:             * @param s00 the central sample.
1210:             * @param s01 the sample to the right of the central sample.
1211:             * @param s02 the sample two to the right of the central sample.
1212:             * @param s1_ the sample below and one to the left of the central sample.
1213:             * @param s10 the sample below the central sample.
1214:             * @param s11 the sample below and one to the right of the central sample.
1215:             * @param s12 the sample below and two to the right of the central sample.
1216:             * @param s2_ the sample two below and one to the left of the central sample.
1217:             * @param s20 the sample two below the central sample.
1218:             * @param s21 the sample two below and one to the right of the central sample.
1219:             * @param s22 the sample two below and two to the right of the central sample.
1220:             * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1221:             * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1222:             * @return the interpolated value as a float.
1223:             * @throws ArrayIndexOutOfBoundsException if xfrac or yfrac are out of bounds.
1224:             */
1225:            public float interpolate(float s__, float s_0, float s_1,
1226:                    float s_2, float s0_, float s00, float s01, float s02,
1227:                    float s1_, float s10, float s11, float s12, float s2_,
1228:                    float s20, float s21, float s22, float xfrac, float yfrac) {
1229:
1230:                int ifrac = (int) (xfrac * numSubsamplesH);
1231:                // Interpolate in X
1232:                int offsetX = 4 * ifrac;
1233:                int offsetX1 = offsetX + 1;
1234:                int offsetX2 = offsetX + 2;
1235:                int offsetX3 = offsetX + 3;
1236:
1237:                float sum_ = dataHf[offsetX] * s__;
1238:                sum_ += dataHf[offsetX1] * s_0;
1239:                sum_ += dataHf[offsetX2] * s_1;
1240:                sum_ += dataHf[offsetX3] * s_2;
1241:
1242:                float sum0 = dataHf[offsetX] * s0_;
1243:                sum0 += dataHf[offsetX1] * s00;
1244:                sum0 += dataHf[offsetX2] * s01;
1245:                sum0 += dataHf[offsetX3] * s02;
1246:
1247:                float sum1 = dataHf[offsetX] * s1_;
1248:                sum1 += dataHf[offsetX1] * s10;
1249:                sum1 += dataHf[offsetX2] * s11;
1250:                sum1 += dataHf[offsetX3] * s12;
1251:
1252:                float sum2 = dataHf[offsetX] * s2_;
1253:                sum2 += dataHf[offsetX1] * s20;
1254:                sum2 += dataHf[offsetX2] * s21;
1255:                sum2 += dataHf[offsetX3] * s22;
1256:
1257:                // Interpolate in Y
1258:                ifrac = (int) (yfrac * numSubsamplesV);
1259:                int offsetY = 4 * ifrac;
1260:                float sum = dataVf[offsetY] * sum_;
1261:                sum += dataVf[offsetY + 1] * sum0;
1262:                sum += dataVf[offsetY + 2] * sum1;
1263:                sum += dataVf[offsetY + 3] * sum2;
1264:
1265:                return sum;
1266:            }
1267:
1268:            /**
1269:             * Performs horizontal interpolation on a one-dimensional array of
1270:             * double samples representing a row of samples.
1271:             *
1272:             * If xfrac does not lie between the range [0.0, 1.0F), an
1273:             * ArrayIndexOutOfBoundsException may occur.
1274:             *
1275:             * @param samples an array of doubles.
1276:             * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1277:             * @return the interpolated value as a double.
1278:             * @throws ArrayIndexOutOfBoundsException if xfrac is out of bounds.
1279:             */
1280:            public double interpolateH(double[] samples, float xfrac) {
1281:                double sum = 0.0;
1282:                int ifrac = (int) (xfrac * numSubsamplesH);
1283:                int offset = width * ifrac;
1284:
1285:                for (int i = 0; i < width; i++) {
1286:                    sum += dataHd[offset + i] * samples[i];
1287:                }
1288:                return sum;
1289:            }
1290:
1291:            /**
1292:             * Performs vertical interpolation on a one-dimensional array of
1293:             * double samples representing a column of samples.
1294:             *
1295:             * If yfrac does not lie between the range [0.0, 1.0F), an
1296:             * ArrayIndexOutOfBoundsException may occur.
1297:             *
1298:             * @param samples an array of doubles.
1299:             * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1300:             * @return the interpolated value as a double.
1301:             * @throws ArrayIndexOutOfBoundsException if yfrac is out of bounds.
1302:             */
1303:            public double interpolateV(double[] samples, float yfrac) {
1304:                double sum = 0.0;
1305:                int ifrac = (int) (yfrac * numSubsamplesV);
1306:                int offset = width * ifrac;
1307:
1308:                for (int i = 0; i < width; i++) {
1309:                    sum += dataVd[offset + i] * samples[i];
1310:                }
1311:                return sum;
1312:            }
1313:
1314:            /**
1315:             * Performs horizontal interpolation on a pair of double samples.
1316:             * This method may be used instead of the array version for speed.
1317:             * It should only be called if width == 2.
1318:             *
1319:             * If xfrac does not lie between the range [0.0, 1.0F), an
1320:             * ArrayIndexOutOfBoundsException may occur.
1321:             *
1322:             * @param s0 the central sample.
1323:             * @param s1 the sample to the right of the central sample.
1324:             * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1325:             * @return the interpolated value as a double.
1326:             * @throws ArrayIndexOutOfBoundsException if xfrac is out of bounds.
1327:             */
1328:            public double interpolateH(double s0, double s1, float xfrac) {
1329:                double sum = 0.0F;
1330:                int ifrac = (int) (xfrac * numSubsamplesH);
1331:                // Assume width == 2
1332:                int offset = 2 * ifrac;
1333:
1334:                sum = dataHd[offset] * s0 + dataHd[offset + 1] * s1;
1335:                return sum;
1336:            }
1337:
1338:            /**
1339:             * Performs horizontal interpolation on a quadruple of double
1340:             * samples. This method may be used instead of the array version for
1341:             * speed. It should only be called if width == 4 and keyX == 1.
1342:             *
1343:             * If xfrac does not lie between the range [0.0, 1.0F), an
1344:             * ArrayIndexOutOfBoundsException may occur.
1345:             *
1346:             * @param s_ the sample to the left of the central sample.
1347:             * @param s0 the central sample.
1348:             * @param s1 the sample to the right of the central sample.
1349:             * @param s2 the sample to the right of s1.
1350:             * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1351:             * @return the interpolated value as a double.
1352:             * @throws ArrayIndexOutOfBoundsException if xfrac is out of bounds.
1353:             */
1354:            public double interpolateH(double s_, double s0, double s1,
1355:                    double s2, float xfrac) {
1356:                int ifrac = (int) (xfrac * numSubsamplesH);
1357:                // Assume width == 4
1358:                int offset = 4 * ifrac;
1359:
1360:                double sum = dataHd[offset] * s_;
1361:                sum += dataHd[offset + 1] * s0;
1362:                sum += dataHd[offset + 2] * s1;
1363:                sum += dataHd[offset + 3] * s2;
1364:                return sum;
1365:            }
1366:
1367:            /**
1368:             * Performs vertical interpolation on a pair of double samples.
1369:             * This method may be used instead of the array version for speed.
1370:             * It should only be called if height == 2 and keyY == 0.
1371:             *
1372:             * If yfrac does not lie between the range [0.0, 1.0F), an
1373:             * ArrayIndexOutOfBoundsException may occur.
1374:             *
1375:             * @param s0 the central sample.
1376:             * @param s1 the sample below the central sample.
1377:             * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1378:             * @return the interpolated value as a double.
1379:             * @throws ArrayIndexOutOfBoundsException if yfrac is out of bounds.
1380:             */
1381:            public double interpolateV(double s0, double s1, float yfrac) {
1382:                int ifrac = (int) (yfrac * numSubsamplesV);
1383:                // Assume width == 2
1384:                int offset = 2 * ifrac;
1385:                double sum = dataVd[offset] * s0;
1386:                sum += dataVd[offset + 1] * s1;
1387:                return sum;
1388:            }
1389:
1390:            /**
1391:             * Performs vertical interpolation on a quadruple of double
1392:             * samples. This method may be used instead of the array version for
1393:             * speed. It should only be called if height == 4 and keyY == 1.
1394:             *
1395:             * If yfrac does not lie between the range [0.0, 1.0F), an
1396:             * ArrayIndexOutOfBoundsException may occur.
1397:             *
1398:             * @param s_ the sample above the central sample.
1399:             * @param s0 the central sample.
1400:             * @param s1 the sample below the central sample.
1401:             * @param s2 the sample below s1.
1402:             * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1403:             * @return the interpolated value as a double.
1404:             * @throws ArrayIndexOutOfBoundsException if yfrac is out of bounds.
1405:             */
1406:            public double interpolateV(double s_, double s0, double s1,
1407:                    double s2, float yfrac) {
1408:                int ifrac = (int) (yfrac * numSubsamplesV);
1409:                // Assume width == 4
1410:                int offset = 4 * ifrac;
1411:                double sum = dataVd[offset] * s_;
1412:                sum += dataVd[offset + 1] * s0;
1413:                sum += dataVd[offset + 2] * s1;
1414:                sum += dataVd[offset + 3] * s2;
1415:                return sum;
1416:            }
1417:
1418:            /**
1419:             * Performs interpolation on a 2x2 grid of double samples.
1420:             * It should only be called if width == height == 2 and
1421:             * keyX == keyY == 0.
1422:             *
1423:             * If either xfrac or yfrac does not lie between the range [0.0, 1.0F), an
1424:             * ArrayIndexOutOfBoundsException may occur.
1425:             *
1426:             * @param s00 the central sample.
1427:             * @param s01 the sample to the right of the central sample.
1428:             * @param s10 the sample below the central sample.
1429:             * @param s11 the sample below and to the right of the central sample.
1430:             * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1431:             * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1432:             * @return the interpolated value as a double.
1433:             * @throws ArrayIndexOutOfBoundsException if xfrac or yfrac are out of bounds.
1434:             */
1435:            public double interpolate(double s00, double s01, double s10,
1436:                    double s11, float xfrac, float yfrac) {
1437:                int ifrac = (int) (xfrac * numSubsamplesH);
1438:                // Interpolate in X
1439:                int offsetX = 2 * ifrac;
1440:                double sum0 = dataHd[offsetX] * s00 + dataHd[offsetX + 1] * s01;
1441:                double sum1 = dataHd[offsetX] * s10 + dataHd[offsetX + 1] * s11;
1442:
1443:                // Interpolate in Y
1444:                ifrac = (int) (yfrac * numSubsamplesV);
1445:                int offsetY = 2 * ifrac;
1446:                double sum = dataVd[offsetY] * sum0 + dataVd[offsetY + 1]
1447:                        * sum1;
1448:
1449:                return sum;
1450:            }
1451:
1452:            /**
1453:             * Performs interpolation on a 4x4 grid of double samples.
1454:             * It should only be called if width == height == 4 and
1455:             * keyX == keyY == 1.
1456:             *
1457:             * If either xfrac or yfrac does not lie between the range [0.0, 1.0F), an
1458:             * ArrayIndexOutOfBoundsException may occur.
1459:             *
1460:             * @param s__ the sample above and to the left of the central sample.
1461:             * @param s_0 the sample above the central sample.
1462:             * @param s_1 the sample above and one to the right of the central sample.
1463:             * @param s_2 the sample above and two to the right of the central sample.
1464:             * @param s0_ the sample to the left of the central sample.
1465:             * @param s00 the central sample.
1466:             * @param s01 the sample to the right of the central sample.
1467:             * @param s02 the sample two to the right of the central sample.
1468:             * @param s1_ the sample below and one to the left of the central sample.
1469:             * @param s10 the sample below the central sample.
1470:             * @param s11 the sample below and one to the right of the central sample.
1471:             * @param s12 the sample below and two to the right of the central sample.
1472:             * @param s2_ the sample two below and one to the left of the central sample.
1473:             * @param s20 the sample two below the central sample.
1474:             * @param s21 the sample two below and one to the right of the central sample.
1475:             * @param s22 the sample two below and two to the right of the central sample.
1476:             * @param xfrac the X subsample position, in the range [0.0F, 1.0F).
1477:             * @param yfrac the Y subsample position, in the range [0.0F, 1.0F).
1478:             * @return the interpolated value as a double.
1479:             * @throws ArrayIndexOutOfBoundsException if xfrac or yfrac are out of bounds.
1480:             */
1481:            public double interpolate(double s__, double s_0, double s_1,
1482:                    double s_2, double s0_, double s00, double s01, double s02,
1483:                    double s1_, double s10, double s11, double s12, double s2_,
1484:                    double s20, double s21, double s22, float xfrac, float yfrac) {
1485:
1486:                int ifrac = (int) (xfrac * numSubsamplesH);
1487:                // Interpolate in X
1488:                int offsetX = 4 * ifrac;
1489:                int offsetX1 = offsetX + 1;
1490:                int offsetX2 = offsetX + 2;
1491:                int offsetX3 = offsetX + 3;
1492:
1493:                double sum_ = dataHd[offsetX] * s__;
1494:                sum_ += dataHd[offsetX1] * s_0;
1495:                sum_ += dataHd[offsetX2] * s_1;
1496:                sum_ += dataHd[offsetX3] * s_2;
1497:
1498:                double sum0 = dataHd[offsetX] * s0_;
1499:                sum0 += dataHd[offsetX1] * s00;
1500:                sum0 += dataHd[offsetX2] * s01;
1501:                sum0 += dataHd[offsetX3] * s02;
1502:
1503:                double sum1 = dataHd[offsetX] * s1_;
1504:                sum1 += dataHd[offsetX1] * s10;
1505:                sum1 += dataHd[offsetX2] * s11;
1506:                sum1 += dataHd[offsetX3] * s12;
1507:
1508:                double sum2 = dataHd[offsetX] * s2_;
1509:                sum2 += dataHd[offsetX1] * s20;
1510:                sum2 += dataHd[offsetX2] * s21;
1511:                sum2 += dataHd[offsetX3] * s22;
1512:
1513:                // Interpolate in Y
1514:                ifrac = (int) (yfrac * numSubsamplesV);
1515:                int offsetY = 4 * ifrac;
1516:                double sum = dataVd[offsetY] * sum_;
1517:                sum += dataVd[offsetY + 1] * sum0;
1518:                sum += dataVd[offsetY + 2] * sum1;
1519:                sum += dataVd[offsetY + 3] * sum2;
1520:
1521:                return sum;
1522:            }
1523:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.