Source Code Cross Referenced for GeographicImageWriter.java in  » GIS » GeoTools-2.4.1 » org » geotools » image » io » 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 » GIS » GeoTools 2.4.1 » org.geotools.image.io 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2003-2006, Geotools Project Managment Committee (PMC)
005:         *    (C) 2001, Institut de Recherche pour le Développement
006:         *
007:         *    This library is free software; you can redistribute it and/or
008:         *    modify it under the terms of the GNU Lesser General Public
009:         *    License as published by the Free Software Foundation; either
010:         *    version 2.1 of the License, or (at your option) any later version.
011:         *
012:         *    This library is distributed in the hope that it will be useful,
013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         *    Lesser General Public License for more details.
016:         */
017:        package org.geotools.image.io;
018:
019:        import java.awt.Rectangle;
020:        import java.awt.image.Raster;
021:        import java.awt.image.RenderedImage;
022:        import java.io.IOException;
023:        import java.util.logging.Level;
024:        import java.util.logging.Logger;
025:        import java.util.logging.LogRecord;
026:        import javax.imageio.IIOImage;
027:        import javax.imageio.ImageWriter;
028:        import javax.imageio.ImageWriteParam;
029:        import javax.imageio.ImageTypeSpecifier;
030:        import javax.imageio.spi.ImageWriterSpi;
031:        import javax.imageio.metadata.IIOMetadata;
032:        import javax.imageio.metadata.IIOMetadataFormatImpl;
033:        import javax.imageio.metadata.IIOInvalidTreeException;
034:        import javax.imageio.event.IIOWriteWarningListener;
035:        import javax.media.jai.iterator.RectIter;
036:        import javax.media.jai.iterator.RectIterFactory;
037:
038:        import org.geotools.image.ImageDimension;
039:        import org.geotools.util.logging.Logging;
040:        import org.geotools.resources.i18n.Locales;
041:        import org.geotools.resources.i18n.Errors;
042:        import org.geotools.resources.i18n.ErrorKeys;
043:        import org.geotools.resources.IndexedResourceBundle;
044:
045:        /**
046:         * Base class for writers of geographic images.
047:         *
048:         * @since 2.4
049:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/coverageio/src/main/java/org/geotools/image/io/GeographicImageWriter.java $
050:         * @version $Id: GeographicImageWriter.java 27862 2007-11-12 19:51:19Z desruisseaux $
051:         * @author Martin Desruisseaux
052:         */
053:        public abstract class GeographicImageWriter extends ImageWriter {
054:            /**
055:             * The logger to use for events related to this image writer.
056:             */
057:            static final Logger LOGGER = Logging
058:                    .getLogger("org.geotools.image.io");
059:
060:            /**
061:             * Index of the image in process of being written. This convenience index is reset to 0
062:             * by {@link #close} method.
063:             */
064:            private int imageIndex = 0;
065:
066:            /**
067:             * Index of the ithumbnail in process of being written. This convenience index
068:             * is reset to 0 by {@link #close} method.
069:             */
070:            private int thumbnailIndex = 0;
071:
072:            /**
073:             * Constructs a {@code GeographicImageWriter}.
074:             *
075:             * @param originatingProvider The {@code ImageWriterSpi} that
076:             *        is constructing this object, or {@code null}.
077:             */
078:            protected GeographicImageWriter(final ImageWriterSpi provider) {
079:                super (provider);
080:                availableLocales = Locales.getAvailableLocales();
081:            }
082:
083:            /**
084:             * Sets the output.
085:             */
086:            //@Override
087:            public void setOutput(final Object output) {
088:                imageIndex = 0;
089:                thumbnailIndex = 0;
090:                super .setOutput(output);
091:            }
092:
093:            /**
094:             * Returns the resources for formatting error messages.
095:             */
096:            final IndexedResourceBundle getErrorResources() {
097:                return Errors.getResources(getLocale());
098:            }
099:
100:            /**
101:             * Ensures that the specified parameter is non-null.
102:             *
103:             * @param  parameter The parameter name, for formatting an error message if needed.
104:             * @param  value The value to test.
105:             * @throws IllegalArgumentException if {@code value} is null.
106:             */
107:            private void ensureNonNull(final String parameter,
108:                    final Object value) throws IllegalArgumentException {
109:                if (value == null) {
110:                    throw new IllegalArgumentException(getErrorResources()
111:                            .getString(ErrorKeys.NULL_ARGUMENT_$1, parameter));
112:                }
113:            }
114:
115:            /**
116:             * Returns a metadata object containing default values for encoding a stream of images.
117:             * The default implementation returns {@code null}, which is appropriate for writer that
118:             * do not make use of stream meta-data.
119:             *
120:             * @param param Parameters that will be used to encode the image (in cases where
121:             *              it may affect the structure of the metadata), or {@code null}.
122:             * @return The metadata, or {@code null}.
123:             */
124:            public IIOMetadata getDefaultStreamMetadata(
125:                    final ImageWriteParam param) {
126:                return null;
127:            }
128:
129:            /**
130:             * Returns a metadata object containing default values for encoding an image of the given
131:             * type. The default implementation returns {@code null}, which is appropriate for writer
132:             * that do not make use of image meta-data.
133:             *
134:             * @param imageType The format of the image to be written later.
135:             * @param param Parameters that will be used to encode the image (in cases where
136:             *              it may affect the structure of the metadata), or {@code null}.
137:             * @return The metadata, or {@code null}.
138:             */
139:            public IIOMetadata getDefaultImageMetadata(
140:                    final ImageTypeSpecifier imageType,
141:                    final ImageWriteParam param) {
142:                return null;
143:            }
144:
145:            /**
146:             * Returns a metadata object initialized to the specified data for encoding a stream
147:             * of images. The default implementation copies the specified data into a
148:             * {@linkplain #getDefaultStreamMetadata default stream metadata}.
149:             *
150:             * @param inData Stream metadata used to initialize the state of the returned object.
151:             * @param param Parameters that will be used to encode the image (in cases where
152:             *              it may affect the structure of the metadata), or {@code null}.
153:             * @return The metadata, or {@code null}.
154:             */
155:            public IIOMetadata convertStreamMetadata(final IIOMetadata inData,
156:                    final ImageWriteParam param) {
157:                ensureNonNull("inData", inData);
158:                final IIOMetadata outData = getDefaultStreamMetadata(param);
159:                final String format = commonMetadataFormatName(inData, outData);
160:                if (format != null)
161:                    try {
162:                        outData.mergeTree(format, inData.getAsTree(format));
163:                        return outData;
164:                    } catch (IIOInvalidTreeException ex) {
165:                        warningOccurred("convertStreamMetadata", ex);
166:                    }
167:                return null;
168:            }
169:
170:            /**
171:             * Returns a metadata object initialized to the specified data for encoding an image
172:             * of the given type. The default implementation copies the specified data into a
173:             * {@linkplain #getDefaultImageMetadata default image metadata}.
174:             *
175:             * @param inData Image metadata used to initialize the state of the returned object.
176:             * @param imageType The format of the image to be written later.
177:             * @param param Parameters that will be used to encode the image (in cases where
178:             *              it may affect the structure of the metadata), or {@code null}.
179:             * @return The metadata, or {@code null}.
180:             */
181:            public IIOMetadata convertImageMetadata(final IIOMetadata inData,
182:                    final ImageTypeSpecifier imageType,
183:                    final ImageWriteParam param) {
184:                ensureNonNull("inData", inData);
185:                final IIOMetadata outData = getDefaultImageMetadata(imageType,
186:                        param);
187:                final String format = commonMetadataFormatName(inData, outData);
188:                if (format != null)
189:                    try {
190:                        outData.mergeTree(format, inData.getAsTree(format));
191:                        return outData;
192:                    } catch (IIOInvalidTreeException ex) {
193:                        warningOccurred("convertImageMetadata", ex);
194:                    }
195:                return null;
196:            }
197:
198:            /**
199:             * Finds a common metadata format name between the two specified metadata objects. This
200:             * method query for the {@code outData} {@linkplain #getNativeMetadataFormatName native
201:             * metadata format name} first.
202:             *
203:             * @param  inData  The input metadata.
204:             * @param  outData The output metadata.
205:             * @return A metadata format name common to {@code inData} and {@code outData},
206:             *         or {@code null} if none where found.
207:             */
208:            private static String commonMetadataFormatName(
209:                    final IIOMetadata inData, final IIOMetadata outData) {
210:                String format = outData.getNativeMetadataFormatName();
211:                if (isSupportedFormat(inData, format)) {
212:                    return format;
213:                }
214:                final String[] formats = outData.getExtraMetadataFormatNames();
215:                if (formats != null) {
216:                    for (int i = 0; i < formats.length; i++) {
217:                        format = formats[i];
218:                        if (isSupportedFormat(inData, format)) {
219:                            return format;
220:                        }
221:                    }
222:                }
223:                if (outData.isStandardMetadataFormatSupported()
224:                        && inData.isStandardMetadataFormatSupported()) {
225:                    return IIOMetadataFormatImpl.standardMetadataFormatName;
226:                }
227:                return null;
228:            }
229:
230:            /**
231:             * Returns {@code true} if the specified metadata supports the specified format.
232:             *
233:             * @param  metadata The metadata to test.
234:             * @param  format The format name to test, or {@code null}.
235:             * @return {@code true} if the specified metadata suports the specified format.
236:             */
237:            private static boolean isSupportedFormat(
238:                    final IIOMetadata metadata, final String format) {
239:                if (format != null) {
240:                    if (format.equalsIgnoreCase(metadata
241:                            .getNativeMetadataFormatName())) {
242:                        return true;
243:                    }
244:                    final String[] formats = metadata
245:                            .getExtraMetadataFormatNames();
246:                    if (formats != null) {
247:                        for (int i = 0; i < formats.length; i++) {
248:                            if (format.equalsIgnoreCase(formats[i])) {
249:                                return true;
250:                            }
251:                        }
252:                    }
253:                }
254:                return false;
255:            }
256:
257:            /**
258:             * Returns true if the methods that take an {@link IIOImage} parameter are capable of dealing
259:             * with a {@link Raster}. The default implementation returns {@code true} since it is assumed
260:             * that subclasses will fetch pixels using the iterator returned by {@link #createRectIter
261:             * createRectIter}.
262:             */
263:            //@Override
264:            public boolean canWriteRasters() {
265:                return true;
266:            }
267:
268:            /**
269:             * Returns an iterator over the pixels of the specified image, taking subsampling in account.
270:             *
271:             * @param  image The image or raster to be written.
272:             * @param  parameters The write parameters, or {@code null} if the whole image will be written.
273:             * @return An iterator over the pixel values of the image to be written.
274:             */
275:            protected static RectIter createRectIter(final IIOImage image,
276:                    final ImageWriteParam parameters) {
277:                /*
278:                 * Examines the parameters for subsampling in lines, columns and bands. If a subsampling
279:                 * is specified, the source region will be translated by the subsampling offset (if any).
280:                 */
281:                Rectangle bounds;
282:                int[] sourceBands;
283:                final int sourceXSubsampling;
284:                final int sourceYSubsampling;
285:                if (parameters != null) {
286:                    bounds = parameters.getSourceRegion(); // Needs to be a clone.
287:                    sourceXSubsampling = parameters.getSourceXSubsampling();
288:                    sourceYSubsampling = parameters.getSourceYSubsampling();
289:                    if (sourceXSubsampling != 1 || sourceYSubsampling != 1) {
290:                        if (bounds == null) {
291:                            if (image.hasRaster()) {
292:                                bounds = image.getRaster().getBounds(); // Needs to be a clone.
293:                            } else {
294:                                final RenderedImage i = image
295:                                        .getRenderedImage();
296:                                bounds = new Rectangle(i.getMinX(),
297:                                        i.getMinY(), i.getWidth(), i
298:                                                .getHeight());
299:                            }
300:                        }
301:                        final int xOffset = parameters.getSubsamplingXOffset();
302:                        final int yOffset = parameters.getSubsamplingYOffset();
303:                        bounds.x += xOffset;
304:                        bounds.y += yOffset;
305:                        bounds.width -= xOffset;
306:                        bounds.height -= yOffset;
307:                        // Fits to the smallest bounding box, which is
308:                        // required by SubsampledRectIter implementation.
309:                        bounds.width -= (bounds.width - 1) % sourceXSubsampling;
310:                        bounds.height -= (bounds.height - 1)
311:                                % sourceYSubsampling;
312:                    }
313:                    sourceBands = parameters.getSourceBands();
314:                } else {
315:                    sourceBands = null;
316:                    bounds = null;
317:                    sourceXSubsampling = 1;
318:                    sourceYSubsampling = 1;
319:                }
320:                /*
321:                 * Creates the JAIiterator which will iterates over all pixels in the source region.
322:                 * If no subsampling is specified and the source bands do not move and band, then the
323:                 * JAI iterator is returned directly.
324:                 */
325:                final int numBands;
326:                RectIter iterator;
327:                if (image.hasRaster()) {
328:                    final Raster raster = image.getRaster();
329:                    numBands = raster.getNumBands();
330:                    iterator = RectIterFactory.create(raster, bounds);
331:                } else {
332:                    final RenderedImage raster = image.getRenderedImage();
333:                    numBands = raster.getSampleModel().getNumBands();
334:                    iterator = RectIterFactory.create(raster, bounds);
335:                }
336:                if (sourceXSubsampling == 1 && sourceYSubsampling == 1) {
337:                    if (sourceBands == null) {
338:                        return iterator;
339:                    }
340:                    if (sourceBands.length == numBands) {
341:                        boolean identity = true;
342:                        for (int i = 0; i < numBands; i++) {
343:                            if (sourceBands[i] != i) {
344:                                identity = false;
345:                                break;
346:                            }
347:                        }
348:                        if (identity) {
349:                            return iterator;
350:                        }
351:                    }
352:                }
353:                /*
354:                 * A subsampling is required. Wraps the JAI iterator into a subsampler.
355:                 */
356:                if (sourceBands == null) {
357:                    sourceBands = new int[numBands];
358:                    for (int i = 0; i < numBands; i++) {
359:                        sourceBands[i] = i;
360:                    }
361:                }
362:                return new SubsampledRectIter(iterator, sourceXSubsampling,
363:                        sourceYSubsampling, sourceBands);
364:            }
365:
366:            /**
367:             * Computes the size of the region to be read, taking subsampling in account.
368:             *
369:             * @param  image The image or raster to be written.
370:             * @param  parameters The write parameters, or {@code null} if the whole image will be written.
371:             * @return dimension The dimension of the image to be written.
372:             */
373:            protected static ImageDimension computeSize(final IIOImage image,
374:                    final ImageWriteParam parameters) {
375:                final ImageDimension dimension;
376:                if (image.hasRaster()) {
377:                    dimension = new ImageDimension(image.getRaster());
378:                } else {
379:                    dimension = new ImageDimension(image.getRenderedImage());
380:                }
381:                if (parameters != null) {
382:                    final Rectangle bounds = parameters.getSourceRegion();
383:                    if (bounds != null) {
384:                        if (bounds.width < dimension.width) {
385:                            dimension.width = bounds.width;
386:                        }
387:                        if (bounds.height < dimension.height) {
388:                            dimension.height = bounds.height;
389:                        }
390:                    }
391:                    dimension.width -= parameters.getSubsamplingXOffset();
392:                    dimension.height -= parameters.getSubsamplingYOffset();
393:                }
394:                return dimension;
395:            }
396:
397:            /**
398:             * Broadcasts the start of an image write to all registered listeners. The default
399:             * implementation invokes the {@linkplain #processImageStarted(int) super-class method}
400:             * with an image index maintained by this writer.
401:             */
402:            protected void processImageStarted() {
403:                processImageStarted(imageIndex);
404:            }
405:
406:            /**
407:             * Broadcasts the completion of an image write to all registered listeners.
408:             */
409:            //@Override
410:            protected void processImageComplete() {
411:                super .processImageComplete();
412:                thumbnailIndex = 0;
413:                imageIndex++;
414:            }
415:
416:            /**
417:             * Broadcasts the start of a thumbnail write to all registered listeners. The default
418:             * implementation invokes the {@linkplain #processThumbnailStarted(int,int) super-class
419:             * method} with an image and thumbnail index maintained by this writer.
420:             */
421:            protected void processThumbnailStarted() {
422:                processThumbnailStarted(imageIndex, thumbnailIndex);
423:            }
424:
425:            /**
426:             * Broadcasts the completion of a thumbnail write to all registered listeners.
427:             */
428:            //@Override
429:            protected void processThumbnailComplete() {
430:                super .processThumbnailComplete();
431:                thumbnailIndex++;
432:            }
433:
434:            /**
435:             * Broadcasts a warning message to all registered listeners. The default implementation
436:             * invokes the {@linkplain #processWarningOccurred(int,String) super-class method} with
437:             * an image index maintained by this writer.
438:             */
439:            protected void processWarningOccurred(final String warning) {
440:                processWarningOccurred(imageIndex, warning);
441:            }
442:
443:            /**
444:             * Broadcasts a warning message to all registered listeners. The default implementation
445:             * invokes the {@linkplain #processWarningOccurred(int,String,String) super-class method}
446:             * with an image index maintained by this writer.
447:             */
448:            protected void processWarningOccurred(final String baseName,
449:                    final String keyword) {
450:                processWarningOccurred(imageIndex, baseName, keyword);
451:            }
452:
453:            /**
454:             * Invoked when a warning occured. The default implementation make the following choice:
455:             * <p>
456:             * <ul>
457:             *   <li>If at least one {@linkplain IIOWriteWarningListener warning listener}
458:             *       has been {@linkplain #addIIOWriteWarningListener specified}, then the
459:             *       {@link IIOWriteWarningListener#warningOccurred warningOccurred} method is
460:             *       invoked for each of them and the log record is <strong>not</strong> logged.</li>
461:             *
462:             *   <li>Otherwise, the log record is sent to the {@code "org.geotools.image.io"} logger.</li>
463:             * </ul>
464:             *
465:             * Subclasses may override this method if more processing is wanted, or for
466:             * throwing exception if some warnings should be considered as fatal errors.
467:             */
468:            public void warningOccurred(final LogRecord record) {
469:                if (warningListeners == null) {
470:                    LOGGER.log(record);
471:                } else {
472:                    processWarningOccurred(IndexedResourceBundle.format(record));
473:                }
474:            }
475:
476:            /**
477:             * Convenience method for logging an exception from the given method.
478:             */
479:            private void warningOccurred(final String method, final Exception ex) {
480:                final LogRecord record = new LogRecord(Level.WARNING, ex
481:                        .toString());
482:                record
483:                        .setSourceClassName(GeographicImageWriter.class
484:                                .getName());
485:                record.setSourceMethodName(method);
486:                record.setThrown(ex);
487:                warningOccurred(record);
488:            }
489:
490:            /**
491:             * To be overriden and made {@code protected} by {@link StreamImageWriter} only.
492:             */
493:            void close() throws IOException {
494:                imageIndex = 0;
495:                thumbnailIndex = 0;
496:            }
497:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.