Source Code Cross Referenced for MlibAffineOpImage.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » com » sun » media » jai » mlib » 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 » com.sun.media.jai.mlib 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: MlibAffineOpImage.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:55:49 $
010:         * $State: Exp $
011:         */
012:        package com.sun.media.jai.mlib;
013:
014:        import java.awt.Point;
015:        import java.awt.Rectangle;
016:        import java.awt.image.DataBuffer;
017:        import java.awt.image.SampleModel;
018:        import java.awt.image.Raster;
019:        import java.awt.image.RenderedImage;
020:        import java.awt.image.WritableRaster;
021:        import java.awt.image.renderable.ParameterBlock;
022:        import java.awt.image.renderable.RenderedImageFactory;
023:        import java.awt.geom.AffineTransform;
024:        import java.awt.geom.Point2D;
025:        import java.awt.geom.Rectangle2D;
026:        import javax.media.jai.BorderExtender;
027:        import javax.media.jai.GeometricOpImage;
028:        import javax.media.jai.ImageLayout;
029:        import javax.media.jai.Interpolation;
030:        import javax.media.jai.InterpolationNearest;
031:        import javax.media.jai.InterpolationBilinear;
032:        import javax.media.jai.InterpolationBicubic;
033:        import javax.media.jai.InterpolationBicubic2;
034:        import javax.media.jai.KernelJAI;
035:        import javax.media.jai.OpImage;
036:        import javax.media.jai.PlanarImage;
037:        import javax.media.jai.util.ImagingException;
038:        import javax.media.jai.util.ImagingListener;
039:        import java.util.Map;
040:        import com.sun.medialib.mlib.*;
041:        import com.sun.media.jai.util.ImageUtil;
042:
043:        // import com.sun.media.jai.test.OpImageTester;
044:
045:        /**
046:         * An OpImage class to perform AffineTransform on a source image.
047:         *
048:         */
049:        class MlibAffineOpImage extends GeometricOpImage {
050:
051:            /**
052:             * The transformation in matrix form (medialib expects this form)
053:             */
054:            protected double f_transform[];
055:            protected double m_transform[];
056:            protected double medialib_tr[];
057:            protected AffineTransform transform;
058:            protected AffineTransform i_transform;
059:
060:            /** The Interpolation object. */
061:            protected Interpolation interp;
062:
063:            /** Store source & padded rectangle info */
064:            private Rectangle srcimg, padimg;
065:
066:            /** The BorderExtender */
067:            protected BorderExtender extender;
068:
069:            /** The true writable area */
070:            private Rectangle theDest;
071:
072:            /** Cache the ImagingListener */
073:            private ImagingListener listener;
074:
075:            /**
076:             * Padding values for interpolation
077:             */
078:            public int lpad, rpad, tpad, bpad;
079:
080:            private static ImageLayout layoutHelper(ImageLayout layout,
081:                    RenderedImage source, AffineTransform forward_tr) {
082:                ImageLayout newLayout;
083:                if (layout != null) {
084:                    newLayout = (ImageLayout) layout.clone();
085:                } else {
086:                    newLayout = new ImageLayout();
087:                }
088:
089:                //
090:                // Get sx0,sy0 coordinates & width & height of the source.
091:                //
092:                float sx0 = (float) source.getMinX();
093:                float sy0 = (float) source.getMinY();
094:                float sw = (float) source.getWidth();
095:                float sh = (float) source.getHeight();
096:
097:                //
098:                // The 4 points (clockwise order) are
099:                //      (sx0, sy0),    (sx0+sw, sy0)
100:                //      (sx0, sy0+sh), (sx0+sw, sy0+sh)
101:                //
102:                Point2D[] pts = new Point2D[4];
103:                pts[0] = new Point2D.Float(sx0, sy0);
104:                pts[1] = new Point2D.Float((sx0 + sw), sy0);
105:                pts[2] = new Point2D.Float((sx0 + sw), (sy0 + sh));
106:                pts[3] = new Point2D.Float(sx0, (sy0 + sh));
107:
108:                // Forward map
109:                forward_tr.transform(pts, 0, pts, 0, 4);
110:
111:                float dx0 = Float.MAX_VALUE;
112:                float dy0 = Float.MAX_VALUE;
113:                float dx1 = -Float.MAX_VALUE;
114:                float dy1 = -Float.MAX_VALUE;
115:                for (int i = 0; i < 4; i++) {
116:                    float px = (float) pts[i].getX();
117:                    float py = (float) pts[i].getY();
118:
119:                    dx0 = Math.min(dx0, px);
120:                    dy0 = Math.min(dy0, py);
121:                    dx1 = Math.max(dx1, px);
122:                    dy1 = Math.max(dy1, py);
123:                }
124:
125:                //
126:                // Get the width & height of the resulting bounding box.
127:                // This is set on the layout
128:                //
129:                int lw = (int) (dx1 - dx0);
130:                int lh = (int) (dy1 - dy0);
131:
132:                //
133:                // Set the starting integral coordinate
134:                // with the following criterion.
135:                // If it's greater than 0.5, set it to the next integral value (ceil)
136:                // else set it to the integral value (floor).
137:                //
138:                int lx0, ly0;
139:
140:                int i_dx0 = (int) Math.floor(dx0);
141:                if (Math.abs(dx0 - i_dx0) <= 0.5) {
142:                    lx0 = i_dx0;
143:                } else {
144:                    lx0 = (int) Math.ceil(dx0);
145:                }
146:
147:                int i_dy0 = (int) Math.floor(dy0);
148:                if (Math.abs(dy0 - i_dy0) <= 0.5) {
149:                    ly0 = i_dy0;
150:                } else {
151:                    ly0 = (int) Math.ceil(dy0);
152:                }
153:
154:                //
155:                // Create the layout
156:                //
157:                newLayout.setMinX(lx0);
158:                newLayout.setMinY(ly0);
159:                newLayout.setWidth(lw);
160:                newLayout.setHeight(lh);
161:
162:                return newLayout;
163:            }
164:
165:            /**
166:             * Creates a MlibAffineOpImage given a ParameterBlock containing the
167:             * image source and the AffineTransform and the interpolation.
168:             * The image dimensions are derived from the source image.  The tile
169:             * grid layout, SampleModel, and ColorModel may optionally be specified
170:             * by an ImageLayout object.
171:             *
172:             * @param source a RenderedImage.
173:             * @param extender a BorderExtender, or null.
174:
175:             *        or null.  If null, a default cache will be used.
176:             * @param layout an ImageLayout optionally containing the tile grid layout,
177:             *        SampleModel, and ColorModel, or null.
178:             * @param kernel the convolution KernelJAI.
179:             */
180:            public MlibAffineOpImage(RenderedImage source, ImageLayout layout,
181:                    Map config, BorderExtender extender,
182:                    AffineTransform transform, Interpolation interp,
183:                    double[] backgroundValues) {
184:                super (vectorize(source),
185:                        layoutHelper(layout, source, transform), config, true,
186:                        extender, interp, backgroundValues);
187:
188:                // store the interp and extender objects
189:                this .interp = interp;
190:
191:                // the extender
192:                this .extender = extender;
193:
194:                // cache the listener
195:                listener = ImageUtil
196:                        .getImagingListener((java.awt.RenderingHints) config);
197:
198:                // Store the padding values
199:                lpad = interp.getLeftPadding();
200:                rpad = interp.getRightPadding();
201:                tpad = interp.getTopPadding();
202:                bpad = interp.getBottomPadding();
203:
204:                //
205:                // Store source bounds rectangle
206:                // and the padded rectangle (for extension cases)
207:                //
208:                srcimg = new Rectangle(getSourceImage(0).getMinX(),
209:                        getSourceImage(0).getMinY(), getSourceImage(0)
210:                                .getWidth(), getSourceImage(0).getHeight());
211:                padimg = new Rectangle(srcimg.x - lpad, srcimg.y - tpad,
212:                        srcimg.width + lpad + rpad, srcimg.height + tpad + bpad);
213:
214:                if (extender == null) {
215:                    //
216:                    // Source has to be shrunk as per interpolation
217:                    // as a result the destination produced could
218:                    // be different from the layout
219:                    //
220:
221:                    //
222:                    // Get sx0,sy0 coordinates and width & height of the source
223:                    //
224:                    float sx0 = (float) srcimg.x;
225:                    float sy0 = (float) srcimg.y;
226:                    float sw = (float) srcimg.width;
227:                    float sh = (float) srcimg.height;
228:
229:                    //
230:                    // get padding amounts as per interpolation
231:                    //
232:                    float f_lpad = (float) lpad;
233:                    float f_rpad = (float) rpad;
234:                    float f_tpad = (float) tpad;
235:                    float f_bpad = (float) bpad;
236:
237:                    //
238:                    // As per pixel defined to be at (0.5, 0.5)
239:                    //
240:                    if ((interp instanceof  InterpolationBilinear)
241:                            || (interp instanceof  InterpolationBicubic)
242:                            || (interp instanceof  InterpolationBicubic2)) {
243:                        f_lpad += 0.5;
244:                        f_tpad += 0.5;
245:                        f_rpad += 0.5;
246:                        f_bpad += 0.5;
247:                    }
248:
249:                    //
250:                    // Shrink the source by padding amount prior to forward map
251:                    // This is the maxmimum available source than can be mapped
252:                    //
253:                    sx0 += f_lpad;
254:                    sy0 += f_tpad;
255:                    sw -= (f_lpad + f_rpad);
256:                    sh -= (f_tpad + f_bpad);
257:
258:                    //
259:                    // The 4 points are (x0, y0),     (x0+w, y0)
260:                    //                  (x0+w, y0+h), (x0, y0+h)
261:                    //
262:                    Point2D[] pts = new Point2D[4];
263:                    pts[0] = new Point2D.Float(sx0, sy0);
264:                    pts[1] = new Point2D.Float((sx0 + sw), sy0);
265:                    pts[2] = new Point2D.Float((sx0 + sw), (sy0 + sh));
266:                    pts[3] = new Point2D.Float(sx0, (sy0 + sh));
267:
268:                    // Forward map
269:                    transform.transform(pts, 0, pts, 0, 4);
270:
271:                    float dx0 = Float.MAX_VALUE;
272:                    float dy0 = Float.MAX_VALUE;
273:                    float dx1 = -Float.MAX_VALUE;
274:                    float dy1 = -Float.MAX_VALUE;
275:                    for (int i = 0; i < 4; i++) {
276:                        float px = (float) pts[i].getX();
277:                        float py = (float) pts[i].getY();
278:
279:                        dx0 = Math.min(dx0, px);
280:                        dy0 = Math.min(dy0, py);
281:                        dx1 = Math.max(dx1, px);
282:                        dy1 = Math.max(dy1, py);
283:                    }
284:
285:                    //
286:                    // The layout is the wholly contained integer area of the
287:                    // corresponding floating point bounding box.
288:                    // We cannot round the corners of the floating rect because it
289:                    // would increase the size of the rect, so we need to ceil the
290:                    // upper corner and floor the lower corner.
291:                    //
292:                    int lx0 = (int) Math.ceil(dx0);
293:                    int ly0 = (int) Math.ceil(dy0);
294:                    int lx1 = (int) Math.floor(dx1);
295:                    int ly1 = (int) Math.floor(dy1);
296:
297:                    theDest = new Rectangle(lx0, ly0, lx1 - lx0, ly1 - ly0);
298:                } else {
299:                    theDest = getBounds();
300:                }
301:
302:                // Store the inverse and forward transform
303:                try {
304:                    this .i_transform = transform.createInverse();
305:                } catch (java.awt.geom.NoninvertibleTransformException e) {
306:                    String message = JaiI18N.getString("MlibAffineOpImage0");
307:                    listener.errorOccurred(message, new ImagingException(
308:                            message, e), this , false);
309:                    //            throw new RuntimeException(JaiI18N.getString("MlibAffineOpImage0"));
310:                }
311:                this .transform = (AffineTransform) transform.clone();
312:
313:                //
314:                // Get the forward transform into an array
315:                // Java returns the values into the array as
316:                // {m00 m10 m01 m11 m02 m12}
317:                //
318:                this .f_transform = new double[6];
319:                transform.getMatrix(this .f_transform);
320:
321:                //
322:                // Rearrange the transform to medialib specifications
323:                // J2D's transform is [m00 m01 m02] [m10 m11 m12]
324:                // Medialib's transform is [a b tx] [c d ty]
325:                //
326:                this .medialib_tr = new double[6];
327:                medialib_tr[0] = f_transform[0]; // a  <---> m00
328:                medialib_tr[1] = f_transform[2]; // b  <---> m01
329:                medialib_tr[2] = f_transform[4]; // tx <---> m02
330:                medialib_tr[3] = f_transform[1]; // c  <---> m10
331:                medialib_tr[4] = f_transform[3]; // d  <---> m11
332:                medialib_tr[5] = f_transform[5]; // ty <---> m12
333:
334:                //
335:                // Make a copy for our internal use
336:                //
337:                this .m_transform = new double[6];
338:                m_transform[0] = f_transform[0]; // a  <---> m00
339:                m_transform[1] = f_transform[2]; // b  <---> m01
340:                m_transform[2] = f_transform[4]; // tx <---> m02
341:                m_transform[3] = f_transform[1]; // c  <---> m10
342:                m_transform[4] = f_transform[3]; // d  <---> m11
343:                m_transform[5] = f_transform[5]; // ty <---> m12
344:            }
345:
346:            /**
347:             * Computes the source point corresponding to the supplied point.
348:             *
349:             * @param destPt the position in destination image coordinates
350:             * to map to source image coordinates.
351:             *
352:             * @return a <code>Point2D</code> of the same class as
353:             * <code>destPt</code>.
354:             *
355:             * @throws IllegalArgumentException if <code>destPt</code> is
356:             * <code>null</code>.
357:             *
358:             * @since JAI 1.1.2
359:             */
360:            public Point2D mapDestPoint(Point2D destPt) {
361:                if (destPt == null) {
362:                    throw new IllegalArgumentException(JaiI18N
363:                            .getString("Generic0"));
364:                }
365:
366:                Point2D dpt = (Point2D) destPt.clone();
367:                dpt.setLocation(dpt.getX() + 0.5, dpt.getY() + 0.5);
368:
369:                Point2D spt = i_transform.transform(dpt, null);
370:                spt.setLocation(spt.getX() - 0.5, spt.getY() - 0.5);
371:
372:                return spt;
373:            }
374:
375:            /**
376:             * Computes the destination point corresponding to the supplied point.
377:             *
378:             * @param sourcePt the position in source image coordinates
379:             * to map to destination image coordinates.
380:             *
381:             * @return a <code>Point2D</code> of the same class as
382:             * <code>sourcePt</code>.
383:             *
384:             * @throws IllegalArgumentException if <code>destPt</code> is
385:             * <code>null</code>.
386:             *
387:             * @since JAI 1.1.2
388:             */
389:            public Point2D mapSourcePoint(Point2D sourcePt) {
390:                if (sourcePt == null) {
391:                    throw new IllegalArgumentException(JaiI18N
392:                            .getString("Generic0"));
393:                }
394:
395:                Point2D spt = (Point2D) sourcePt.clone();
396:                spt.setLocation(spt.getX() + 0.5, spt.getY() + 0.5);
397:
398:                Point2D dpt = transform.transform(spt, null);
399:                dpt.setLocation(dpt.getX() - 0.5, dpt.getY() - 0.5);
400:
401:                return dpt;
402:            }
403:
404:            /**
405:             * Forward map the source Rectangle.
406:             */
407:            protected Rectangle forwardMapRect(Rectangle sourceRect,
408:                    int sourceIndex) {
409:                return transform.createTransformedShape(sourceRect).getBounds();
410:            }
411:
412:            /**
413:             * Backward map the destination Rectangle.
414:             */
415:            protected Rectangle backwardMapRect(Rectangle destRect,
416:                    int sourceIndex) {
417:                //
418:                // Backward map the destination rectangle to get the
419:                // corresponding source rectangle
420:                //
421:                float dx0 = (float) destRect.x;
422:                float dy0 = (float) destRect.y;
423:                float dw = (float) (destRect.width);
424:                float dh = (float) (destRect.height);
425:
426:                Point2D[] pts = new Point2D[4];
427:                pts[0] = new Point2D.Float(dx0, dy0);
428:                pts[1] = new Point2D.Float((dx0 + dw), dy0);
429:                pts[2] = new Point2D.Float((dx0 + dw), (dy0 + dh));
430:                pts[3] = new Point2D.Float(dx0, (dy0 + dh));
431:
432:                i_transform.transform(pts, 0, pts, 0, 4);
433:
434:                float f_sx0 = Float.MAX_VALUE;
435:                float f_sy0 = Float.MAX_VALUE;
436:                float f_sx1 = -Float.MAX_VALUE;
437:                float f_sy1 = -Float.MAX_VALUE;
438:                for (int i = 0; i < 4; i++) {
439:                    float px = (float) pts[i].getX();
440:                    float py = (float) pts[i].getY();
441:
442:                    f_sx0 = Math.min(f_sx0, px);
443:                    f_sy0 = Math.min(f_sy0, py);
444:                    f_sx1 = Math.max(f_sx1, px);
445:                    f_sy1 = Math.max(f_sy1, py);
446:                }
447:
448:                int s_x0 = 0, s_y0 = 0, s_x1 = 0, s_y1 = 0;
449:
450:                // Find the bounding box of the source rectangle
451:                if (interp instanceof  InterpolationNearest) {
452:                    s_x0 = (int) Math.floor(f_sx0);
453:                    s_y0 = (int) Math.floor(f_sy0);
454:                    s_x1 = (int) Math.ceil(f_sx1);
455:                    s_y1 = (int) Math.ceil(f_sy1);
456:                } else {
457:                    s_x0 = (int) Math.floor(f_sx0 - 0.5);
458:                    s_y0 = (int) Math.floor(f_sy0 - 0.5);
459:                    s_x1 = (int) Math.ceil(f_sx1);
460:                    s_y1 = (int) Math.ceil(f_sy1);
461:                }
462:
463:                //
464:                // Return the new rectangle
465:                //
466:                return new Rectangle(s_x0, s_y0, s_x1 - s_x0, s_y1 - s_y0);
467:            }
468:
469:            /*
470:             * Compute a given tile
471:             */
472:            public Raster computeTile(int tileX, int tileY) {
473:                //
474:                // Create a new WritableRaster to represent this tile.
475:                //
476:                Point org = new Point(tileXToX(tileX), tileYToY(tileY));
477:                WritableRaster dest = createWritableRaster(sampleModel, org);
478:
479:                //
480:                // Clip output rectangle to image bounds.
481:                //
482:                Rectangle rect = new Rectangle(org.x, org.y, tileWidth,
483:                        tileHeight);
484:
485:                //
486:                // Clip destination tile against the writable destination
487:                // area. This is either the layout or a smaller area if
488:                // no extension is specified.
489:                //
490:                Rectangle destRect = rect.intersection(theDest);
491:                Rectangle destRect1 = rect.intersection(getBounds());
492:                if ((destRect.width <= 0) || (destRect.height <= 0)) {
493:                    if (setBackground) {
494:                        ImageUtil.fillBackground(dest, destRect1,
495:                                backgroundValues);
496:                    }
497:                    // No area to write
498:                    return dest;
499:                }
500:
501:                //
502:                // determine the source rectangle needed to compute the destRect
503:                //
504:                Rectangle srcRect = mapDestRect(destRect, 0);
505:                if (extender == null) {
506:                    srcRect = srcRect.intersection(srcimg);
507:                } else {
508:                    srcRect = srcRect.intersection(padimg);
509:                }
510:
511:                if (srcRect.width <= 0 || srcRect.height <= 0) {
512:                    // destRect backward mapped outside the source
513:                    if (setBackground) {
514:                        ImageUtil.fillBackground(dest, destRect1,
515:                                backgroundValues);
516:                    }
517:                    return dest;
518:                }
519:
520:                if (!destRect1.equals(destRect)) {
521:                    // beware that destRect1 contains destRect
522:                    ImageUtil.fillBordersWithBackgroundValues(destRect1,
523:                            destRect, dest, backgroundValues);
524:                }
525:
526:                Raster[] sources = new Raster[1];
527:
528:                // Get the source data
529:                if (extender == null) {
530:                    sources[0] = getSourceImage(0).getData(srcRect);
531:                } else {
532:                    sources[0] = getSourceImage(0).getExtendedData(srcRect,
533:                            extender);
534:                }
535:
536:                computeRect(sources, dest, destRect);
537:
538:                // Recycle the source tile
539:                if (getSourceImage(0).overlapsMultipleTiles(srcRect)) {
540:                    recycleTile(sources[0]);
541:                }
542:
543:                return dest;
544:            }
545:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.