Source Code Cross Referenced for SnapshotImage.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: SnapshotImage.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.2 $
009:         * $Date: 2005/05/12 18:24:34 $
010:         * $State: Exp $
011:         */
012:        package javax.media.jai;
013:
014:        import java.awt.Point;
015:        import java.awt.image.Raster;
016:        import java.awt.image.TileObserver;
017:        import java.awt.image.WritableRaster;
018:        import java.awt.image.WritableRenderedImage;
019:        import java.util.Enumeration;
020:        import java.util.HashSet;
021:        import java.util.Hashtable;
022:        import java.util.Iterator;
023:
024:        /**
025:         * A (Raster, X, Y) tuple.
026:         */
027:        final class TileCopy {
028:
029:            /** The tile's <code>Raster</code> data. */
030:            Raster tile;
031:
032:            /** The tile's column within the image tile grid. */
033:            int tileX;
034:
035:            /** The tile's row within the image tile grid. */
036:            int tileY;
037:
038:            /**
039:             * Constructs a TileCopy object given the tile's <code>Raster</code> data
040:             * and its location in the tile grid.
041:             *
042:             * @param tile the <code>Raster</code> containing the tile's data.
043:             * @param tileX the tile's X position in the tile grid.
044:             * @param tileY the tile's X position in the tile grid.
045:             */
046:            TileCopy(Raster tile, int tileX, int tileY) {
047:                this .tile = tile;
048:                this .tileX = tileX;
049:                this .tileY = tileY;
050:            }
051:        }
052:
053:        /**
054:         * A proxy for <code>Snapshot</code> that calls
055:         * <code>Snapshot.dispose()</code> when finalized.
056:         * No references to a SnapshotProxy are held internally, only user
057:         * references.  Thus it will be garbage collected when the last user
058:         * reference is relinquished.  The <code>Snapshot</code>'s
059:         * <code>dispose()</code> method
060:         * is called from <code>SnapshotProxy.finalize()</code>, ensuring that all
061:         * of the resources held by the <code>Snapshot</code> will become collectable.
062:         */
063:        final class SnapshotProxy extends PlanarImage {
064:            /**
065:             * The parent <code>Snapshot</code> to which we forward
066:             * <code>getTile()</code> calls.
067:             */
068:            Snapshot parent;
069:
070:            /**
071:             * Construct a new proxy for a given <code>Snapshot</code>.
072:             *
073:             * @param parent the <code>Snapshot</code> to which method calls will
074:             * be forwarded.
075:             */
076:            SnapshotProxy(Snapshot parent) {
077:                super (new ImageLayout(parent), null, null);
078:                this .parent = parent;
079:            }
080:
081:            /**
082:             * Forwards a tile request to the parent <code>Snapshot</code>.
083:             *
084:             * @param tileX the X index of the tile.
085:             * @param tileY the Y index of the tile.
086:             * @return the tile as a <code>Raster</code>.
087:             */
088:            public Raster getTile(int tileX, int tileY) {
089:                return parent.getTile(tileX, tileY);
090:            }
091:
092:            /** Disposes of resources held by this proxy. */
093:            public void dispose() {
094:                parent.dispose();
095:            }
096:        }
097:
098:        /**
099:         * A non-public class that holds a portion of the state associated
100:         * with a <code>SnapShotImage</code>.  A <code>Snapshot</code> provides the
101:         * appearance of a <code>PlanarImage</code> with fixed contents.  In order to
102:         * provide this illusion, however, the <code>Snapshot</code> relies on the
103:         * fact that it belongs to a linked list of <code>Snapshot</code>s rooted in a
104:         * particular <code>SnapShotImage</code>; it cannot function independently.
105:         *
106:         */
107:        final class Snapshot extends PlanarImage {
108:
109:            /** The creator of this image. */
110:            SnapshotImage parent;
111:
112:            /** The next <code>Snapshot</code> in a doubly-linked list. */
113:            Snapshot next;
114:
115:            /** The previous <code>Snapshot</code> in a doubly-linked list. */
116:            Snapshot prev;
117:
118:            /** A set of cached TileCopy elements. */
119:            Hashtable tiles = new Hashtable();
120:
121:            /** True if <code>dispose()</code> has been called. */
122:            boolean disposed = false;
123:
124:            /**
125:             * Constructs a <code>Snapshot</code> that will provide a synchronous
126:             * view of a <code>SnapshotImage</code> at a particular moment in time.
127:             *
128:             * @param parent a <code>SnapshotImage</code> this image will be viewing.
129:             */
130:            Snapshot(SnapshotImage parent) {
131:                super (new ImageLayout(parent), null, null);
132:                this .parent = parent;
133:            }
134:
135:            /**
136:             * Returns the version of a tile "seen" by this <code>Snapshot</code>.
137:             * The tile "seen" is the oldest copy of the tile made after
138:             * the creation of this <code>Snapshot</code>; it may be held in the
139:             * tiles <code>Hashtable</code> of this <code>Snapshot</code> or one of
140:             * its successors.  If no later <code>Snapshot</code> holds a copy of
141:             * the tile, the current version of the tile from the source image is
142:             * returned.
143:             *
144:             * <p> <code>getTile()</code> is synchronized in order to prevent calls to
145:             * <code>dispose()</code>, which will cause the list of
146:             * <code>Snapshot</code>s to change, from occurring at the same time as
147:             * the walking of the list.
148:             *
149:             * @param tileX the X index of the tile.
150:             * @param tileY the Y index of the tile.
151:             * @return the tile as a <code>Raster</code>.
152:             */
153:            public Raster getTile(int tileX, int tileY) {
154:                // Make sure dispose() and getTile() are mutually exclusive
155:                synchronized (parent) {
156:                    // Check local set of tile copies, if not there move
157:                    // forward to the next <code>Snapshot</code>, if last image
158:                    // get the tile from the real source image.
159:
160:                    TileCopy tc = (TileCopy) tiles.get(new Point(tileX, tileY));
161:                    if (tc != null) {
162:                        return tc.tile;
163:                    } else if (next != null) {
164:                        return next.getTile(tileX, tileY);
165:                    } else {
166:                        return parent.getTrueSource().getTile(tileX, tileY);
167:                    }
168:                }
169:            }
170:
171:            /**
172:             * Sets the next <code>Snapshot</code> in the list to a given
173:             * <code>Snapshot</code>.
174:             *
175:             * @param next the next <code>Snapshot</code> in the list.
176:             */
177:            void setNext(Snapshot next) {
178:                this .next = next;
179:            }
180:
181:            /**
182:             * Sets the previous <code>Snapshot</code> in the list to a given
183:             * <code>Snapshot</code>.
184:             *
185:             * @param prev the previous <code>Snapshot</code> in the list.
186:             */
187:            void setPrev(Snapshot prev) {
188:                this .prev = prev;
189:            }
190:
191:            /**
192:             * Returns true if this <code>Snapshot</code> already stores a version
193:             * of a specified tile.
194:             *
195:             * @param tileX the X index of the tile.
196:             * @param tileY the Y index of the tile.
197:             * @return true if this <code>Snapshot</code> holds a copy of the tile.
198:             */
199:            boolean hasTile(int tileX, int tileY) {
200:                TileCopy tc = (TileCopy) tiles.get(new Point(tileX, tileY));
201:                return tc != null;
202:            }
203:
204:            /**
205:             * Stores a given tile in this <code>Snapshot</code>.  The caller should
206:             * not attempt to store more than one version of a given tile.
207:             *
208:             * @param tile a <code>Raster</code> containing the tile data.
209:             * @param tileX the tile's column within the image tile grid.
210:             * @param tileY the tile's row within the image tile grid.
211:             */
212:            void addTile(Raster tile, int tileX, int tileY) {
213:                TileCopy tc = new TileCopy(tile, tileX, tileY);
214:                tiles.put(new Point(tileX, tileY), tc);
215:            }
216:
217:            /** This image will no longer be referenced by the user. */
218:            public void dispose() {
219:                // Make sure dispose() and getTile() are mutually exclusive
220:                synchronized (parent) {
221:                    // Make it idempotent
222:                    if (disposed) {
223:                        return;
224:                    }
225:                    disposed = true;
226:
227:                    // If this is the last Snapshot, inform the parent
228:                    if (parent.getTail() == this ) {
229:                        parent.setTail(prev);
230:                    }
231:
232:                    // Remove 'this' from the chain
233:                    if (prev != null) {
234:                        prev.setNext(next);
235:                    }
236:                    if (next != null) {
237:                        next.setPrev(prev);
238:                    }
239:
240:                    // If there is a previous node, push tiles back to it
241:                    if (prev != null) {
242:                        // Push tiles back to the previous Snapshot
243:                        Enumeration enumeration = tiles.elements();
244:                        while (enumeration.hasMoreElements()) {
245:                            TileCopy tc = (TileCopy) enumeration.nextElement();
246:                            if (!prev.hasTile(tc.tileX, tc.tileY)) {
247:                                prev.addTile(tc.tile, tc.tileX, tc.tileY);
248:                            }
249:                        }
250:                    }
251:
252:                    // Null out links to help the GC
253:                    parent = null;
254:                    next = prev = null;
255:                    tiles = null;
256:                }
257:            }
258:        }
259:
260:        /**
261:         * A class providing an arbitrary number of synchronous views of a
262:         * possibly changing <code>WritableRenderedImage</code>.
263:         * <code>SnapshotImage</code> is responsible for stabilizing changing sources
264:         * in order to allow deferred execution of operations dependent on such
265:         * sources.
266:         *
267:         * <p> Any <code>RenderedImage</code> may be used as the source of a
268:         * <code>SnapshotImage</code>; if it is a <code>WritableRenderedImage</code>,
269:         * the <code>SnapshotImage</code> will register itself as a
270:         * <code>TileObserver</code> and make copies of tiles that are about to change.
271:         * Multiple versions of each tile are maintained internally, as long as they
272:         * are in demand.  <code>SnapshotImage</code> is able to track demand and
273:         * should be able to simply forward requests for tiles to the source most
274:         * of the time, without the need to make a copy.
275:         *
276:         * <p> When used as a source, calls to getTile will simply be passed
277:         * along to the source.  In other words, <code>SnapshotImage</code> is
278:         * completely transparent.  However, by calling <code>createSnapshot()</code>
279:         * an instance of a non-public <code>PlanarImage</code> subclass (called
280:         * <code>Snapshot</code> in this implementation) will be created and returned.
281:         * This image will always return tile data with contents as of the time of its
282:         * construction.
283:         *
284:         * <p> When a particular <code>Snapshot</code> is no longer needed, its
285:         * <code>dispose()</code> method may be called.    The <code>dispose()</code>
286:         * method will be called automatically when the <code>Snapshot</code> is
287:         * finalized by the garbage collector.  Disposing of the <code>Snapshot</code>
288:         * allows tile data held by the <code>Snapshot</code> that is not needed by
289:         * any other <code>Snapshot</code> to be disposed of as well.
290:         *
291:         * <p> This implementation of <code>SnapshotImage</code> makes use of a
292:         * doubly-linked list of <code>Snapshot</code> objects.  A new
293:         * <code>Snapshot</code> is added to the tail of the list whenever
294:         * <code>createSnapshot()</code> is called.  Each <code>Snapshot</code>
295:         * has a cache containing copies of any tiles that were writable at the
296:         * time of its construction, as well as any tiles that become writable
297:         * between the time of its construction and the construction of the next
298:         * <code>Snapshot</code>.
299:         *
300:         * <p> When asked for a tile, a <code>Snapshot</code> checks its local cache
301:         * and returns its version of the tile if one is found.  Otherwise, it
302:         * forwards the request onto its successor.  This process continues
303:         * until the latest <code>Snapshot</code> is reached; if it does not contain
304:         * a copy of the tile, the tile is requested from the real source image.
305:         *
306:         * <p> When a <code>Snapshot</code> is no longer needed, its
307:         * <code>dispose()</code> method attempts to push the contents of its tile
308:         * cache back to the previous <code>Snapshot</code> in the linked list.  If
309:         * that image possesses a version of the same tile, the tile is not pushed
310:         * back and may be discarded.
311:         *
312:         * @see java.awt.image.RenderedImage
313:         * @see java.awt.image.TileObserver
314:         * @see java.awt.image.WritableRenderedImage
315:         * @see PlanarImage
316:         *
317:         */
318:        public class SnapshotImage extends PlanarImage implements  TileObserver {
319:
320:            /** The real image source. */
321:            private PlanarImage source;
322:
323:            /** The last entry in the list of <code>Snapshot</code>, initially null. */
324:            private Snapshot tail = null;
325:
326:            /** The set of active tiles, represented as a HashSet of Points. */
327:            private HashSet activeTiles = new HashSet();
328:
329:            /**
330:             * Constructs a <code>SnapshotImage</code> from a <code>PlanarImage</code>
331:             * source.
332:             *
333:             * @param source a <code>PlanarImage</code> source.
334:             * @throws IllegalArgumentException if source is null.
335:             */
336:            public SnapshotImage(PlanarImage source) {
337:                super (new ImageLayout(source), null, null);
338:
339:                // Record the source image
340:                this .source = source;
341:                //  Set image parameters to match the source
342:
343:                //  Determine which tiles of the source image are writable
344:                if (source instanceof  WritableRenderedImage) {
345:                    WritableRenderedImage wri = (WritableRenderedImage) source;
346:                    wri.addTileObserver(this );
347:
348:                    Point[] pts = wri.getWritableTileIndices();
349:                    if (pts != null) {
350:                        int num = pts.length;
351:                        for (int i = 0; i < num; i++) {
352:                            //  Add these tiles to the active list
353:                            Point p = pts[i];
354:                            activeTiles.add(new Point(p.x, p.y));
355:                        }
356:                    }
357:                }
358:            }
359:
360:            /**
361:             * Returns the <code>PlanarImage</code> source of this
362:             * <code>SnapshotImage</code>.
363:             *
364:             * @return a <code>PlanarImage</code> that is the source of data for this
365:             * image.
366:             */
367:            protected PlanarImage getTrueSource() {
368:                return source;
369:            }
370:
371:            /**
372:             * Sets the reference to the most current <code>Snapshot</code> to a given
373:             * <code>Snapshot</code>.
374:             *
375:             * @param tail a reference to the new most current <code>Snapshot</code>.
376:             */
377:            void setTail(Snapshot tail) {
378:                this .tail = tail;
379:            }
380:
381:            /**
382:             * Returns a reference to the most current <code>Snapshot</code>.
383:             *
384:             * @return the <code>Snapshot</code> at the tail end of the list.
385:             */
386:            Snapshot getTail() {
387:                return tail;
388:            }
389:
390:            /**
391:             * Creates and returns a <code>Raster</code> copy of a given source tile.
392:             *
393:             * @param tileX the X index of the tile.
394:             * @param tileY the Y index of the tile.
395:             * @return a newly-constructed <code>Raster</code> containing a copy
396:             *         of the tile data.
397:             */
398:            private Raster createTileCopy(int tileX, int tileY) {
399:                int x = tileXToX(tileX);
400:                int y = tileYToY(tileY);
401:                Point p = new Point(x, y);
402:
403:                WritableRaster tile = RasterFactory.createWritableRaster(
404:                        sampleModel, p);
405:                source.copyData(tile);
406:                return tile;
407:            }
408:
409:            /**
410:             * Creates a snapshot of this image.  This snapshot may be used
411:             * indefinitely, and will always appear to have the pixel data that
412:             * this image has currently.  The snapshot is semantically a copy
413:             * of this image but may be implemented in a more efficient manner.
414:             * Multiple snapshots taken at different times may share tiles that
415:             * have not changed, and tiles that are currently static in this
416:             * image's source do not need to be copied at all.
417:             *
418:             * @return a <code>PlanarImage</code> snapshot.
419:             */
420:            public PlanarImage createSnapshot() {
421:                if (source instanceof  WritableRenderedImage) {
422:                    // Create a new Snapshot
423:                    Snapshot snap = new Snapshot(this );
424:
425:                    // For each active tile:
426:                    Iterator iter = activeTiles.iterator();
427:                    while (iter.hasNext()) {
428:                        Point p = (Point) iter.next();
429:
430:                        // Make a copy and store it in the Snapshot
431:                        Raster tile = createTileCopy(p.x, p.y);
432:                        snap.addTile(tile, p.x, p.y);
433:                    }
434:
435:                    // Add the new Snapshot to the list of snapshots
436:                    if (tail == null) {
437:                        tail = snap;
438:                    } else {
439:                        tail.setNext(snap);
440:                        snap.setPrev(tail);
441:                        tail = snap;
442:                    }
443:
444:                    // Create a proxy and return it
445:                    return new SnapshotProxy(snap);
446:                } else {
447:                    return source;
448:                }
449:            }
450:
451:            /**
452:             * Receives the information that a tile is either about to become
453:             * writable, or is about to become no longer writable.
454:             *
455:             * @param source the <code>WritableRenderedImage</code> for which we
456:             *               are an observer.
457:             * @param tileX the X index of the tile.
458:             * @param tileY the Y index of the tile.
459:             * @param willBeWritable true if the tile is becoming writable.
460:             */
461:            public void tileUpdate(WritableRenderedImage source, int tileX,
462:                    int tileY, boolean willBeWritable) {
463:                if (willBeWritable) {
464:                    // If the last Snapshot doesn't have the tile, copy it
465:                    if ((tail != null) && (!tail.hasTile(tileX, tileY))) {
466:                        tail
467:                                .addTile(createTileCopy(tileX, tileY), tileX,
468:                                        tileY);
469:                    }
470:                    // Add the tile to the active list
471:                    activeTiles.add(new Point(tileX, tileY));
472:                } else {
473:                    // Remove the tile from the active list
474:                    activeTiles.remove(new Point(tileX, tileY));
475:                }
476:            }
477:
478:            /**
479:             * Returns a non-snapshotted tile from the source.
480:             *
481:             * @param tileX the X index of the tile.
482:             * @param tileY the Y index of the tile.
483:             * @return the tile as a <code>Raster</code>.
484:             */
485:            public Raster getTile(int tileX, int tileY) {
486:                //  Return the current source tile (X, Y)
487:                return source.getTile(tileX, tileY);
488:            }
489:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.