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


001:        /*
002:         * $RCSfile: ImageReadOpImage.java,v $
003:         *
004:         * 
005:         * Copyright (c) 2005 Sun Microsystems, Inc. All  Rights Reserved.
006:         * 
007:         * Redistribution and use in source and binary forms, with or without
008:         * modification, are permitted provided that the following conditions
009:         * are met: 
010:         * 
011:         * - Redistribution of source code must retain the above copyright 
012:         *   notice, this  list of conditions and the following disclaimer.
013:         * 
014:         * - Redistribution in binary form must reproduce the above copyright
015:         *   notice, this list of conditions and the following disclaimer in 
016:         *   the documentation and/or other materials provided with the
017:         *   distribution.
018:         * 
019:         * Neither the name of Sun Microsystems, Inc. or the names of 
020:         * contributors may be used to endorse or promote products derived 
021:         * from this software without specific prior written permission.
022:         * 
023:         * This software is provided "AS IS," without a warranty of any 
024:         * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 
025:         * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 
026:         * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
027:         * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 
028:         * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 
029:         * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
030:         * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 
031:         * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
032:         * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
033:         * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
034:         * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
035:         * POSSIBILITY OF SUCH DAMAGES. 
036:         * 
037:         * You acknowledge that this software is not designed or intended for 
038:         * use in the design, construction, operation or maintenance of any 
039:         * nuclear facility. 
040:         *
041:         * $Revision: 1.2 $
042:         * $Date: 2006/07/14 21:43:57 $
043:         * $State: Exp $
044:         */
045:        package com.sun.media.jai.imageioimpl;
046:
047:        import java.awt.Dimension;
048:        import java.awt.Point;
049:        import java.awt.Rectangle;
050:        import java.awt.image.BufferedImage;
051:        import java.awt.image.ColorModel;
052:        import java.awt.image.Raster;
053:        import java.awt.image.SampleModel;
054:        import java.awt.image.WritableRaster;
055:        import java.io.InputStream;
056:        import java.io.IOException;
057:        import java.util.Iterator;
058:        import java.util.Map;
059:        import javax.imageio.ImageReader;
060:        import javax.imageio.ImageReadParam;
061:        import javax.imageio.ImageTypeSpecifier;
062:        import javax.imageio.metadata.IIOMetadata;
063:        import javax.imageio.spi.ImageReaderSpi;
064:        import javax.imageio.stream.ImageInputStream;
065:        import javax.media.jai.ImageLayout;
066:        import javax.media.jai.OpImage;
067:        import com.sun.media.jai.operator.ImageReadDescriptor;
068:
069:        /**
070:         * Implementation of the <code>OpImage</code> of the "ImageRead" operation.
071:         */
072:        final class ImageReadOpImage extends OpImage {
073:
074:            /**
075:             * XXX For testing only.
076:             */
077:            /* XXX
078:            public static void main(String[] args) throws Throwable {
079:                java.io.File file = new java.io.File(args[0]);
080:                int imageIndex = args.length > 1 ?
081:                    Integer.valueOf(args[1]).intValue() : 0;
082:                int tileSize = args.length > 2 ?
083:                    Integer.valueOf(args[2]).intValue() : 128;
084:
085:                javax.imageio.stream.ImageInputStream stream =
086:                    new javax.imageio.stream.FileImageInputStream(file);
087:
088:                Iterator iter = javax.imageio.ImageIO.getImageReaders(stream);
089:                ImageReader imageReader = (ImageReader)iter.next();
090:                imageReader.setInput(stream,
091:                                     true, // seekForwardOnly
092:                                     false); // ignoreMetadata
093:
094:                ImageLayout layout = new ImageLayout();
095:                layout.setTileWidth(tileSize).setTileHeight(tileSize);
096:                //layout.setTileGridXOffset(42).setTileGridYOffset(7);
097:
098:                ImageReadParam param = imageReader.getDefaultReadParam();
099:                param.setSourceSubsampling(2, 2, 0, 0);
100:                param.setSourceRegion(new Rectangle(128, 0, 256, 256));
101:                param.setSourceBands(new int[] {2, 1, 0});
102:                param.setDestinationBands(new int[] {0, 1, 2});
103:
104:                OpImage image = new ImageReadOpImage(layout, // ImageLayout
105:                                                     null, // Map
106:                                                     param, // ImageReadParam
107:                                                     imageReader,
108:                                                     imageIndex,
109:                                                     true,
110:                                                     null); // streamToClose
111:
112:                System.out.println(new ImageLayout(image));
113:
114:                System.out.println("\nImage Properties:");
115:                String[] propNames = image.getPropertyNames();
116:                if(propNames != null) {
117:                    for(int i = 0; i < propNames.length; i++) {
118:                        System.out.println(i+" "+propNames[i]+" = "+
119:                                           image.getProperty(propNames[i]));
120:                    }
121:                }
122:                System.out.println("");
123:
124:                BufferedImage[] thumbnails = null;
125:                Object thumbnailProp =
126:                    image.getProperty(ImageReadDescriptor.PROPERTY_NAME_THUMBNAILS);
127:                if(thumbnailProp != java.awt.Image.UndefinedProperty) {
128:                    thumbnails = (BufferedImage[])thumbnailProp;
129:                }
130:
131:                java.awt.Frame frame =
132:                    new java.awt.Frame("ImageReadOpImage Test: "+file);
133:                if(thumbnails != null) {
134:                    frame.setLayout(new java.awt.GridLayout(1, thumbnails.length+1));
135:                }
136:
137:                frame.add(new javax.media.jai.widget.ScrollingImagePanel(image,
138:                                                                         image.getWidth(),
139:                                                                         image.getHeight()));
140:                if(thumbnails != null) {
141:                    for(int i= 0; i < thumbnails.length; i++) {
142:                        frame.add(new javax.media.jai.widget.ScrollingImagePanel(thumbnails[i],
143:                                                                                 thumbnails[i].getWidth(),
144:                                                                                 thumbnails[i].getHeight()));
145:                    }
146:                }
147:                frame.pack();
148:                frame.show();
149:            }
150:             */
151:
152:            /**
153:             * The <code>ImageReadParam</code> used in reading the image.
154:             */
155:            private ImageReadParam param;
156:
157:            /**
158:             * The <code>ImageReader</code> used to read the image.
159:             */
160:            private ImageReader reader;
161:
162:            /**
163:             * The index of the image to be read.
164:             */
165:            private int imageIndex;
166:
167:            /**
168:             * Whether thumbnails are to be read.
169:             */
170:            private boolean readThumbnails;
171:
172:            /**
173:             * Whether stream metadata have been be read.
174:             */
175:            private boolean streamMetadataRead = false;
176:
177:            /**
178:             * Whether image metadata have been be read.
179:             */
180:            private boolean imageMetadataRead = false;
181:
182:            /**
183:             * A stream to be closed when the instance is disposed; may be null.
184:             */
185:            private ImageInputStream streamToClose;
186:
187:            /**
188:             * Destination to source X scale factor.
189:             */
190:            private int scaleX;
191:
192:            /**
193:             * Destination to source Y scale factor.
194:             */
195:            private int scaleY;
196:
197:            /**
198:             * Destination to source X translation factor.
199:             */
200:            private int transX;
201:
202:            /**
203:             * Destination to source Y translation factor.
204:             */
205:            private int transY;
206:
207:            /**
208:             * Derive the image layout based on the user-supplied layout,
209:             * reading parameters, and image index.
210:             */
211:            private static ImageLayout layoutHelper(ImageLayout il,
212:                    ImageReadParam param, ImageReader reader, int imageIndex)
213:                    throws IOException {
214:                ImageLayout layout = (il == null) ? new ImageLayout()
215:                        : (ImageLayout) il.clone();
216:
217:                // --- Determine the image type. ---
218:
219:                // If not provided in the original layout, set the SampleModel
220:                // and ColorModel from the ImageReadParam, if supplied.
221:                if (!layout.isValid(ImageLayout.SAMPLE_MODEL_MASK)
222:                        && !layout.isValid(ImageLayout.COLOR_MODEL_MASK)) {
223:                    // If an ImageReadParam has been supplied and has its
224:                    // destinationType set then use it. Otherwise default to
225:                    // the raw image type.
226:                    ImageTypeSpecifier imageType = (param != null && param
227:                            .getDestinationType() != null) ? param
228:                            .getDestinationType() : reader
229:                            .getRawImageType(imageIndex);
230:
231:                    // XXX The following block of code should not be necessary
232:                    // but for J2SE 1.4.0 FCS ImageReader.getRawImageType(0)
233:                    // returns null for earth.jpg, Bas-noir.jpg, etc.
234:                    if (imageType == null) {
235:                        Iterator imageTypes = reader.getImageTypes(imageIndex);
236:                        while (imageType == null && imageTypes.hasNext()) {
237:                            imageType = (ImageTypeSpecifier) imageTypes.next();
238:                        }
239:                    }
240:
241:                    // XXX Should an exception be thrown if imageType is null?
242:                    if (imageType != null) {
243:                        // Set the SampleModel and ColorModel.
244:                        layout.setSampleModel(imageType.getSampleModel());
245:                        layout.setColorModel(imageType.getColorModel());
246:                    }
247:                }
248:
249:                // --- Set up the destination bounds. ---
250:
251:                // Calculate the computable destination bounds.
252:                Dimension sourceSize = getSourceSize(param, reader, imageIndex);
253:                Rectangle srcRegion = new Rectangle();
254:                Rectangle destRegion = new Rectangle();
255:                computeRegions(param, sourceSize.width, sourceSize.height,
256:                        layout.getMinX(null), // valid value or 0
257:                        layout.getMinY(null), // valid value or 0
258:                        false, srcRegion, destRegion);
259:
260:                if (!destRegion.isEmpty()) {
261:                    // Backup layout image bounds with computable bounds.
262:                    if (!layout.isValid(ImageLayout.WIDTH_MASK)) {
263:                        layout.setWidth(destRegion.width);
264:                    }
265:                    if (!layout.isValid(ImageLayout.HEIGHT_MASK)) {
266:                        layout.setHeight(destRegion.height);
267:                    }
268:                    if (!layout.isValid(ImageLayout.MIN_X_MASK)) {
269:                        layout.setMinX(destRegion.x);
270:                    }
271:                    if (!layout.isValid(ImageLayout.MIN_Y_MASK)) {
272:                        layout.setMinY(destRegion.y);
273:                    }
274:
275:                    // Ensure the layout bounds intersect computable bounds.
276:                    Rectangle destBounds = new Rectangle(layout.getMinX(null),
277:                            layout.getMinY(null), layout.getWidth(null), layout
278:                                    .getHeight(null));
279:                    if (destRegion.intersection(destBounds).isEmpty()) {
280:                        throw new IllegalArgumentException(I18N
281:                                .getString("ImageReadOpImage0"));
282:                    }
283:                }
284:
285:                // --- Set up the tile grid. ---
286:
287:                if (!layout.isValid(ImageLayout.TILE_GRID_X_OFFSET_MASK)) {
288:                    layout.setTileGridXOffset(reader
289:                            .getTileGridXOffset(imageIndex));
290:                }
291:                if (!layout.isValid(ImageLayout.TILE_GRID_Y_OFFSET_MASK)) {
292:                    layout.setTileGridYOffset(reader
293:                            .getTileGridYOffset(imageIndex));
294:                }
295:                if (!layout.isValid(ImageLayout.TILE_WIDTH_MASK)) {
296:                    layout.setTileWidth(reader.getTileWidth(imageIndex));
297:                }
298:                if (!layout.isValid(ImageLayout.TILE_HEIGHT_MASK)) {
299:                    layout.setTileHeight(reader.getTileHeight(imageIndex));
300:                }
301:
302:                return layout;
303:            }
304:
305:            /**
306:             * Returns whether an <code>ImageTypeSpecifier</code> may be used
307:             * to read in the image at a specified index.
308:             *
309:             * XXX
310:             */
311:            private static boolean isCompatibleType(
312:                    ImageTypeSpecifier imageType, ImageReader reader,
313:                    int imageIndex) throws IOException {
314:                Iterator imageTypes = reader.getImageTypes(imageIndex);
315:
316:                boolean foundIt = false;
317:                while (imageTypes.hasNext()) {
318:                    ImageTypeSpecifier type = (ImageTypeSpecifier) imageTypes
319:                            .next();
320:                    if (type.equals(imageType)) {
321:                        foundIt = true;
322:                        break;
323:                    }
324:                }
325:
326:                return foundIt;
327:            }
328:
329:            /**
330:             * Returns the source region to be read. If the sourceRenderSize
331:             * is being used it is returned; otherwise the raw source dimensions
332:             * are returned.
333:             *
334:             * XXX
335:             */
336:            private static Dimension getSourceSize(ImageReadParam param,
337:                    ImageReader reader, int imageIndex) throws IOException {
338:                Dimension sourceSize = null;
339:                if (param != null && param.canSetSourceRenderSize()) {
340:                    sourceSize = param.getSourceRenderSize();
341:                }
342:                if (sourceSize == null) {
343:                    sourceSize = new Dimension(reader.getWidth(imageIndex),
344:                            reader.getHeight(imageIndex));
345:                }
346:                return sourceSize;
347:            }
348:
349:            /**
350:             * XXX
351:             */
352:            // Code copied from ImageReader.java
353:            private static Rectangle getSourceRegion(ImageReadParam param,
354:                    int srcWidth, int srcHeight) {
355:                Rectangle sourceRegion = new Rectangle(0, 0, srcWidth,
356:                        srcHeight);
357:                if (param != null) {
358:                    Rectangle region = param.getSourceRegion();
359:                    if (region != null) {
360:                        sourceRegion = sourceRegion.intersection(region);
361:                    }
362:
363:                    int subsampleXOffset = param.getSubsamplingXOffset();
364:                    int subsampleYOffset = param.getSubsamplingYOffset();
365:                    sourceRegion.x += subsampleXOffset;
366:                    sourceRegion.y += subsampleYOffset;
367:                    sourceRegion.width -= subsampleXOffset;
368:                    sourceRegion.height -= subsampleYOffset;
369:                }
370:
371:                return sourceRegion;
372:            }
373:
374:            /**
375:             * XXX
376:             */
377:            // clipDestRegion: whether to clip destRegion to positive coordinates.
378:            // Code based on method of same name in ImageReader.java
379:            private static void computeRegions(ImageReadParam param,
380:                    int srcWidth, int srcHeight, int destMinX, int destMinY,
381:                    boolean clipDestRegion, Rectangle srcRegion,
382:                    Rectangle destRegion) {
383:                if (srcRegion == null) {
384:                    throw new IllegalArgumentException("srcRegion == null");
385:                }
386:                if (destRegion == null) {
387:                    throw new IllegalArgumentException("destRegion == null");
388:                }
389:
390:                // Start with the entire source image
391:                srcRegion.setBounds(0, 0, srcWidth, srcHeight);
392:
393:                // Destination also starts with source image, as that is the
394:                // maximum extent if there is no subsampling
395:                destRegion.setBounds(destMinX, destMinY, srcWidth, srcHeight);
396:
397:                // Clip that to the param region, if there is one
398:                int periodX = 1;
399:                int periodY = 1;
400:                int gridX = 0;
401:                int gridY = 0;
402:                if (param != null) {
403:                    Rectangle paramSrcRegion = param.getSourceRegion();
404:                    if (paramSrcRegion != null) {
405:                        srcRegion.setBounds(srcRegion
406:                                .intersection(paramSrcRegion));
407:                    }
408:                    periodX = param.getSourceXSubsampling();
409:                    periodY = param.getSourceYSubsampling();
410:                    gridX = param.getSubsamplingXOffset();
411:                    gridY = param.getSubsamplingYOffset();
412:                    srcRegion.translate(gridX, gridY);
413:                    srcRegion.width -= gridX;
414:                    srcRegion.height -= gridY;
415:                    Point destinationOffset = param.getDestinationOffset();
416:                    destRegion.translate(destinationOffset.x,
417:                            destinationOffset.y);
418:                }
419:
420:                if (clipDestRegion) {
421:                    // Now clip any negative destination offsets, i.e. clip
422:                    // to the top and left of the destination image
423:                    if (destRegion.x < 0) {
424:                        int delta = -destRegion.x * periodX;
425:                        srcRegion.x += delta;
426:                        srcRegion.width -= delta;
427:                        destRegion.x = 0;
428:                    }
429:                    if (destRegion.y < 0) {
430:                        int delta = -destRegion.y * periodY;
431:                        srcRegion.y += delta;
432:                        srcRegion.height -= delta;
433:                        destRegion.y = 0;
434:                    }
435:                }
436:
437:                // Now clip the destination Region to the subsampled width and height
438:                int subsampledWidth = (srcRegion.width + periodX - 1) / periodX;
439:                int subsampledHeight = (srcRegion.height + periodY - 1)
440:                        / periodY;
441:                destRegion.width = subsampledWidth;
442:                destRegion.height = subsampledHeight;
443:
444:                if (srcRegion.isEmpty() || destRegion.isEmpty()) {
445:                    throw new IllegalArgumentException(I18N
446:                            .getString("ImageReadOpImage1"));
447:                }
448:            }
449:
450:            /**
451:             * XXX
452:             * NB: This class may reset the following fields of the ImageReadParam
453:             *     destinationOffset
454:             *     destinationType
455:             *     sourceRegion
456:             */
457:            ImageReadOpImage(ImageLayout layout, Map configuration,
458:                    ImageReadParam param, ImageReader reader, int imageIndex,
459:                    boolean readThumbnails, ImageInputStream streamToClose)
460:                    throws IOException {
461:                super (null, layoutHelper(layout, param, reader, imageIndex),
462:                        configuration, false);
463:
464:                // Revise parameter 'param' as needed.
465:                if (param == null) {
466:                    // Get the ImageReadParam from the ImageReader.
467:                    param = reader.getDefaultReadParam();
468:                } else if (param instanceof  Cloneable) {
469:                    this .param = param;
470:                } else if (param.getClass().getName().equals(
471:                        "javax.imageio.ImageReadParam")) {
472:                    // The ImageReadParam passed in is non-null. As the
473:                    // ImageReadParam class is not Cloneable, if the param
474:                    // class is simply ImageReadParam, then create a new
475:                    // ImageReadParam instance and set all its fields
476:                    // which were set in param. This will eliminate problems
477:                    // with concurrent modification of param for the cases
478:                    // in which there is not a special ImageReadparam used.
479:
480:                    // Create a new ImageReadParam instance.
481:                    ImageReadParam newParam = new ImageReadParam();
482:
483:                    // Set all fields which need to be set.
484:
485:                    // IIOParamController field.
486:                    if (param.hasController()) {
487:                        newParam.setController(param.getController());
488:                    }
489:
490:                    // Destination fields.
491:                    newParam.setDestination(param.getDestination());
492:                    if (param.getDestinationType() != null) {
493:                        // Set the destination type only if non-null as the
494:                        // setDestinationType() clears the destination field.
495:                        newParam.setDestinationType(param.getDestinationType());
496:                    }
497:                    newParam.setDestinationBands(param.getDestinationBands());
498:                    newParam.setDestinationOffset(param.getDestinationOffset());
499:
500:                    // Source fields.
501:                    newParam.setSourceBands(param.getSourceBands());
502:                    newParam.setSourceRegion(param.getSourceRegion());
503:                    if (param.getSourceMaxProgressivePass() != Integer.MAX_VALUE) {
504:                        newParam.setSourceProgressivePasses(param
505:                                .getSourceMinProgressivePass(), param
506:                                .getSourceNumProgressivePasses());
507:                    }
508:                    if (param.canSetSourceRenderSize()) {
509:                        newParam.setSourceRenderSize(param
510:                                .getSourceRenderSize());
511:                    }
512:                    newParam.setSourceSubsampling(
513:                            param.getSourceXSubsampling(), param
514:                                    .getSourceYSubsampling(), param
515:                                    .getSubsamplingXOffset(), param
516:                                    .getSubsamplingYOffset());
517:
518:                    // Replace the local variable with the new ImageReadParam.
519:                    param = newParam;
520:                }
521:
522:                // Revise parameter 'readThumbnails' as needed.
523:                if (readThumbnails && !reader.hasThumbnails(imageIndex)) {
524:                    // Unset thumbnail flag if not supported by ImageReader.
525:                    readThumbnails = false;
526:                }
527:
528:                // Set instance variables from (possibly revised) parameters.
529:                this .param = param;
530:                this .reader = reader;
531:                this .imageIndex = imageIndex;
532:                this .readThumbnails = readThumbnails;
533:                this .streamToClose = streamToClose;
534:
535:                // If an ImageTypeSpecifier is specified in the ImageReadParam
536:                // but it is incompatible with the ImageReader, then attempt to
537:                // replace it with a compatible one derived from this image.
538:                if (param.getDestinationType() != null
539:                        && !isCompatibleType(param.getDestinationType(),
540:                                reader, imageIndex) && sampleModel != null
541:                        && colorModel != null) {
542:                    ImageTypeSpecifier newImageType = new ImageTypeSpecifier(
543:                            colorModel, sampleModel);
544:                    if (isCompatibleType(newImageType, reader, imageIndex)) {
545:                        param.setDestinationType(newImageType);
546:                    }
547:                }
548:
549:                // --- Compute the destination to source mapping coefficients. ---
550:
551:                Dimension sourceSize = getSourceSize(param, reader, imageIndex);
552:
553:                Rectangle srcRegion = getSourceRegion(param, sourceSize.width,
554:                        sourceSize.height);
555:
556:                Point destinationOffset = this .param.getDestinationOffset();
557:
558:                this .scaleX = this .param.getSourceXSubsampling();
559:                this .scaleY = this .param.getSourceYSubsampling();
560:                this .transX = srcRegion.x + this .param.getSubsamplingXOffset()
561:                        - this .param.getSourceXSubsampling()
562:                        * (minX + destinationOffset.x);
563:                this .transY = srcRegion.y + this .param.getSubsamplingYOffset()
564:                        - this .param.getSourceYSubsampling()
565:                        * (minY + destinationOffset.y);
566:
567:                // Replace the original destination offset with (0,0) as the
568:                // destination-to-source mapping assimilates this value.
569:                this .param.setDestinationOffset(new Point());
570:                // XXX Need to unset other ImageReadParam settings either here
571:                // or in computeTile(). Examine this issue taking into account
572:                // synchronization.
573:
574:                // Set the ImageReadParam property.
575:                setProperty(ImageReadDescriptor.PROPERTY_NAME_IMAGE_READ_PARAM,
576:                        param);
577:
578:                // Set the ImageReader property.
579:                setProperty(ImageReadDescriptor.PROPERTY_NAME_IMAGE_READER,
580:                        reader);
581:
582:                // If metadata are being read, set the value of the metadata
583:                // properties to UndefinedProperty so that the property
584:                // names will appear in the array of property names. The actual
585:                // values will be retrieved when getProperty() is invoked.
586:                if (!reader.isIgnoringMetadata()) {
587:                    // Get the service provider interface, if any.
588:                    ImageReaderSpi provider = reader.getOriginatingProvider();
589:
590:                    // Stream metadata.
591:                    if (provider == null
592:                            || provider
593:                                    .isStandardStreamMetadataFormatSupported()
594:                            || provider.getNativeStreamMetadataFormatName() != null) {
595:                        // Assume an ImageReader with a null provider supports
596:                        // stream metadata.
597:                        setProperty(
598:                                ImageReadDescriptor.PROPERTY_NAME_METADATA_STREAM,
599:                                java.awt.Image.UndefinedProperty);
600:                    } else {
601:                        // Provider supports neither standard nor native stream
602:                        // metadata so set flag to suppress later reading attempt.
603:                        streamMetadataRead = true;
604:                    }
605:
606:                    // Image metadata.
607:                    if (provider == null
608:                            || provider
609:                                    .isStandardImageMetadataFormatSupported()
610:                            || provider.getNativeImageMetadataFormatName() != null) {
611:                        // Assume an ImageReader with a null provider supports
612:                        // image metadata.
613:                        setProperty(
614:                                ImageReadDescriptor.PROPERTY_NAME_METADATA_IMAGE,
615:                                java.awt.Image.UndefinedProperty);
616:                    } else {
617:                        // Provider supports neither standard nor native image
618:                        // metadata so set flag to suppress later reading attempt.
619:                        imageMetadataRead = true;
620:                    }
621:                }
622:
623:                // If thumbnail read flag is set, set the value of the thumbnail
624:                // property to UndefinedProperty so that the thumbnail property
625:                // name will appear in the array of property names. The actual
626:                // value will be retrieved when getProperty() is invoked.
627:                if (readThumbnails && reader.readerSupportsThumbnails()) {
628:                    setProperty(ImageReadDescriptor.PROPERTY_NAME_THUMBNAILS,
629:                            java.awt.Image.UndefinedProperty);
630:                }
631:            }
632:
633:            /**
634:             * Returns false as ImageReaders might return Rasters
635:             * via computeTile() tile that are internally cached.
636:             */
637:            public boolean computesUniqueTiles() {
638:                return false;
639:            }
640:
641:            /**
642:             * XXX
643:             */
644:            private Rectangle computeSourceRect(Rectangle destRect) {
645:                Rectangle sourceRect = new Rectangle();
646:
647:                sourceRect.x = scaleX * destRect.x + transX;
648:                sourceRect.y = scaleY * destRect.y + transY;
649:
650:                sourceRect.width = scaleX * (destRect.x + destRect.width)
651:                        + transX - sourceRect.x;
652:                sourceRect.height = scaleY * (destRect.y + destRect.height)
653:                        + transY - sourceRect.y;
654:
655:                return sourceRect;
656:            }
657:
658:            /**
659:             * Computes a tile.
660:             *
661:             * @param tileX The X index of the tile.
662:             * @param tileY The Y index of the tile.
663:             */
664:            public Raster computeTile(int tileX, int tileY) {
665:                //XXX System.out.println("Tile ("+tileX+","+tileY+")");
666:                // Create a new WritableRaster to represent this tile.
667:                Point org = new Point(tileXToX(tileX), tileYToY(tileY));
668:                //WritableRaster dest = Raster.createWritableRaster(sampleModel, org);
669:                Rectangle rect = new Rectangle(org.x, org.y, tileWidth,
670:                        tileHeight);
671:
672:                // Clip output rectangle to image bounds.
673:                // Not sure what will happen here with the bounds intersection.
674:                Rectangle destRect = rect.intersection(getBounds());
675:                // XXX Check for destRect.isEmpty()?
676:
677:                /* XXX delete
678:                java.awt.geom.AffineTransform transform =
679:                    new java.awt.geom.AffineTransform(scaleX, 0, 0, scaleY,
680:                                                      transX, transY);
681:                 */
682:                Rectangle srcRect = computeSourceRect(destRect);
683:                /* XXX delete
684:                transform.createTransformedShape(destRect).getBounds();
685:                 */
686:
687:                WritableRaster readerTile = null;
688:                try {
689:                    synchronized (reader) {
690:                        param.setSourceRegion(srcRect);
691:                        BufferedImage bi = reader.read(imageIndex, param);
692:                        WritableRaster ras = bi.getRaster();
693:                        readerTile = ras.createWritableChild(0, 0, ras
694:                                .getWidth(), ras.getHeight(), org.x, org.y,
695:                                null);
696:                    }
697:                } catch (IOException e) {
698:                    throw new RuntimeException(e);
699:                }
700:
701:                WritableRaster tile = null;
702:                if (sampleModel == readerTile.getSampleModel()) {
703:                    tile = readerTile;
704:                } else {
705:                    // XXX As this method is synchronized, could a single
706:                    // destination be supplied to the reader instead of
707:                    // creating a new one?
708:                    tile = Raster.createWritableRaster(sampleModel, org);
709:                    tile.setRect(readerTile);
710:                }
711:
712:                return tile;
713:            }
714:
715:            /**
716:             * Throws an IllegalArgumentException since the image has no image
717:             * sources.
718:             *
719:             * @param sourceRect ignored.
720:             * @param sourceIndex ignored.
721:             *
722:             * @throws IllegalArgumentException since the image has no sources.
723:             */
724:            public Rectangle mapSourceRect(Rectangle sourceRect, int sourceIndex) {
725:                throw new IllegalArgumentException(I18N
726:                        .getString("ImageReadOpImage2"));
727:            }
728:
729:            /**
730:             * Throws an IllegalArgumentException since the image has no image
731:             * sources.
732:             *
733:             * @param destRect ignored.
734:             * @param sourceIndex ignored.
735:             *
736:             * @throws IllegalArgumentException since the image has no sources.
737:             */
738:            public Rectangle mapDestRect(Rectangle destRect, int sourceIndex) {
739:                throw new IllegalArgumentException(I18N
740:                        .getString("ImageReadOpImage2"));
741:            }
742:
743:            /**
744:             * Gets a property from the property set of this image.  If the
745:             * property name is not recognized,
746:             * <code>java.awt.Image.UndefinedProperty</code> will be returned.
747:             *
748:             * <p>This implementation first attempts to retrieve the property
749:             * using the equivalent superclass method.  If the returned value
750:             * is not a valid property value, the requested property name is
751:             * that of the image thumbnails property, the stream metadata
752:             * property, or the image metadata property, and there has been no
753:             * prior attempt to read the corresponding property value, then its
754:             * reads the value and set the property.  This implementation therefore
755:             * defers reading of the image thumbnails, stream metadata, and image
756:             * metadata values until the correpsonding property is actually
757:             * requested.</p>
758:             *
759:             * @param name the name of the property to get, as a <code>String</code>.
760:             *
761:             * @return A reference to the property <code>Object</code>, or the value
762:             *         <code>java.awt.Image.UndefinedProperty</code>.
763:             *
764:             * @exception IllegalArgumentException if <code>propertyName</code>
765:             *                                     is <code>null</code>.
766:             */
767:            public Object getProperty(String name) {
768:                // Attempt to get property from superclass method.
769:                Object property = super .getProperty(name);
770:
771:                // If thumbnail property name with undefined value and thumbnails
772:                // are being read and an attempt to read them has not already been
773:                // made, then read the thumbnails and set the property.
774:                if ((property == null || property == java.awt.Image.UndefinedProperty)) {
775:
776:                    // Thumbnails
777:                    if (readThumbnails
778:                            && name
779:                                    .equalsIgnoreCase(ImageReadDescriptor.PROPERTY_NAME_THUMBNAILS)) {
780:
781:                        // Lock the class to avoid a race condition here
782:                        // and with computeTile().
783:                        synchronized (reader) {
784:                            // First re-check the flag in case another thread
785:                            // got here first.
786:                            if (readThumbnails) {
787:                                try {
788:                                    // Get number of thumbnails.
789:                                    int numThumbnails = reader
790:                                            .getNumThumbnails(imageIndex);
791:
792:                                    if (numThumbnails > 0) {
793:                                        // Read all thumbnails.
794:                                        BufferedImage[] thumbnails = new BufferedImage[numThumbnails];
795:                                        for (int i = 0; i < numThumbnails; i++) {
796:                                            thumbnails[i] = reader
797:                                                    .readThumbnail(imageIndex,
798:                                                            i);
799:                                        }
800:
801:                                        // Set thumbnail property.
802:                                        setProperty(
803:                                                ImageReadDescriptor.PROPERTY_NAME_THUMBNAILS,
804:                                                thumbnails);
805:
806:                                        // Update return value.
807:                                        property = thumbnails;
808:                                    }
809:                                } catch (IOException e) {
810:                                    throw new RuntimeException(e);
811:                                } finally {
812:                                    // If return value is somehow null set it
813:                                    // to UndefinedProperty.
814:                                    if (property == null) {
815:                                        property = java.awt.Image.UndefinedProperty;
816:                                    }
817:
818:                                    // Unset thumbnail flag to avert subsequent
819:                                    // reading attempts in case this one failed.
820:                                    readThumbnails = false;
821:                                }
822:                            }
823:                        }
824:                    } else if (!reader.isIgnoringMetadata()
825:                            && ((!streamMetadataRead && name
826:                                    .equalsIgnoreCase(ImageReadDescriptor.PROPERTY_NAME_METADATA_STREAM)) || (!imageMetadataRead && name
827:                                    .equalsIgnoreCase(ImageReadDescriptor.PROPERTY_NAME_METADATA_IMAGE)))) {
828:
829:                        // Lock the class to avoid a race condition here
830:                        // and with computeTile().
831:                        synchronized (reader) {
832:
833:                            // Set flag to indicate stream or image metadata.
834:                            boolean isStreamMetadata = name
835:                                    .equalsIgnoreCase(ImageReadDescriptor.PROPERTY_NAME_METADATA_STREAM);
836:
837:                            // Recheck the appropriate flag.
838:                            if (!(isStreamMetadata ? streamMetadataRead
839:                                    : imageMetadataRead)) {
840:
841:                                // Set property name.
842:                                String propertyName = isStreamMetadata ? ImageReadDescriptor.PROPERTY_NAME_METADATA_STREAM
843:                                        : ImageReadDescriptor.PROPERTY_NAME_METADATA_IMAGE;
844:
845:                                IIOMetadata metadata = null;
846:                                try {
847:                                    // Read metadata.
848:                                    metadata = isStreamMetadata ? reader
849:                                            .getStreamMetadata() : reader
850:                                            .getImageMetadata(imageIndex);
851:
852:                                    // Set metadata property.
853:                                    if (metadata != null) {
854:                                        setProperty(propertyName, metadata);
855:                                    }
856:
857:                                    // Update return value.
858:                                    property = metadata;
859:                                } catch (IOException e) {
860:                                    throw new RuntimeException(e);
861:                                } finally {
862:                                    // If return value is somehow null set it
863:                                    // to UndefinedProperty.
864:                                    if (property == null) {
865:                                        property = java.awt.Image.UndefinedProperty;
866:                                    }
867:
868:                                    // Set appropriate flag to avert subsequent
869:                                    // reading attempts in case this one failed.
870:                                    if (isStreamMetadata) {
871:                                        streamMetadataRead = true;
872:                                    } else {
873:                                        imageMetadataRead = true;
874:                                    }
875:                                }
876:                            }
877:                        }
878:                    }
879:                }
880:
881:                return property;
882:            }
883:
884:            /**
885:             * Closes an <code>ImageInputStream</code> passed in, if any.
886:             */
887:            public void dispose() {
888:                if (streamToClose != null) {
889:                    try {
890:                        streamToClose.close();
891:                    } catch (IOException e) {
892:                        // Ignore it.
893:                    }
894:                }
895:
896:                super.dispose();
897:            }
898:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.