Source Code Cross Referenced for WarpAffine.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) 


001:        /*
002:         * $RCSfile: WarpAffine.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:23 $
010:         * $State: Exp $
011:         */
012:        package javax.media.jai;
013:
014:        import java.awt.Rectangle;
015:        import java.awt.geom.AffineTransform;
016:        import java.awt.geom.Point2D;
017:
018:        /**
019:         * A description of an Affine warp.
020:         *
021:         * <p> The transform is specified as a mapping from destination
022:         * space to source space, a backward mapping, as opposed to the
023:         * forward mapping used in AffineOpImage.
024:         *
025:         * <p> The source position (x', y') of a point (x, y) is given by the
026:         * first order (affine) bivariate polynomials:
027:         *
028:         * <pre>
029:         * x' = p(x, y) = c1 + c2*x + c3*y
030:         * y' = q(x, y) = c4 + c5*x + c6*y
031:         * </pre>
032:         *
033:         * <p> <code>WarpAffine</code> is marked final so that it may be more
034:         * easily inlined.
035:         *
036:         */
037:        public final class WarpAffine extends WarpPolynomial {
038:
039:            private float c1, c2, c3; // coefficients for X
040:            private float c4, c5, c6; // coefficients for Y
041:
042:            private float invc1, invc2, invc3; // inverse xform coefficients for X
043:            private float invc4, invc5, invc6; // inverse xform coefficients for Y
044:
045:            private AffineTransform transform;
046:            private AffineTransform invTransform;
047:
048:            /**
049:             * @param transform
050:             * @return An array of <code>float</code>s.
051:             */
052:            private static final float[] xCoeffsHelper(AffineTransform transform) {
053:                float[] coeffs = new float[3];
054:                coeffs[0] = (float) transform.getTranslateX();
055:                coeffs[1] = (float) transform.getScaleX();
056:                coeffs[2] = (float) transform.getShearX();
057:                return coeffs;
058:            }
059:
060:            private static final float[] yCoeffsHelper(AffineTransform transform) {
061:                float[] coeffs = new float[3];
062:                coeffs[0] = (float) transform.getTranslateY();
063:                coeffs[1] = (float) transform.getShearY();
064:                coeffs[2] = (float) transform.getScaleY();
065:                return coeffs;
066:            }
067:
068:            /**
069:             * Constructs a <code>WarpAffine</code> with a given transform mapping
070:             * destination pixels into source space.  The transform is
071:             * given by:
072:             *
073:             * <pre>
074:             * x' = xCoeffs[0] + xCoeffs[1]*x + xCoeffs[2]*y;
075:             * y' = yCoeffs[0] + yCoeffs[1]*x + yCoeffs[2]*y;
076:             * </pre>
077:             *
078:             * where <code>x', y'</code> are the source image coordinates
079:             * and <code>x, y</code> are the destination image coordinates.
080:             *
081:             * @param xCoeffs  The 3 destination to source transform coefficients for
082:             *                 the X coordinate.
083:             * @param yCoeffs  The 3 destination to source transform coefficients for
084:             *                 the Y coordinate.
085:             * @param preScaleX  The scale factor to apply to input (dest) X positions.
086:             * @param preScaleY  The scale factor to apply to input (dest) Y positions.
087:             * @param postScaleX  The scale factor to apply to the evaluated x transform
088:             * @param postScaleY  The scale factor to apply to the evaluated y transform
089:             *
090:             * @throws IllegalArgumentException if array <code>xCoeffs</code> or
091:             *         <code>yCoeffs</code> does not have length of 3.
092:             */
093:            public WarpAffine(float[] xCoeffs, float[] yCoeffs,
094:                    float preScaleX, float preScaleY, float postScaleX,
095:                    float postScaleY) {
096:                super (xCoeffs, yCoeffs, preScaleX, preScaleY, postScaleX,
097:                        postScaleY);
098:
099:                if (xCoeffs.length != 3 || yCoeffs.length != 3) {
100:                    throw new IllegalArgumentException(JaiI18N
101:                            .getString("WarpAffine0"));
102:                }
103:
104:                c1 = xCoeffs[0];
105:                c2 = xCoeffs[1];
106:                c3 = xCoeffs[2];
107:
108:                c4 = yCoeffs[0];
109:                c5 = yCoeffs[1];
110:                c6 = yCoeffs[2];
111:
112:                transform = getTransform();
113:
114:                // Transform inversion may throw NoninvertibleTransformException
115:                try {
116:                    invTransform = transform.createInverse();
117:
118:                    invc1 = (float) invTransform.getTranslateX();
119:                    invc2 = (float) invTransform.getScaleX();
120:                    invc3 = (float) invTransform.getShearX();
121:
122:                    invc4 = (float) invTransform.getTranslateY();
123:                    invc5 = (float) invTransform.getShearY();
124:                    invc6 = (float) invTransform.getScaleY();
125:                } catch (java.awt.geom.NoninvertibleTransformException e) {
126:                    // Transform can't be inverted, so set inverse to null
127:                    invTransform = null;
128:                }
129:            }
130:
131:            /**
132:             * Constructs a <code>WarpAffine</code> with pre- and post-scale
133:             * factors of 1.
134:             *
135:             * @param xCoeffs  The 3 destination to source transform coefficients for
136:             *                 the X coordinate.
137:             * @param yCoeffs  The 3 destination to source transform coefficients for
138:             *                 the Y coordinate.
139:             */
140:            public WarpAffine(float[] xCoeffs, float[] yCoeffs) {
141:                this (xCoeffs, yCoeffs, 1.0F, 1.0F, 1.0F, 1.0F);
142:            }
143:
144:            /**
145:             * Constructs a <code>WarpAffine</code> with a given transform mapping
146:             * destination pixels into source space.  Note that this is
147:             * a backward mapping as opposed to the forward mapping used in
148:             * AffineOpImage.
149:             *
150:             * @param transform The destination to source transform.
151:             * @param preScaleX The scale factor to apply to source X positions.
152:             * @param preScaleY The scale factor to apply to source Y positions.
153:             * @param postScaleX The scale factor to apply to destination X positions.
154:             * @param postScaleY The scale factor to apply to destination Y positions.
155:             */
156:            public WarpAffine(AffineTransform transform, float preScaleX,
157:                    float preScaleY, float postScaleX, float postScaleY) {
158:                this (xCoeffsHelper(transform), yCoeffsHelper(transform),
159:                        preScaleX, preScaleY, postScaleX, postScaleY);
160:            }
161:
162:            /**
163:             * Constructs a <code>WarpAffine</code> with pre- and post-scale
164:             * factors of 1.
165:             *
166:             * @param transform An <code>AffineTransform</code> mapping dest to source
167:             *                  coordinates.
168:             */
169:            public WarpAffine(AffineTransform transform) {
170:                this (transform, 1.0F, 1.0F, 1.0F, 1.0F);
171:            }
172:
173:            /**
174:             * Returns a clone of the <code>AffineTransform</code> associated
175:             * with this <code>WarpAffine</code> object.
176:             *
177:             * @return An <code>AffineTransform</code>.
178:             */
179:            public AffineTransform getTransform() {
180:                return new AffineTransform(c2, c5, c3, c6, c1, c4);
181:            }
182:
183:            /**
184:             * Computes the source subpixel positions for a given rectangular
185:             * destination region, subsampled with an integral period.  The
186:             * destination region is specified using normal integral (full
187:             * pixel) coordinates.  The source positions returned by the
188:             * method are specified in floating point.
189:             *
190:             * @param x The minimum X coordinate of the destination region.
191:             * @param y The minimum Y coordinate of the destination region.
192:             * @param width The width of the destination region.
193:             * @param height The height of the destination region.
194:             * @param periodX The horizontal sampling period.
195:             * @param periodY The vertical sampling period.
196:             *
197:             * @param destRect A <code>float</code> array containing at least
198:             *        <code>2*((width+periodX-1)/periodX)*
199:             *                ((height+periodY-1)/periodY)</code>
200:             *        elements, or <code>null</code>.  If <code>null</code>, a
201:             *        new array will be constructed.
202:             *
203:             * @return A reference to the <code>destRect</code> parameter if
204:             *         it is non-<code>null</code>, or a new
205:             *         <code>float</code> array otherwise.
206:             */
207:            public float[] warpSparseRect(int x, int y, int width, int height,
208:                    int periodX, int periodY, float[] destRect) {
209:
210:                //XXX: This method should do its calculations in doubles
211:                if (destRect == null) {
212:                    destRect = new float[((width + periodX - 1) / periodX)
213:                            * ((height + periodY - 1) / periodY) * 2];
214:                }
215:
216:                //
217:                // Original formula
218:                //     x' = c1 + c2*x + c3*y
219:                //     y' = c4 + c5*x + c6*y
220:                //
221:                // Take in preScale, postScale, and 0.5 shift
222:                //     x' = (c1 + c2*(x+0.5)*preScaleX +
223:                //           c3*(y+0.5)*preScaleY) * postScaleX - 0.5
224:                //     y' = (c4 + c5*(x+0.5)*preScaleX +
225:                //           c6*(y+0.5)*preScaleY) * postScaleY - 0.5
226:                //
227:                // The next point, increment by periodX
228:                //     x' = (c1 + c2*(x+periodX+0.5)*preScaleX +
229:                //           c3*(y+0.5)*preScaleY) * postScaleX - 0.5
230:                //     y' = (c4 + c5*(x+periodX+0.5)*preScaleX +
231:                //           c6*(y+0.5)*preScaleY) * postScaleY - 0.5
232:                //
233:                // The difference between the 2 points
234:                //     dx = c2 * periodX * preScaleX * postScaleX
235:                //     dy = c5 * periodX * preScaleX * postScaleY
236:                //
237:
238:                float px1 = periodX * preScaleX; // power for period X
239:
240:                float dx = c2 * px1 * postScaleX; // delta x for x poly
241:                float dy = c5 * px1 * postScaleY; // delta x for y poly
242:
243:                float x1 = (x + 0.5F) * preScaleX; // power for x
244:
245:                width += x;
246:                height += y;
247:                int index = 0; // destRect index
248:
249:                for (int j = y; j < height; j += periodY) {
250:                    float y1 = (j + 0.5F) * preScaleY; // power for current y
251:
252:                    // The warped position for the first point of the current line.
253:                    float wx = (c1 + c2 * x1 + c3 * y1) * postScaleX - 0.5F;
254:                    float wy = (c4 + c5 * x1 + c6 * y1) * postScaleY - 0.5F;
255:
256:                    for (int i = x; i < width; i += periodX) {
257:                        destRect[index++] = wx;
258:                        destRect[index++] = wy;
259:
260:                        wx += dx;
261:                        wy += dy;
262:                    }
263:                }
264:
265:                return destRect;
266:            }
267:
268:            /**
269:             * Computes a Rectangle that is guaranteed to enclose the region
270:             * of the source that is required in order to produce a given
271:             * rectangular output region.
272:             *
273:             * @param destRect The Rectangle in destination coordinates.
274:             *
275:             * @return A <code>Rectangle</code> in the source coordinate
276:             *         system that is guaranteed to contain all pixels
277:             *         referenced by the output of <code>warpRect()</code> on
278:             *         the destination region, or <code>null</code>.
279:             *
280:             * @throws IllegalArgumentException if <code>destRect</code> is
281:             *         <code>null</code>.
282:             */
283:            public Rectangle mapDestRect(Rectangle destRect) {
284:                if (destRect == null) {
285:                    throw new IllegalArgumentException(JaiI18N
286:                            .getString("Generic0"));
287:                }
288:
289:                int dx0 = destRect.x;
290:                int dx1 = destRect.x + destRect.width;
291:                int dy0 = destRect.y;
292:                int dy1 = destRect.y + destRect.height;
293:
294:                float[] pt;
295:                float sx0, sx1, sy0, sy1;
296:
297:                pt = mapDestPoint(dx0, dy0);
298:                sx0 = pt[0];
299:                sx1 = pt[0];
300:                sy0 = pt[1];
301:                sy1 = pt[1];
302:
303:                pt = mapDestPoint(dx1, dy0);
304:                sx0 = Math.min(sx0, pt[0]);
305:                sx1 = Math.max(sx1, pt[0]);
306:                sy0 = Math.min(sy0, pt[1]);
307:                sy1 = Math.max(sy1, pt[1]);
308:
309:                pt = mapDestPoint(dx0, dy1);
310:                sx0 = Math.min(sx0, pt[0]);
311:                sx1 = Math.max(sx1, pt[0]);
312:                sy0 = Math.min(sy0, pt[1]);
313:                sy1 = Math.max(sy1, pt[1]);
314:
315:                pt = mapDestPoint(dx1, dy1);
316:                sx0 = Math.min(sx0, pt[0]);
317:                sx1 = Math.max(sx1, pt[0]);
318:                sy0 = Math.min(sy0, pt[1]);
319:                sy1 = Math.max(sy1, pt[1]);
320:
321:                int x = (int) Math.floor(sx0);
322:                int y = (int) Math.floor(sy0);
323:                int w = (int) Math.ceil(sx1 - x);
324:                int h = (int) Math.ceil(sy1 - y);
325:
326:                return new Rectangle(x, y, w, h);
327:            }
328:
329:            /**
330:             * Computes a Rectangle that is guaranteed to enclose the region
331:             * of the destination to which the source rectangle maps.
332:             *
333:             * @param srcRect The Rectangle in source coordinates.
334:             *
335:             * @return A <code>Rectangle</code> in the destination coordinate
336:             *         system that is guaranteed to contain all pixels
337:             *         within the forward mapping of the source rectangle.
338:             *
339:             * @throws IllegalArgumentException if <code>srctRect</code> is
340:             *         <code>null</code>.
341:             *
342:             * @since JAI 1.1
343:             */
344:            public Rectangle mapSourceRect(Rectangle srcRect) {
345:                if (srcRect == null) {
346:                    throw new IllegalArgumentException(JaiI18N
347:                            .getString("Generic0"));
348:                }
349:
350:                //
351:                // According to spec, we return null if no forward
352:                // mapping can be derived.
353:                //
354:                if (invTransform == null) {
355:                    return null;
356:                }
357:
358:                int sx0 = srcRect.x;
359:                int sx1 = srcRect.x + srcRect.width;
360:                int sy0 = srcRect.y;
361:                int sy1 = srcRect.y + srcRect.height;
362:
363:                float[] pt;
364:                float dx0, dx1, dy0, dy1;
365:
366:                pt = mapSrcPoint(sx0, sy0);
367:                dx0 = pt[0];
368:                dx1 = pt[0];
369:                dy0 = pt[1];
370:                dy1 = pt[1];
371:
372:                pt = mapSrcPoint(sx1, sy0);
373:                dx0 = Math.min(dx0, pt[0]);
374:                dx1 = Math.max(dx1, pt[0]);
375:                dy0 = Math.min(dy0, pt[1]);
376:                dy1 = Math.max(dy1, pt[1]);
377:
378:                pt = mapSrcPoint(sx0, sy1);
379:                dx0 = Math.min(dx0, pt[0]);
380:                dx1 = Math.max(dx1, pt[0]);
381:                dy0 = Math.min(dy0, pt[1]);
382:                dy1 = Math.max(dy1, pt[1]);
383:
384:                pt = mapSrcPoint(sx1, sy1);
385:                dx0 = Math.min(dx0, pt[0]);
386:                dx1 = Math.max(dx1, pt[0]);
387:                dy0 = Math.min(dy0, pt[1]);
388:                dy1 = Math.max(dy1, pt[1]);
389:
390:                int x = (int) Math.floor(dx0);
391:                int y = (int) Math.floor(dy0);
392:                int w = (int) Math.ceil(dx1 - x);
393:                int h = (int) Math.ceil(dy1 - y);
394:
395:                return new Rectangle(x, y, w, h);
396:            }
397:
398:            // Maps a dest point to the source.
399:            private float[] mapDestPoint(int x, int y) {
400:                //XXX: This method should do its calculations in doubles
401:
402:                //
403:                //     x' = (c1 + c2*(x+0.5)*preScaleX +
404:                //           c3*(y+0.5)*preScaleY) * postScaleX - 0.5
405:                //     y' = (c4 + c5*(x+0.5)*preScaleX +
406:                //           c6*(y+0.5)*preScaleY) * postScaleY - 0.5
407:                //
408:                float fx = (x + 0.5F) * preScaleX; // pixel energy is at center
409:                float fy = (y + 0.5F) * preScaleY;
410:
411:                float[] p = new float[2];
412:                p[0] = (c1 + c2 * fx + c3 * fy) * postScaleX - 0.5F;
413:                p[1] = (c4 + c5 * fx + c6 * fy) * postScaleY - 0.5F;
414:
415:                return p;
416:            }
417:
418:            // Maps a source point to the dest.
419:            private float[] mapSrcPoint(int x, int y) {
420:                //XXX: This method should do its calculations in doubles
421:
422:                //
423:                //     x' = (invc1 + invc2*(x+0.5)*preScaleX +
424:                //           invc3*(y+0.5)*preScaleY) * postScaleX - 0.5
425:                //     y' = (invc4 + invc5*(x+0.5)*preScaleX +
426:                //           invc6*(y+0.5)*preScaleY) * postScaleY - 0.5
427:                //
428:                float fx = (x + 0.5F) * preScaleX; // pixel energy is at center
429:                float fy = (y + 0.5F) * preScaleY;
430:
431:                float[] p = new float[2];
432:                p[0] = (invc1 + invc2 * fx + invc3 * fy) * postScaleX - 0.5F;
433:                p[1] = (invc4 + invc5 * fx + invc6 * fy) * postScaleY - 0.5F;
434:
435:                return p;
436:            }
437:
438:            /**
439:             * Computes the source point corresponding to the supplied point.
440:             *
441:             * <p>This method returns the value of <code>pt</code> in the following
442:             * code snippet:
443:             *
444:             * <pre>
445:             * double dx = (destPt.getX() + 0.5)*preScaleX;
446:             * double dy = (destPt.getY() + 0.5)*preScaleY;
447:             * Point2D pt = (Point2D)destPt.clone();
448:             * pt.setLocation((c1 + c2*dx + c3*dy)*postScaleX - 0.5F,
449:             *                (c4 + c5*dx + c6*dy)*postScaleY - 0.5F);
450:             * </pre>
451:             * </p>
452:             *
453:             * @param destPt the position in destination image coordinates
454:             * to map to source image coordinates.
455:             *
456:             * @return a <code>Point2D</code> of the same class as
457:             * <code>destPt</code>.
458:             *
459:             * @throws IllegalArgumentException if <code>destPt</code> is
460:             * <code>null</code>.
461:             *
462:             * @since JAI 1.1.2
463:             */
464:            public Point2D mapDestPoint(Point2D destPt) {
465:                if (destPt == null) {
466:                    throw new IllegalArgumentException(JaiI18N
467:                            .getString("Generic0"));
468:                }
469:
470:                double dx = (destPt.getX() + 0.5) * preScaleX;
471:                double dy = (destPt.getY() + 0.5) * preScaleY;
472:
473:                Point2D pt = (Point2D) destPt.clone();
474:
475:                pt.setLocation((c1 + c2 * dx + c3 * dy) * postScaleX - 0.5F,
476:                        (c4 + c5 * dx + c6 * dy) * postScaleY - 0.5F);
477:
478:                return pt;
479:            }
480:
481:            /**
482:             * Computes the destination point corresponding to the supplied point.
483:             *
484:             * <p>If the transform is invertible, this method returns the value of
485:             * <code>pt</code> in the following code snippet:
486:             *
487:             * <pre>
488:             * double sx = (sourcePt.getX() + 0.5F)/postScaleX;
489:             * double sy = (sourcePt.getY() + 0.5F)/postScaleY;
490:             * Point2D pt = (Point2D)sourcePt.clone();
491:             * pt.setLocation((invc1 + invc2*sx + invc3*sy)/preScaleX - 0.5F,
492:             *                (invc4 + invc5*sx + invc6*sy)/preScaleY - 0.5F);
493:             * </pre>
494:             *
495:             * where <code>invc*</code> are the inverse transform coefficients. If
496:             * the transform is not invertible, <code>null</code> is returned.</p>
497:             *
498:             * @param sourcePt the position in source image coordinates
499:             * to map to destination image coordinates.
500:             *
501:             * @return a <code>Point2D</code> of the same class as
502:             * <code>sourcePt</code> or <code>null> if the transform is
503:             * not invertible.
504:             *
505:             * @throws IllegalArgumentException if <code>destPt</code> is
506:             * <code>null</code>.
507:             *
508:             * @since JAI 1.1.2
509:             */
510:            public Point2D mapSourcePoint(Point2D sourcePt) {
511:                if (sourcePt == null) {
512:                    throw new IllegalArgumentException(JaiI18N
513:                            .getString("Generic0"));
514:                }
515:
516:                if (invTransform == null) {
517:                    return null;
518:                }
519:
520:                double sx = (sourcePt.getX() + 0.5F) / postScaleX;
521:                double sy = (sourcePt.getY() + 0.5F) / postScaleY;
522:
523:                Point2D pt = (Point2D) sourcePt.clone();
524:
525:                pt.setLocation((invc1 + invc2 * sx + invc3 * sy) / preScaleX
526:                        - 0.5F, (invc4 + invc5 * sx + invc6 * sy) / preScaleY
527:                        - 0.5F);
528:
529:                return pt;
530:            }
531:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.