Source Code Cross Referenced for ImageMIPMap.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: ImageMIPMap.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:09 $
010:         * $State: Exp $
011:         */
012:        package javax.media.jai;
013:
014:        import java.awt.Image;
015:        import java.awt.geom.AffineTransform;
016:        import java.awt.image.RenderedImage;
017:        import java.awt.image.renderable.ParameterBlock;
018:        import java.awt.image.renderable.RenderableImage;
019:        import java.beans.PropertyChangeListener;
020:        import java.util.Vector;
021:        import com.sun.media.jai.util.PropertyUtil;
022:
023:        /**
024:         * A class implementing the "MIP map" operation on a
025:         * <code>RenderedImage</code>.  Given a <code>RenderedImage</code>,
026:         * which represents the image at the highest resolution level, the
027:         * image at each lower resolution level may be derived by performing a
028:         * specific chain of operations to down sample the image at the next
029:         * higher resolution level repeatedly.  The highest resolution level is
030:         * defined as level 0.
031:         *
032:         * <p> The <code>downSampler</code> is a chain of operations that is
033:         * used to derive the image at the next lower resolution level from
034:         * the image at the current resolution level.  That is, given an image
035:         * at resolution level <code>i</code>, the <code>downSampler</code> is
036:         * used to obtain the image at resolution level <code>i+1</code>.
037:         * The chain may contain one or more operation nodes; however, each
038:         * node must be a <code>RenderedOp</code>.  The parameter points to the
039:         * last node in the chain.  The very first node in the chain must be
040:         * a <code>RenderedOp</code> that takes one <code>RenderedImage</code>
041:         * as its source.  All other nodes may have multiple sources.  When
042:         * traversing back up the chain, if a node has more than one source,
043:         * the first source, <code>source0</code>, is used to move up the
044:         * chain.  This parameter is saved by reference.
045:         *
046:         * @see ImagePyramid
047:         *
048:         */
049:        public class ImageMIPMap implements  ImageJAI {
050:
051:            /** The image with the highest resolution. */
052:            protected RenderedImage highestImage;
053:
054:            /** The image at the current resolution level. */
055:            protected RenderedImage currentImage;
056:
057:            /** The current resolution level. */
058:            protected int currentLevel = 0;
059:
060:            /** The operation chain used to derive the lower resolution images. */
061:            protected RenderedOp downSampler;
062:
063:            /**
064:             * A helper object to manage firing events.
065:             *
066:             * @since JAI 1.1
067:             */
068:            protected PropertyChangeSupportJAI eventManager = null;
069:
070:            /**
071:             * A helper object to manage the image properties.
072:             *
073:             * @since JAI 1.1
074:             */
075:            protected WritablePropertySourceImpl properties = null;
076:
077:            /** The default constructor. */
078:            protected ImageMIPMap() {
079:                eventManager = new PropertyChangeSupportJAI(this );
080:                properties = new WritablePropertySourceImpl(null, null,
081:                        eventManager);
082:            }
083:
084:            /**
085:             * Constructor.  The down sampler is an "affine" operation that
086:             * uses the supplied <code>AffineTransform</code> and
087:             * <code>Interpolation</code> objects.
088:             * All input parameters are saved by reference.
089:             *
090:             * @param image  The image with the highest resolution.
091:             * @param transform  An affine matrix used with an "affine" operation
092:             *        to derive the lower resolution images.
093:             * @param interpolation  The interpolation method for the "affine"
094:             *        operation.  It may be <code>null</code>, in which case the
095:             *        default "nearest neighbor" interpolation method is used.
096:             *
097:             * @throws IllegalArgumentException if <code>image</code> is
098:             *         <code>null</code>.
099:             * @throws IllegalArgumentException if <code>transform</code> is
100:             *         <code>null</code>.
101:             */
102:            public ImageMIPMap(RenderedImage image, AffineTransform transform,
103:                    Interpolation interpolation) {
104:                this ();
105:
106:                if (image == null || transform == null) {
107:                    throw new IllegalArgumentException(JaiI18N
108:                            .getString("Generic0"));
109:                }
110:
111:                ParameterBlock pb = new ParameterBlock();
112:                pb.addSource(image);
113:                pb.add(transform);
114:                pb.add(interpolation);
115:
116:                downSampler = JAI.create("affine", pb);
117:                downSampler.removeSources();
118:
119:                highestImage = image;
120:                currentImage = highestImage;
121:            }
122:
123:            /**
124:             * Constructor.  The <code>downSampler</code> points to the last
125:             * operation node in the <code>RenderedOp</code> chain.  The very
126:             * first operation in the chain must not have any source images
127:             * specified; that is, its number of sources must be 0.  All input
128:             * parameters are saved by reference.
129:             *
130:             * @param image  The image with the highest resolution.
131:             * @param downSampler  The operation chain used to derive the lower
132:             *        resolution images.  No validation is done on the first
133:             *        operation in the chain.
134:             *
135:             * @throws IllegalArgumentException if <code>image</code> is <code>null</code>.
136:             * @throws IllegalArgumentException if <code>downSampler</code> is
137:             *         <code>null</code>.
138:             */
139:            public ImageMIPMap(RenderedImage image, RenderedOp downSampler) {
140:                this ();
141:                if (image == null || downSampler == null) {
142:                    throw new IllegalArgumentException(JaiI18N
143:                            .getString("Generic0"));
144:                }
145:
146:                highestImage = image;
147:                currentImage = highestImage;
148:                this .downSampler = downSampler;
149:            }
150:
151:            /**
152:             * Constructs a new <code>ImageMIPMap</code> from a
153:             * <code>RenderedOp</code> chain.  The <code>downSampler</code>
154:             * points to the last operation node in the
155:             * <code>RenderedOp</code> chain.  The source image is determined
156:             * by traversing up the chain: starting at the bottom node, given by
157:             * the <code>downSample</code> parameter, we move to the first
158:             * source of the node and repeat until we find either a sourceless
159:             * <code>RenderedOp</code> or any other type of
160:             * <code>RenderedImage</code>.
161:             *
162:             * The <code>downSampler</code> parameter is saved by reference
163:             * and should not be modified during the lifetime of any
164:             * <code>ImageMIPMap</code> referring to it.
165:             *
166:             * @param downSampler  The operation chain used to derive the lower
167:             *        resolution images.  The source of the first node in this
168:             *        chain is taken as the image with the highest resolution.
169:             *
170:             * @throws IllegalArgumentException if <code>downSampler</code> is
171:             *         <code>null</code>.
172:             * @throws IllegalArgumentException if <code>downSampler</code>
173:             *         has no sources.
174:             * @throws IllegalArgumentException if an object other than a
175:             *         <code>RenderedImage</code> is found in the
176:             *         <code>downSampler</code> chain.
177:             */
178:            public ImageMIPMap(RenderedOp downSampler) {
179:                this ();
180:
181:                if (downSampler == null) {
182:                    throw new IllegalArgumentException(JaiI18N
183:                            .getString("Generic0"));
184:                }
185:
186:                if (downSampler.getNumSources() == 0) {
187:                    throw new IllegalArgumentException(JaiI18N
188:                            .getString("ImageMIPMap0"));
189:                }
190:
191:                // Find the highest resolution image from the chain.
192:                RenderedOp op = downSampler;
193:                while (true) {
194:                    Object src = op.getNodeSource(0);
195:
196:                    if (src instanceof  RenderedOp) {
197:                        RenderedOp srcOp = (RenderedOp) src;
198:
199:                        if (srcOp.getNumSources() == 0) {
200:                            highestImage = srcOp;
201:                            op.removeSources();
202:                            break;
203:                        } else {
204:                            op = srcOp;
205:                        }
206:                    } else if (src instanceof  RenderedImage) {
207:                        highestImage = (RenderedImage) src;
208:                        op.removeSources();
209:                        break;
210:                    } else {
211:                        throw new IllegalArgumentException(JaiI18N
212:                                .getString("ImageMIPMap1"));
213:                    }
214:                }
215:
216:                currentImage = highestImage;
217:                this .downSampler = downSampler;
218:            }
219:
220:            /**
221:             * Returns an array of <code>String</code>s recognized as names by
222:             * this property source.  If no property names match,
223:             * <code>null</code> will be returned.
224:             *
225:             * <p> The default implementation returns <code>null</code>, i.e.,
226:             * no property names are recognized.
227:             *
228:             * @return An array of <code>String</code>s giving the valid
229:             *         property names.
230:             */
231:            public String[] getPropertyNames() {
232:                return properties.getPropertyNames();
233:            }
234:
235:            /**
236:             * Returns an array of <code>String</code>s recognized as names by
237:             * this property source that begin with the supplied prefix.  If
238:             * no property names are recognized, or no property names match,
239:             * <code>null</code> will be returned.
240:             * The comparison is done in a case-independent manner.
241:             *
242:             * @return An array of <code>String</code>s giving the valid
243:             *         property names.
244:             *
245:             * @param prefix the supplied prefix for the property source.
246:             *
247:             * @throws IllegalArgumentException if <code>prefix</code> is
248:             *                                  <code>null</code>.
249:             */
250:            public String[] getPropertyNames(String prefix) {
251:                return properties.getPropertyNames(prefix);
252:            }
253:
254:            /**
255:             * Returns the class expected to be returned by a request for
256:             * the property with the specified name.  If this information
257:             * is unavailable, <code>null</code> will be returned.
258:             *
259:             * @return The <code>Class</code> expected to be return by a
260:             *         request for the value of this property or <code>null</code>.
261:             *
262:             * @exception IllegalArgumentException if <code>name</code>
263:             *                                     is <code>null</code>.
264:             *
265:             * @since JAI 1.1
266:             */
267:            public Class getPropertyClass(String name) {
268:                return properties.getPropertyClass(name);
269:            }
270:
271:            /**
272:             * Returns the specified property.  The default implementation
273:             * returns <code>java.awt.Image.UndefinedProperty</code>.
274:             *
275:             * @param name  The name of the property.
276:             *
277:             * @return The value of the property, as an Object.
278:             *
279:             * @exception IllegalArgumentException if <code>name</code>
280:             *                                     is <code>null</code>.
281:             */
282:            public Object getProperty(String name) {
283:                return properties.getProperty(name);
284:            }
285:
286:            /**
287:             * Sets a property on a <code>ImageMIPMap</code>.
288:             *
289:             * @param name a <code>String</code> containing the property's name.
290:             * @param value the property, as a general <code>Object</code>.
291:             *
292:             * @throws IllegalArgumentException  If <code>name</code> or 
293:             *         <code>value</code> is <code>null</code>.
294:             *
295:             * @since JAI 1.1
296:             */
297:            public void setProperty(String name, Object value) {
298:                properties.setProperty(name, value);
299:            }
300:
301:            /**
302:             * Removes the named property from the <code>ImageMIPMap</code>.
303:             *
304:             * @exception IllegalArgumentException if <code>name</code>
305:             *                                     is <code>null</code>.
306:             *
307:             * @since JAI 1.1
308:             */
309:            public void removeProperty(String name) {
310:                properties.removeProperty(name);
311:            }
312:
313:            /**
314:             * Add a PropertyChangeListener to the listener list. The
315:             * listener is registered for all properties.
316:             *
317:             * @since JAI 1.1
318:             */
319:            public void addPropertyChangeListener(
320:                    PropertyChangeListener listener) {
321:                eventManager.addPropertyChangeListener(listener);
322:            }
323:
324:            /**
325:             * Add a PropertyChangeListener for a specific property. The
326:             * listener will be invoked only when a call on
327:             * firePropertyChange names that specific property.  The case of
328:             * the name is ignored.
329:             *
330:             * @since JAI 1.1
331:             */
332:            public void addPropertyChangeListener(String propertyName,
333:                    PropertyChangeListener listener) {
334:                eventManager.addPropertyChangeListener(propertyName, listener);
335:            }
336:
337:            /**
338:             * Remove a PropertyChangeListener from the listener list. This
339:             * removes a PropertyChangeListener that was registered for all
340:             * properties.
341:             *
342:             * @since JAI 1.1
343:             */
344:            public void removePropertyChangeListener(
345:                    PropertyChangeListener listener) {
346:                eventManager.removePropertyChangeListener(listener);
347:            }
348:
349:            /**
350:             * Remove a PropertyChangeListener for a specific property.  The case
351:             * of the name is ignored.
352:             *
353:             * @since JAI 1.1
354:             */
355:            public void removePropertyChangeListener(String propertyName,
356:                    PropertyChangeListener listener) {
357:                eventManager.removePropertyChangeListener(propertyName,
358:                        listener);
359:            }
360:
361:            /**
362:             * Returns the current resolution level.  The highest resolution
363:             * level is defined as level 0.
364:             */
365:            public int getCurrentLevel() {
366:                return currentLevel;
367:            }
368:
369:            /** Returns the image at the current resolution level. */
370:            public RenderedImage getCurrentImage() {
371:                return currentImage;
372:            }
373:
374:            /**
375:             * Returns the image at the specified resolution level.  The
376:             * requested level must be greater than or equal to 0 or
377:             * <code>null</code> will be returned.
378:             *
379:             * @param level The specified level of resolution
380:             */
381:            public RenderedImage getImage(int level) {
382:                if (level < 0) {
383:                    return null;
384:                }
385:
386:                if (level < currentLevel) { // restart from the highest image
387:                    currentImage = highestImage;
388:                    currentLevel = 0;
389:                }
390:
391:                while (currentLevel < level) {
392:                    getDownImage();
393:                }
394:                return currentImage;
395:            }
396:
397:            /**
398:             * Returns the image at the next lower resolution level,
399:             * obtained by applying the <code>downSampler</code> on the
400:             * image at the current resolution level.
401:             */
402:            public RenderedImage getDownImage() {
403:                currentLevel++;
404:
405:                /* Duplicate the downSampler op chain. */
406:                RenderedOp op = duplicate(downSampler, vectorize(currentImage));
407:                currentImage = op.getRendering();
408:                return currentImage;
409:            }
410:
411:            /**
412:             * Duplicates a <code>RenderedOp</code> chain.  Each node in the
413:             * chain must be a <code>RenderedOp</code>.  The <code>op</code>
414:             * parameter points to the last <code>RenderedOp</code> in the chain.
415:             * The very first op in the chain must have no sources and its source
416:             * will be set to the supplied image vector.  When traversing up the
417:             * chain, if any node has more than one source, the first source will
418:             * be used.  The first source of each node is duplicated; all other
419:             * sources are copied by reference.
420:             *
421:             * @param op RenderedOp chain
422:             * @param vector of source images
423:             *
424:             * @throws IllegalArgumentException if <code>op</code> is <code>null</code>.
425:             * @throws IllegalArgumentException if <code>images</code> is <code>null</code>.
426:             */
427:            protected RenderedOp duplicate(RenderedOp op, Vector images) {
428:                if (images == null) {
429:                    throw new IllegalArgumentException(JaiI18N
430:                            .getString("Generic0"));
431:                }
432:
433:                //
434:                // Duplicates a RenderedOp with the original OperationRegistry,
435:                // OperationName, ParameterBlock, and RenderingHints copied over
436:                // by reference.  No property information is copied.
437:                //
438:                op = new RenderedOp(op.getRegistry(), op.getOperationName(), op
439:                        .getParameterBlock(), op.getRenderingHints());
440:
441:                ParameterBlock pb = new ParameterBlock();
442:                pb.setParameters(op.getParameters());
443:
444:                Vector srcs = op.getSources();
445:                int numSrcs = srcs.size();
446:
447:                if (numSrcs == 0) { // first op in the chain
448:                    pb.setSources(images);
449:
450:                } else { // recursively duplicate source0
451:                    pb.addSource(duplicate((RenderedOp) srcs.elementAt(0),
452:                            images));
453:
454:                    for (int i = 1; i < numSrcs; i++) {
455:                        pb.addSource(srcs.elementAt(i));
456:                    }
457:                }
458:
459:                op.setParameterBlock(pb);
460:                return op;
461:            }
462:
463:            /**
464:             * Returns the current image as a <code>RenderableImage</code>.
465:             * This method returns a <code>MultiResolutionRenderableImage</code>.
466:             * The <code>numImages</code> parameter indicates the number of
467:             * <code>RenderedImage</code>s used to construct the
468:             * <code>MultiResolutionRenderableImage</code>.  Starting with the
469:             * current image, the images are obtained by finding the necessary
470:             * number of lower resolution images using the <code>downSampler</code>.
471:             * The current level and current image will not be changed.
472:             * If the width or height reaches 1, the downsampling will stop
473:             * and return the renderable image.
474:             *
475:             * <p> The <code>numImages</code> should be greater than or equal to 1.
476:             * If a value of less than 1 is specified, this method uses 1 image,
477:             * which is the current image.
478:             *
479:             * @param numImages The number of lower resolution images.
480:             * @param minX The minimum X coordinate of the Renderable, as a float.
481:             * @param minY The minimum Y coordinate of the Renderable, as a float.
482:             * @param height The height of the Renderable, as a float.
483:             *
484:             * @throws IllegalArgumentException if <code>height</code> is less than 0.
485:             *
486:             * @see MultiResolutionRenderableImage
487:             */
488:            public RenderableImage getAsRenderable(int numImages, float minX,
489:                    float minY, float height) {
490:                Vector v = new Vector();
491:                v.add(currentImage);
492:
493:                RenderedImage image = currentImage;
494:                for (int i = 1; i < numImages; i++) {
495:                    RenderedOp op = duplicate(downSampler, vectorize(image));
496:                    image = op.getRendering();
497:
498:                    if (image.getWidth() <= 1 || image.getHeight() <= 1) {
499:                        break;
500:                    }
501:
502:                    v.add(image);
503:                }
504:
505:                return new MultiResolutionRenderableImage(v, minX, minY, height);
506:            }
507:
508:            /**
509:             * Returns the current image as a <code>RenderableImage</code>.
510:             * This method returns a <code>MultiResolutionRenderableImage</code>
511:             * with the current image as the only source image, minX and minY
512:             * set to 0.0, and height set to 1.0.
513:             *
514:             * @see MultiResolutionRenderableImage
515:             */
516:            public RenderableImage getAsRenderable() {
517:                return getAsRenderable(1, 0.0F, 0.0F, 1.0F);
518:            }
519:
520:            // XXX - see OpImage vectorize and consolidate?
521:            //       could be public static in PlanarImage
522:            /**
523:             * Creates and returns a <code>Vector</code> containing a single
524:             * element equal to the supplied <code>RenderedImage</code>.
525:             *
526:             *
527:             * @since JAI 1.1
528:             */
529:            protected final Vector vectorize(RenderedImage image) {
530:                Vector v = new Vector(1);
531:                v.add(image);
532:                return v;
533:            }
534:
535:            /**
536:             * Creates and returns a <code>Vector</code> containing two
537:             * elements equal to the supplied <code>RenderedImage</code>s
538:             * in the order given.
539:             *
540:             *
541:             * @since JAI 1.1
542:             */
543:            protected final Vector vectorize(RenderedImage im1,
544:                    RenderedImage im2) {
545:                Vector v = new Vector(2);
546:                v.add(im1);
547:                v.add(im2);
548:                return v;
549:            }
550:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.