KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > imageio > ImageIO


1 /*
2  * @(#)ImageIO.java 1.85 04/05/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.imageio;
9
10 import java.awt.image.BufferedImage JavaDoc;
11 import java.awt.image.RenderedImage JavaDoc;
12 import java.io.File JavaDoc;
13 import java.io.InputStream JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.OutputStream JavaDoc;
16 import java.lang.reflect.Method JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.security.AccessController JavaDoc;
19 import java.util.Arrays JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.HashSet JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.NoSuchElementException JavaDoc;
24 import java.util.Set JavaDoc;
25 import javax.imageio.spi.IIORegistry JavaDoc;
26 import javax.imageio.spi.ImageReaderSpi JavaDoc;
27 import javax.imageio.spi.ImageWriterSpi JavaDoc;
28 import javax.imageio.spi.ImageInputStreamSpi JavaDoc;
29 import javax.imageio.spi.ImageOutputStreamSpi JavaDoc;
30 import javax.imageio.spi.ImageTranscoderSpi JavaDoc;
31 import javax.imageio.spi.ServiceRegistry JavaDoc;
32 import javax.imageio.stream.ImageInputStream JavaDoc;
33 import javax.imageio.stream.ImageOutputStream JavaDoc;
34 import sun.awt.AppContext;
35 import sun.security.action.GetPropertyAction;
36
37 /**
38  * A class containing static convenience methods for locating
39  * <code>ImageReader</code>s and <code>ImageWriter</code>s, and
40  * performing simple encoding and decoding.
41  *
42  * @version 0.5
43  */

44 public final class ImageIO {
45
46     private static final IIORegistry JavaDoc theRegistry =
47         IIORegistry.getDefaultInstance();
48
49     /**
50      * Constructor is private to prevent instantiation.
51      */

52     private ImageIO() {}
53
54     /**
55      * Scans for plug-ins on the application class path,
56      * loads their service provider classes, and registers a service
57      * provider instance for each one found with the
58      * <code>IIORegistry</code>.
59      *
60      * <p>This method is needed because the application class path can
61      * theoretically change, or additional plug-ins may become available.
62      * Rather than re-scanning the classpath on every invocation of the
63      * API, the class path is scanned automatically only on the first
64      * invocation. Clients can call this method to prompt a re-scan.
65      * Thus this method need only be invoked by sophisticated applications
66      * which dynamically make new plug-ins available at runtime.
67      *
68      * <p> The <code>getResources</code> method of the context
69      * <code>ClassLoader</code> is used locate JAR files containing
70      * files named
71      * <code>META-INF/services/javax.imageio.spi.</code><i>classname</i>,
72      * where <i>classname</i> is one of <code>ImageReaderSpi</code>,
73      * <code>ImageWriterSpi</code>, <code>ImageTranscoderSpi</code>,
74      * <code>ImageInputStreamSpi</code>, or
75      * <code>ImageOutputStreamSpi</code>, along the application class
76      * path.
77      *
78      * <p> The contents of the located files indicate the names of
79      * actual implementation classes which implement the
80      * aforementioned service provider interfaces; the default class
81      * loader is then used to load each of these classes and to
82      * instantiate an instance of each class, which is then placed
83      * into the registry for later retrieval.
84      *
85      * <p> The exact set of locations searched depends on the
86      * implementation of the Java runtime enviroment.
87      *
88      * @see ClassLoader#getResources
89      */

90     public static void scanForPlugins() {
91         theRegistry.registerApplicationClasspathSpis();
92     }
93
94     // ImageInputStreams
95

96     /**
97      * A class to hold information about caching. Each
98      * <code>ThreadGroup</code> will have its own copy
99      * via the <code>AppContext</code> mechanism.
100      */

101     static class CacheInfo {
102         boolean useCache = true;
103         File JavaDoc cacheDirectory = null;
104         Boolean JavaDoc hasPermission = null;
105
106         public CacheInfo() {}
107
108         public boolean getUseCache() {
109             return useCache;
110         }
111
112         public void setUseCache(boolean useCache) {
113             this.useCache = useCache;
114         }
115
116         public File JavaDoc getCacheDirectory() {
117             return cacheDirectory;
118         }
119
120         public void setCacheDirectory(File JavaDoc cacheDirectory) {
121             this.cacheDirectory = cacheDirectory;
122         }
123
124         public Boolean JavaDoc getHasPermission() {
125             return hasPermission;
126         }
127
128         public void setHasPermission(Boolean JavaDoc hasPermission) {
129             this.hasPermission = hasPermission;
130         }
131     }
132
133     /**
134      * Returns the <code>CacheInfo</code> object associated with this
135      * <code>ThreadGroup</code>.
136      */

137     private static synchronized CacheInfo getCacheInfo() {
138         AppContext context = AppContext.getAppContext();
139         CacheInfo info = (CacheInfo)context.get(CacheInfo.class);
140         if (info == null) {
141             info = new CacheInfo();
142             context.put(CacheInfo.class, info);
143         }
144         return info;
145     }
146
147     /**
148      * Returns the default temporary (cache) directory as defined by the
149      * java.io.tmpdir system property.
150      */

151     private static String JavaDoc getTempDir() {
152         GetPropertyAction a = new GetPropertyAction("java.io.tmpdir");
153         return (String JavaDoc)AccessController.doPrivileged(a);
154     }
155
156     /**
157      * Determines whether the caller has write access to the cache
158      * directory, stores the result in the <code>CacheInfo</code> object,
159      * and returns the decision. This method helps to prevent mysterious
160      * SecurityExceptions to be thrown when this convenience class is used
161      * in an applet, for example.
162      */

163     private static boolean hasCachePermission() {
164         Boolean JavaDoc hasPermission = getCacheInfo().getHasPermission();
165
166         if (hasPermission != null) {
167             return hasPermission.booleanValue();
168         } else {
169             try {
170                 SecurityManager JavaDoc security = System.getSecurityManager();
171                 if (security != null) {
172                     File JavaDoc cachedir = getCacheDirectory();
173                     String JavaDoc cachepath;
174
175                     if (cachedir != null) {
176                         cachepath = cachedir.getPath();
177                     } else {
178                         cachepath = getTempDir();
179
180                         if (cachepath == null) {
181                             getCacheInfo().setHasPermission(Boolean.FALSE);
182                             return false;
183                         }
184                     }
185
186                     security.checkWrite(cachepath);
187                 }
188             } catch (SecurityException JavaDoc e) {
189                 getCacheInfo().setHasPermission(Boolean.FALSE);
190                 return false;
191             }
192
193             getCacheInfo().setHasPermission(Boolean.TRUE);
194             return true;
195         }
196     }
197
198     /**
199      * Sets a flag indicating whether a disk-based cache file should
200      * be used when creating <code>ImageInputStream</code>s and
201      * <code>ImageOutputStream</code>s.
202      *
203      * <p> When reading from a standard <code>InputStream</code>>, it
204      * may be necessary to save previously read information in a cache
205      * since the underlying stream does not allow data to be re-read.
206      * Similarly, when writing to a standard
207      * <code>OutputStream</code>, a cache may be used to allow a
208      * previously written value to be changed before flushing it to
209      * the final destination.
210      *
211      * <p> The cache may reside in main memory or on disk. Setting
212      * this flag to <code>false</code> disallows the use of disk for
213      * future streams, which may be advantageous when working with
214      * small images, as the overhead of creating and destroying files
215      * is removed.
216      *
217      * <p> On startup, the value is set to <code>true</code>.
218      *
219      * @param useCache a <code>boolean</code> indicating whether a
220      * cache file should be used, in cases where it is optional.
221      *
222      * @see #getUseCache
223      */

224     public static void setUseCache(boolean useCache) {
225         getCacheInfo().setUseCache(useCache);
226     }
227
228     /**
229      * Returns the current value set by <code>setUseCache</code>, or
230      * <code>true</code> if no explicit setting has been made.
231      *
232      * @return true if a disk-based cache may be used for
233      * <code>ImageInputStream</code>s and
234      * <code>ImageOutputStream</code>s.
235      *
236      * @see #setUseCache
237      */

238     public static boolean getUseCache() {
239         return getCacheInfo().getUseCache();
240     }
241
242     /**
243      * Sets the directory where cache files are to be created. A
244      * value of <code>null</code> indicates that the system-dependent
245      * default temporary-file directory is to be used. If
246      * <code>getUseCache</code> returns false, this value is ignored.
247      *
248      * @param cacheDirectory a <code>File</code> specifying a directory.
249      *
250      * @see File#createTempFile(String, String, File)
251      *
252      * @exception SecurityException if the security manager denies
253      * access to the directory.
254      * @exception IllegalArgumentException if <code>cacheDir</code> is
255      * non-<code>null</code> but is not a directory.
256      *
257      * @see #getCacheDirectory
258      */

259     public static void setCacheDirectory(File JavaDoc cacheDirectory) {
260         if ((cacheDirectory != null) && !(cacheDirectory.isDirectory())) {
261             throw new IllegalArgumentException JavaDoc("Not a directory!");
262         }
263         getCacheInfo().setCacheDirectory(cacheDirectory);
264         getCacheInfo().setHasPermission(null);
265     }
266
267     /**
268      * Returns the current value set by
269      * <code>setCacheDirectory</code>, or <code>null</code> if no
270      * explicit setting has been made.
271      *
272      * @return a <code>File</code> indicating the directory where
273      * cache files will be created, or <code>null</code> to indicate
274      * the system-dependent default temporary-file directory.
275      *
276      * @see #setCacheDirectory
277      */

278     public static File JavaDoc getCacheDirectory() {
279         return getCacheInfo().getCacheDirectory();
280     }
281
282     /**
283      * Returns an <code>ImageInputStream</code> that will take its
284      * input from the given <code>Object</code>. The set of
285      * <code>ImageInputStreamSpi</code>s registered with the
286      * <code>IIORegistry</code> class is queried and the first one
287      * that is able to take input from the supplied object is used to
288      * create the returned <code>ImageInputStream</code>. If no
289      * suitable <code>ImageInputStreamSpi</code> exists,
290      * <code>null</code> is returned.
291      *
292      * <p> The current cache settings from <code>getUseCache</code>and
293      * <code>getCacheDirectory</code> will be used to control caching.
294      *
295      * @param input an <code>Object</code> to be used as an input
296      * source, such as a <code>File</code>, readable
297      * <code>RandomAccessFile</code>, or <code>InputStream</code>.
298      *
299      * @return an <code>ImageInputStream</code>, or <code>null</code>.
300      *
301      * @exception IllegalArgumentException if <code>input</code>
302      * is <code>null</code>.
303      * @exception IOException if a cache file is needed but cannot be
304      * created.
305      *
306      * @see javax.imageio.spi.ImageInputStreamSpi
307      */

308     public static ImageInputStream JavaDoc createImageInputStream(Object JavaDoc input)
309         throws IOException JavaDoc {
310         if (input == null) {
311             throw new IllegalArgumentException JavaDoc("input == null!");
312         }
313
314         Iterator JavaDoc iter;
315         // Ensure category is present
316
try {
317             iter = theRegistry.getServiceProviders(ImageInputStreamSpi JavaDoc.class,
318                                                    true);
319         } catch (IllegalArgumentException JavaDoc e) {
320             return null;
321         }
322
323         boolean usecache = getUseCache() && hasCachePermission();
324
325         while (iter.hasNext()) {
326             ImageInputStreamSpi JavaDoc spi = (ImageInputStreamSpi JavaDoc)iter.next();
327             if (spi.getInputClass().isInstance(input)) {
328                 try {
329                     return spi.createInputStreamInstance(input,
330                                                          usecache,
331                                                          getCacheDirectory());
332                 } catch (IOException JavaDoc e) {
333                     throw new IIOException JavaDoc("Can't create cache file!", e);
334                 }
335             }
336         }
337
338         return null;
339     }
340
341     // ImageOutputStreams
342

343     /**
344      * Returns an <code>ImageOutputStream</code> that will send its
345      * output to the given <code>Object</code>. The set of
346      * <code>ImageOutputStreamSpi</code>s registered with the
347      * <code>IIORegistry</code> class is queried and the first one
348      * that is able to send output from the supplied object is used to
349      * create the returned <code>ImageOutputStream</code>. If no
350      * suitable <code>ImageOutputStreamSpi</code> exists,
351      * <code>null</code> is returned.
352      *
353      * <p> The current cache settings from <code>getUseCache</code>and
354      * <code>getCacheDirectory</code> will be used to control caching.
355      *
356      * @param output an <code>Object</code> to be used as an output
357      * destination, such as a <code>File</code>, writable
358      * <code>RandomAccessFile</code>, or <code>OutputStream</code>.
359      *
360      * @return an <code>ImageOutputStream</code>, or
361      * <code>null</code>.
362      *
363      * @exception IllegalArgumentException if <code>output</code> is
364      * <code>null</code>.
365      * @exception IOException if a cache file is needed but cannot be
366      * created.
367      *
368      * @see javax.imageio.spi.ImageOutputStreamSpi
369      */

370     public static ImageOutputStream JavaDoc createImageOutputStream(Object JavaDoc output)
371         throws IOException JavaDoc {
372         if (output == null) {
373             throw new IllegalArgumentException JavaDoc("output == null!");
374         }
375
376         Iterator JavaDoc iter;
377         // Ensure category is present
378
try {
379             iter = theRegistry.getServiceProviders(ImageOutputStreamSpi JavaDoc.class,
380                                                    true);
381         } catch (IllegalArgumentException JavaDoc e) {
382             return null;
383         }
384
385         boolean usecache = getUseCache() && hasCachePermission();
386
387         while (iter.hasNext()) {
388             ImageOutputStreamSpi JavaDoc spi = (ImageOutputStreamSpi JavaDoc)iter.next();
389             if (spi.getOutputClass().isInstance(output)) {
390                 try {
391                     return spi.createOutputStreamInstance(output,
392                                                           usecache,
393                                                           getCacheDirectory());
394                 } catch (IOException JavaDoc e) {
395                     throw new IIOException JavaDoc("Can't create cache file!", e);
396                 }
397             }
398         }
399
400         return null;
401     }
402
403     // Readers
404

405     private static String JavaDoc[] toStringArray(Set JavaDoc s) {
406         String JavaDoc[] val = new String JavaDoc[s.size()];
407         Iterator JavaDoc iter = s.iterator();
408         int index = 0;
409         while (iter.hasNext()) {
410             val[index++] = (String JavaDoc)iter.next();
411         }
412
413         return val;
414     }
415
416     /**
417      * Returns an array of <code>String</code>s listing all of the
418      * informal format names understood by the current set of registered
419      * readers.
420      *
421      * @return an array of <code>String</code>s.
422      */

423     public static String JavaDoc[] getReaderFormatNames() {
424         Iterator JavaDoc iter;
425         // Ensure category is present
426
try {
427             iter = theRegistry.getServiceProviders(ImageReaderSpi JavaDoc.class, true);
428         } catch (IllegalArgumentException JavaDoc e) {
429             return new String JavaDoc[0];
430         }
431
432         Set JavaDoc s = new HashSet JavaDoc();
433         while (iter.hasNext()) {
434             ImageReaderSpi JavaDoc spi = (ImageReaderSpi JavaDoc)iter.next();
435             String JavaDoc[] names = spi.getFormatNames();
436             for (int i = 0; i < names.length; i++) {
437                 s.add(names[i]);
438             }
439         }
440
441         return toStringArray(s);
442    }
443
444     /**
445      * Returns an array of <code>String</code>s listing all of the
446      * MIME types understood by the current set of registered
447      * readers.
448      *
449      * @return an array of <code>String</code>s.
450      */

451     public static String JavaDoc[] getReaderMIMETypes() {
452         Iterator JavaDoc iter;
453         // Ensure category is present
454
try {
455             iter = theRegistry.getServiceProviders(ImageReaderSpi JavaDoc.class, true);
456         } catch (IllegalArgumentException JavaDoc e) {
457             return new String JavaDoc[0];
458         }
459
460         Set JavaDoc s = new HashSet JavaDoc();
461         while (iter.hasNext()) {
462             ImageReaderSpi JavaDoc spi = (ImageReaderSpi JavaDoc)iter.next();
463             String JavaDoc[] names = spi.getMIMETypes();
464             for (int i = 0; i < names.length; i++) {
465                 s.add(names[i]);
466             }
467         }
468
469         return toStringArray(s);
470     }
471
472     static class ImageReaderIterator implements Iterator JavaDoc<ImageReader JavaDoc> {
473         // Contains ImageReaderSpis
474
public Iterator JavaDoc iter;
475
476         public ImageReaderIterator(Iterator JavaDoc iter) {
477             this.iter = iter;
478         }
479         
480         public boolean hasNext() {
481             return iter.hasNext();
482         }
483
484         public ImageReader JavaDoc next() {
485             ImageReaderSpi JavaDoc spi = null;
486             try {
487                 spi = (ImageReaderSpi JavaDoc)iter.next();
488                 return spi.createReaderInstance();
489             } catch (IOException JavaDoc e) {
490                 // Deregister the spi in this case, but only as
491
// an ImageReaderSpi
492
theRegistry.deregisterServiceProvider(spi, ImageReaderSpi JavaDoc.class);
493             }
494             return null;
495         }
496
497         public void remove() {
498             throw new UnsupportedOperationException JavaDoc();
499         }
500     }
501
502     static class CanDecodeInputFilter
503         implements ServiceRegistry.Filter JavaDoc {
504
505         Object JavaDoc input;
506
507         public CanDecodeInputFilter(Object JavaDoc input) {
508             this.input = input;
509         }
510
511         public boolean filter(Object JavaDoc elt) {
512             try {
513                 ImageReaderSpi JavaDoc spi = (ImageReaderSpi JavaDoc)elt;
514                 ImageInputStream JavaDoc stream = null;
515                 if (input instanceof ImageInputStream JavaDoc) {
516                     stream = (ImageInputStream JavaDoc)input;
517                 }
518                 
519                 // Perform mark/reset as a defensive measure
520
// even though plug-ins are supposed to take
521
// care of it.
522
boolean canDecode = false;
523                 if (stream != null) {
524                     stream.mark();
525                 }
526                 canDecode = spi.canDecodeInput(input);
527                 if (stream != null) {
528                     stream.reset();
529                 }
530                 
531                 return canDecode;
532             } catch (IOException JavaDoc e) {
533                 return false;
534             }
535         }
536     }
537
538     static class CanEncodeImageAndFormatFilter
539         implements ServiceRegistry.Filter JavaDoc {
540
541         ImageTypeSpecifier JavaDoc type;
542         String JavaDoc formatName;
543
544         public CanEncodeImageAndFormatFilter(ImageTypeSpecifier JavaDoc type,
545                                              String JavaDoc formatName) {
546             this.type = type;
547             this.formatName = formatName;
548         }
549
550         public boolean filter(Object JavaDoc elt) {
551             ImageWriterSpi JavaDoc spi = (ImageWriterSpi JavaDoc)elt;
552             return Arrays.asList(spi.getFormatNames()).contains(formatName) &&
553                 spi.canEncodeImage(type);
554         }
555     }
556
557     static class ContainsFilter
558         implements ServiceRegistry.Filter JavaDoc {
559
560         Method JavaDoc method;
561         String JavaDoc name;
562
563         // method returns an array of Strings
564
public ContainsFilter(Method JavaDoc method,
565                               String JavaDoc name) {
566             this.method = method;
567             this.name = name;
568         }
569
570         public boolean filter(Object JavaDoc elt) {
571             try {
572                 return contains((String JavaDoc[])method.invoke(elt, null), name);
573             } catch (Exception JavaDoc e) {
574                 return false;
575             }
576         }
577     }
578
579     /**
580      * Returns an <code>Iterator</code> containing all currently
581      * registered <code>ImageReader</code>s that claim to be able to
582      * decode the supplied <code>Object</code>, typically an
583      * <code>ImageInputStream</code>.
584      *
585      * <p> The stream position is left at its prior position upon
586      * exit from this method.
587      *
588      * @param input an <code>ImageInputStream</code> or other
589      * <code>Object</code> containing encoded image data.
590      *
591      * @return an <code>Iterator</code> containing <code>ImageReader</code>s.
592      *
593      * @exception IllegalArgumentException if <code>input</code> is
594      * <code>null</code>.
595      *
596      * @see javax.imageio.spi.ImageReaderSpi#canDecodeInput
597      */

598     public static Iterator JavaDoc<ImageReader JavaDoc> getImageReaders(Object JavaDoc input) {
599         if (input == null) {
600             throw new IllegalArgumentException JavaDoc("input == null!");
601         }
602         Iterator JavaDoc iter;
603         // Ensure category is present
604
try {
605             iter = theRegistry.getServiceProviders(ImageReaderSpi JavaDoc.class,
606                                               new CanDecodeInputFilter(input),
607                                               true);
608         } catch (IllegalArgumentException JavaDoc e) {
609             return new HashSet JavaDoc().iterator();
610         }
611
612         return new ImageReaderIterator(iter);
613     }
614
615     private static Method JavaDoc readerFormatNamesMethod;
616     private static Method JavaDoc readerFileSuffixesMethod;
617     private static Method JavaDoc readerMIMETypesMethod;
618     private static Method JavaDoc writerFormatNamesMethod;
619     private static Method JavaDoc writerFileSuffixesMethod;
620     private static Method JavaDoc writerMIMETypesMethod;
621
622     static {
623         try {
624             readerFormatNamesMethod =
625                 ImageReaderSpi JavaDoc.class.getMethod("getFormatNames", null);
626             readerFileSuffixesMethod =
627                 ImageReaderSpi JavaDoc.class.getMethod("getFileSuffixes", null);
628             readerMIMETypesMethod =
629                 ImageReaderSpi JavaDoc.class.getMethod("getMIMETypes", null);
630             
631             writerFormatNamesMethod =
632                 ImageWriterSpi JavaDoc.class.getMethod("getFormatNames", null);
633             writerFileSuffixesMethod =
634                 ImageWriterSpi JavaDoc.class.getMethod("getFileSuffixes", null);
635             writerMIMETypesMethod =
636                 ImageWriterSpi JavaDoc.class.getMethod("getMIMETypes", null);
637         } catch (NoSuchMethodException JavaDoc e) {
638             e.printStackTrace();
639         }
640     }
641
642     /**
643      * Returns an <code>Iterator</code> containing all currently
644      * registered <code>ImageReader</code>s that claim to be able to
645      * decode the named format.
646      *
647      * @param formatName a <code>String</code> containing the informal
648      * name of a format (<i>e.g.</i>, "jpeg" or "tiff".
649      *
650      * @return an <code>Iterator</code> containing
651      * <code>ImageReader</code>s.
652      *
653      * @exception IllegalArgumentException if <code>formatName</code>
654      * is <code>null</code>.
655      *
656      * @see javax.imageio.spi.ImageReaderSpi#getFormatNames
657      */

658     public static Iterator JavaDoc<ImageReader JavaDoc>
659     getImageReadersByFormatName(String JavaDoc formatName)
660     {
661         if (formatName == null) {
662             throw new IllegalArgumentException JavaDoc("formatName == null!");
663         }
664         Iterator JavaDoc iter;
665         // Ensure category is present
666
try {
667             iter = theRegistry.getServiceProviders(ImageReaderSpi JavaDoc.class,
668                                     new ContainsFilter(readerFormatNamesMethod,
669                                                        formatName),
670                                                 true);
671         } catch (IllegalArgumentException JavaDoc e) {
672             return new HashSet JavaDoc().iterator();
673         }
674         return new ImageReaderIterator(iter);
675     }
676
677     /**
678      * Returns an <code>Iterator</code> containing all currently
679      * registered <code>ImageReader</code>s that claim to be able to
680      * decode files with the given suffix.
681      *
682      * @param fileSuffix a <code>String</code> containing a file
683      * suffix (<i>e.g.</i>, "jpg" or "tiff").
684      *
685      * @return an <code>Iterator</code> containing
686      * <code>ImageReader</code>s.
687      *
688      * @exception IllegalArgumentException if <code>fileSuffix</code>
689      * is <code>null</code>.
690      *
691      * @see javax.imageio.spi.ImageReaderSpi#getFileSuffixes
692      */

693     public static Iterator JavaDoc<ImageReader JavaDoc>
694     getImageReadersBySuffix(String JavaDoc fileSuffix)
695     {
696         if (fileSuffix == null) {
697             throw new IllegalArgumentException JavaDoc("fileSuffix == null!");
698         }
699         // Ensure category is present
700
Iterator JavaDoc iter;
701         try {
702             iter = theRegistry.getServiceProviders(ImageReaderSpi JavaDoc.class,
703                                    new ContainsFilter(readerFileSuffixesMethod,
704                                                       fileSuffix),
705                                               true);
706         } catch (IllegalArgumentException JavaDoc e) {
707             return new HashSet JavaDoc().iterator();
708         }
709         return new ImageReaderIterator(iter);
710     }
711
712     /**
713      * Returns an <code>Iterator</code> containing all currently
714      * registered <code>ImageReader</code>s that claim to be able to
715      * decode files with the given MIME type.
716      *
717      * @param MIMEType a <code>String</code> containing a file
718      * suffix (<i>e.g.</i>, "image/jpeg" or "image/x-bmp").
719      *
720      * @return an <code>Iterator</code> containing
721      * <code>ImageReader</code>s.
722      *
723      * @exception IllegalArgumentException if <code>MIMEType</code> is
724      * <code>null</code>.
725      *
726      * @see javax.imageio.spi.ImageReaderSpi#getMIMETypes
727      */

728     public static Iterator JavaDoc<ImageReader JavaDoc>
729     getImageReadersByMIMEType(String JavaDoc MIMEType)
730     {
731         if (MIMEType == null) {
732             throw new IllegalArgumentException JavaDoc("MIMEType == null!");
733         }
734         // Ensure category is present
735
Iterator JavaDoc iter;
736         try {
737             iter = theRegistry.getServiceProviders(ImageReaderSpi JavaDoc.class,
738                                       new ContainsFilter(readerMIMETypesMethod,
739                                                          MIMEType),
740                                               true);
741         } catch (IllegalArgumentException JavaDoc e) {
742             return new HashSet JavaDoc().iterator();
743         }
744         return new ImageReaderIterator(iter);
745     }
746
747     // Writers
748

749     /**
750      * Returns an array of <code>String</code>s listing all of the
751      * informal format names understood by the current set of registered
752      * writers.
753      *
754      * @return an array of <code>String</code>s.
755      */

756     public static String JavaDoc[] getWriterFormatNames() {
757         Iterator JavaDoc iter;
758         // Ensure category is present
759
try {
760             iter = theRegistry.getServiceProviders(ImageWriterSpi JavaDoc.class, true);
761         } catch (IllegalArgumentException JavaDoc e) {
762             return new String JavaDoc[0];
763         }
764
765         Set JavaDoc s = new HashSet JavaDoc();
766         while (iter.hasNext()) {
767             ImageWriterSpi JavaDoc spi = (ImageWriterSpi JavaDoc)iter.next();
768             String JavaDoc[] names = spi.getFormatNames();
769             for (int i = 0; i < names.length; i++) {
770                 s.add(names[i]);
771             }
772         }
773
774         return toStringArray(s);
775     }
776
777     /**
778      * Returns an array of <code>String</code>s listing all of the
779      * MIME types understood by the current set of registered
780      * writers.
781      *
782      * @return an array of <code>String</code>s.
783      */

784     public static String JavaDoc[] getWriterMIMETypes() {
785         Iterator JavaDoc iter;
786         // Ensure category is present
787
try {
788             iter = theRegistry.getServiceProviders(ImageWriterSpi JavaDoc.class, true);
789         } catch (IllegalArgumentException JavaDoc e) {
790             return new String JavaDoc[0];
791         }
792         
793         Set JavaDoc s = new HashSet JavaDoc();
794         while (iter.hasNext()) {
795             ImageWriterSpi JavaDoc spi = (ImageWriterSpi JavaDoc)iter.next();
796             String JavaDoc[] names = spi.getMIMETypes();
797             for (int i = 0; i < names.length; i++) {
798                 s.add(names[i]);
799             }
800         }
801
802         return toStringArray(s);
803     }
804
805     static class ImageWriterIterator implements Iterator JavaDoc<ImageWriter JavaDoc> {
806         // Contains ImageWriterSpis
807
public Iterator JavaDoc iter;
808
809         public ImageWriterIterator(Iterator JavaDoc iter) {
810             this.iter = iter;
811         }
812         
813         public boolean hasNext() {
814             return iter.hasNext();
815         }
816
817         public ImageWriter JavaDoc next() {
818             ImageWriterSpi JavaDoc spi = null;
819             try {
820                 spi = (ImageWriterSpi JavaDoc)iter.next();
821                 return spi.createWriterInstance();
822             } catch (IOException JavaDoc e) {
823                 // Deregister the spi in this case, but only as a writerSpi
824
theRegistry.deregisterServiceProvider(spi, ImageWriterSpi JavaDoc.class);
825             }
826             return null;
827         }
828
829         public void remove() {
830             throw new UnsupportedOperationException JavaDoc();
831         }
832     }
833
834     private static boolean contains(String JavaDoc[] names, String JavaDoc name) {
835         for (int i = 0; i < names.length; i++) {
836             if (name.equalsIgnoreCase(names[i])) {
837                 return true;
838             }
839         }
840
841         return false;
842     }
843
844     /**
845      * Returns an <code>Iterator</code> containing all currently
846      * registered <code>ImageWriter</code>s that claim to be able to
847      * encode the named format.
848      *
849      * @param formatName a <code>String</code> containing the informal
850      * name of a format (<i>e.g.</i>, "jpeg" or "tiff".
851      *
852      * @return an <code>Iterator</code> containing
853      * <code>ImageWriter</code>s.
854      *
855      * @exception IllegalArgumentException if <code>formatName</code> is
856      * <code>null</code>.
857      *
858      * @see javax.imageio.spi.ImageWriterSpi#getFormatNames
859      */

860     public static Iterator JavaDoc<ImageWriter JavaDoc>
861     getImageWritersByFormatName(String JavaDoc formatName)
862     {
863         if (formatName == null) {
864             throw new IllegalArgumentException JavaDoc("formatName == null!");
865         }
866         Iterator JavaDoc iter;
867         // Ensure category is present
868
try {
869             iter = theRegistry.getServiceProviders(ImageWriterSpi JavaDoc.class,
870                                     new ContainsFilter(writerFormatNamesMethod,
871                                                        formatName),
872                                             true);
873         } catch (IllegalArgumentException JavaDoc e) {
874             return new HashSet JavaDoc().iterator();
875         }
876         return new ImageWriterIterator(iter);
877     }
878
879     /**
880      * Returns an <code>Iterator</code> containing all currently
881      * registered <code>ImageWriter</code>s that claim to be able to
882      * encode files with the given suffix.
883      *
884      * @param fileSuffix a <code>String</code> containing a file
885      * suffix (<i>e.g.</i>, "jpg" or "tiff").
886      *
887      * @return an <code>Iterator</code> containing <code>ImageWriter</code>s.
888      *
889      * @exception IllegalArgumentException if <code>fileSuffix</code> is
890      * <code>null</code>.
891      *
892      * @see javax.imageio.spi.ImageWriterSpi#getFileSuffixes
893      */

894     public static Iterator JavaDoc<ImageWriter JavaDoc>
895     getImageWritersBySuffix(String JavaDoc fileSuffix)
896     {
897         if (fileSuffix == null) {
898             throw new IllegalArgumentException JavaDoc("fileSuffix == null!");
899         }
900         Iterator JavaDoc iter;
901         // Ensure category is present
902
try {
903             iter = theRegistry.getServiceProviders(ImageWriterSpi JavaDoc.class,
904                                    new ContainsFilter(writerFileSuffixesMethod,
905                                                       fileSuffix),
906                                             true);
907         } catch (IllegalArgumentException JavaDoc e) {
908             return new HashSet JavaDoc().iterator();
909         }
910         return new ImageWriterIterator(iter);
911     }
912
913     /**
914      * Returns an <code>Iterator</code> containing all currently
915      * registered <code>ImageWriter</code>s that claim to be able to
916      * encode files with the given MIME type.
917      *
918      * @param MIMEType a <code>String</code> containing a file
919      * suffix (<i>e.g.</i>, "image/jpeg" or "image/x-bmp").
920      *
921      * @return an <code>Iterator</code> containing <code>ImageWriter</code>s.
922      *
923      * @exception IllegalArgumentException if <code>MIMEType</code> is
924      * <code>null</code>.
925      *
926      * @see javax.imageio.spi.ImageWriterSpi#getMIMETypes
927      */

928     public static Iterator JavaDoc<ImageWriter JavaDoc>
929     getImageWritersByMIMEType(String JavaDoc MIMEType)
930     {
931         if (MIMEType == null) {
932             throw new IllegalArgumentException JavaDoc("MIMEType == null!");
933         }
934         Iterator JavaDoc iter;
935         // Ensure category is present
936
try {
937             iter = theRegistry.getServiceProviders(ImageWriterSpi JavaDoc.class,
938                                       new ContainsFilter(writerMIMETypesMethod,
939                                                          MIMEType),
940                                             true);
941         } catch (IllegalArgumentException JavaDoc e) {
942             return new HashSet JavaDoc().iterator();
943         }
944         return new ImageWriterIterator(iter);
945     }
946
947     /**
948      * Returns an <code>ImageWriter</code>corresponding to the given
949      * <code>ImageReader</code>, if there is one, or <code>null</code>
950      * if the plug-in for this <code>ImageReader</code> does not
951      * specify a corresponding <code>ImageWriter</code>, or if the
952      * given <code>ImageReader</code> is not registered. This
953      * mechanism may be used to obtain an <code>ImageWriter</code>
954      * that will understand the internal structure of non-pixel
955      * metadata (as encoded by <code>IIOMetadata</code> objects)
956      * generated by the <code>ImageReader</code>. By obtaining this
957      * data from the <code>ImageReader</code> and passing it on to the
958      * <code>ImageWriter</code> obtained with this method, a client
959      * program can read an image, modify it in some way, and write it
960      * back out preserving all metadata, without having to understand
961      * anything about the structure of the metadata, or even about
962      * the image format. Note that this method returns the
963      * "preferred" writer, which is the first in the list returned by
964      * <code>javax.imageio.spi.ImageReaderSpi.getImageWriterSpiNames()</code>.
965      *
966      * @param reader an instance of a registered <code>ImageReader</code>.
967      *
968      * @return an <code>ImageWriter</code>, or null.
969      *
970      * @exception IllegalArgumentException if <code>reader</code> is
971      * <code>null</code>.
972      *
973      * @see #getImageReader(ImageWriter)
974      * @see javax.imageio.spi.ImageReaderSpi#getImageWriterSpiNames()
975      */

976     public static ImageWriter JavaDoc getImageWriter(ImageReader JavaDoc reader) {
977         if (reader == null) {
978             throw new IllegalArgumentException JavaDoc("reader == null!");
979         }
980
981         ImageReaderSpi JavaDoc readerSpi = reader.getOriginatingProvider();
982         if (readerSpi == null) {
983             Iterator JavaDoc readerSpiIter;
984             // Ensure category is present
985
try {
986                 readerSpiIter =
987                     theRegistry.getServiceProviders(ImageReaderSpi JavaDoc.class,
988                                                     false);
989             } catch (IllegalArgumentException JavaDoc e) {
990                 return null;
991             }
992
993             while (readerSpiIter.hasNext()) {
994                 ImageReaderSpi JavaDoc temp = (ImageReaderSpi JavaDoc) readerSpiIter.next();
995                 if (temp.isOwnReader(reader)) {
996                     readerSpi = temp;
997                     break;
998                 }
999             }
1000            if (readerSpi == null) {
1001                return null;
1002            }
1003        }
1004
1005        String JavaDoc[] writerNames = readerSpi.getImageWriterSpiNames();
1006        if (writerNames == null) {
1007            return null;
1008        }
1009
1010        Class JavaDoc writerSpiClass = null;
1011        try {
1012            writerSpiClass = Class.forName(writerNames[0], true,
1013                                           ClassLoader.getSystemClassLoader());
1014        } catch (ClassNotFoundException JavaDoc e) {
1015            return null;
1016        }
1017
1018        ImageWriterSpi JavaDoc writerSpi = (ImageWriterSpi JavaDoc)
1019            theRegistry.getServiceProviderByClass(writerSpiClass);
1020        if (writerSpi == null) {
1021            return null;
1022        }
1023
1024        try {
1025            return writerSpi.createWriterInstance();
1026        } catch (IOException JavaDoc e) {
1027            // Deregister the spi in this case, but only as a writerSpi
1028
theRegistry.deregisterServiceProvider(writerSpi,
1029                                                  ImageWriterSpi JavaDoc.class);
1030            return null;
1031        }
1032    }
1033
1034    /**
1035     * Returns an <code>ImageReader</code>corresponding to the given
1036     * <code>ImageWriter</code>, if there is one, or <code>null</code>
1037     * if the plug-in for this <code>ImageWriter</code> does not
1038     * specify a corresponding <code>ImageReader</code>, or if the
1039     * given <code>ImageWriter</code> is not registered. This method
1040     * is provided principally for symmetry with
1041     * <code>getImageWriter(ImageReader)</code>. Note that this
1042     * method returns the "preferred" reader, which is the first in
1043     * the list returned by
1044     * javax.imageio.spi.ImageWriterSpi.<code>getImageReaderSpiNames()</code>.
1045     *
1046     * @param writer an instance of a registered <code>ImageWriter</code>.
1047     *
1048     * @return an <code>ImageReader</code>, or null.
1049     *
1050     * @exception IllegalArgumentException if <code>writer</code> is
1051     * <code>null</code>.
1052     *
1053     * @see #getImageWriter(ImageReader)
1054     * @see javax.imageio.spi.ImageWriterSpi#getImageReaderSpiNames()
1055     */

1056    public static ImageReader JavaDoc getImageReader(ImageWriter JavaDoc writer) {
1057        if (writer == null) {
1058            throw new IllegalArgumentException JavaDoc("writer == null!");
1059        }
1060
1061        ImageWriterSpi JavaDoc writerSpi = writer.getOriginatingProvider();
1062        if (writerSpi == null) {
1063            Iterator JavaDoc writerSpiIter;
1064            // Ensure category is present
1065
try {
1066                writerSpiIter =
1067                    theRegistry.getServiceProviders(ImageWriterSpi JavaDoc.class,
1068                                                    false);
1069            } catch (IllegalArgumentException JavaDoc e) {
1070                return null;
1071            }
1072
1073            while (writerSpiIter.hasNext()) {
1074                ImageWriterSpi JavaDoc temp = (ImageWriterSpi JavaDoc) writerSpiIter.next();
1075                if (temp.isOwnWriter(writer)) {
1076                    writerSpi = temp;
1077                    break;
1078                }
1079            }
1080            if (writerSpi == null) {
1081                return null;
1082            }
1083        }
1084
1085        String JavaDoc[] readerNames = writerSpi.getImageReaderSpiNames();
1086        if (readerNames == null) {
1087            return null;
1088        }
1089
1090        Class JavaDoc readerSpiClass = null;
1091        try {
1092            readerSpiClass = Class.forName(readerNames[0], true,
1093                                           ClassLoader.getSystemClassLoader());
1094        } catch (ClassNotFoundException JavaDoc e) {
1095            return null;
1096        }
1097
1098        ImageReaderSpi JavaDoc readerSpi = (ImageReaderSpi JavaDoc)
1099            theRegistry.getServiceProviderByClass(readerSpiClass);
1100        if (readerSpi == null) {
1101            return null;
1102        }
1103
1104        try {
1105            return readerSpi.createReaderInstance();
1106        } catch (IOException JavaDoc e) {
1107            // Deregister the spi in this case, but only as a readerSpi
1108
theRegistry.deregisterServiceProvider(readerSpi,
1109                                                  ImageReaderSpi JavaDoc.class);
1110            return null;
1111        }
1112    }
1113
1114    /**
1115     * Returns an <code>Iterator</code> containing all currently
1116     * registered <code>ImageWriter</code>s that claim to be able to
1117     * encode images of the given layout (specified using an
1118     * <code>ImageTypeSpecifier</code>) in the given format.
1119     *
1120     * @param type an <code>ImageTypeSpecifier</code> indicating the
1121     * layout of the image to be written.
1122     * @param formatName the informal name of the <code>format</code>.
1123     *
1124     * @return an <code>Iterator</code> containing <code>ImageWriter</code>s.
1125     *
1126     * @exception IllegalArgumentException if any parameter is
1127     * <code>null</code>.
1128     *
1129     * @see javax.imageio.spi.ImageWriterSpi#canEncodeImage(ImageTypeSpecifier)
1130     */

1131    public static Iterator JavaDoc<ImageWriter JavaDoc>
1132    getImageWriters(ImageTypeSpecifier JavaDoc type, String JavaDoc formatName)
1133    {
1134        if (type == null) {
1135            throw new IllegalArgumentException JavaDoc("type == null!");
1136        }
1137        if (formatName == null) {
1138            throw new IllegalArgumentException JavaDoc("formatName == null!");
1139        }
1140
1141        Iterator JavaDoc iter;
1142        // Ensure category is present
1143
try {
1144            iter = theRegistry.getServiceProviders(ImageWriterSpi JavaDoc.class,
1145                                 new CanEncodeImageAndFormatFilter(type,
1146                                                                   formatName),
1147                                            true);
1148        } catch (IllegalArgumentException JavaDoc e) {
1149            return new HashSet JavaDoc().iterator();
1150        }
1151
1152        return new ImageWriterIterator(iter);
1153    }
1154
1155    static class ImageTranscoderIterator
1156    implements Iterator JavaDoc<ImageTranscoder JavaDoc>
1157    {
1158        // Contains ImageTranscoderSpis
1159
public Iterator JavaDoc iter;
1160
1161        public ImageTranscoderIterator(Iterator JavaDoc iter) {
1162            this.iter = iter;
1163        }
1164        
1165        public boolean hasNext() {
1166            return iter.hasNext();
1167        }
1168
1169        public ImageTranscoder JavaDoc next() {
1170            ImageTranscoderSpi JavaDoc spi = null;
1171            spi = (ImageTranscoderSpi JavaDoc)iter.next();
1172            return spi.createTranscoderInstance();
1173        }
1174
1175        public void remove() {
1176            throw new UnsupportedOperationException JavaDoc();
1177        }
1178    }
1179
1180    static class TranscoderFilter
1181        implements ServiceRegistry.Filter JavaDoc {
1182
1183        String JavaDoc readerSpiName;
1184        String JavaDoc writerSpiName;
1185
1186        public TranscoderFilter(ImageReaderSpi JavaDoc readerSpi,
1187                                ImageWriterSpi JavaDoc writerSpi) {
1188            this.readerSpiName = readerSpi.getClass().getName();
1189            this.writerSpiName = writerSpi.getClass().getName();
1190        }
1191
1192        public boolean filter(Object JavaDoc elt) {
1193            ImageTranscoderSpi JavaDoc spi = (ImageTranscoderSpi JavaDoc)elt;
1194            String JavaDoc readerName = spi.getReaderServiceProviderName();
1195            String JavaDoc writerName = spi.getWriterServiceProviderName();
1196            return (readerName.equals(readerSpiName) &&
1197                    writerName.equals(writerSpiName));
1198        }
1199    }
1200
1201    /**
1202     * Returns an <code>Iterator</code> containing all currently
1203     * registered <code>ImageTranscoder</code>s that claim to be
1204     * able to transcode between the metadata of the given
1205     * <code>ImageReader</code> and <code>ImageWriter</code>.
1206     *
1207     * @param reader an <code>ImageReader</code>.
1208     * @param writer an <code>ImageWriter</code>.
1209     *
1210     * @return an <code>Iterator</code> containing
1211     * <code>ImageTranscoder</code>s.
1212     *
1213     * @exception IllegalArgumentException if <code>reader</code> or
1214     * <code>writer</code> is <code>null</code>.
1215     */

1216    public static Iterator JavaDoc<ImageTranscoder JavaDoc>
1217    getImageTranscoders(ImageReader JavaDoc reader, ImageWriter JavaDoc writer)
1218    {
1219        if (reader == null) {
1220            throw new IllegalArgumentException JavaDoc("reader == null!");
1221        }
1222        if (writer == null) {
1223            throw new IllegalArgumentException JavaDoc("writer == null!");
1224        }
1225        ImageReaderSpi JavaDoc readerSpi = reader.getOriginatingProvider();
1226        ImageWriterSpi JavaDoc writerSpi = writer.getOriginatingProvider();
1227        ServiceRegistry.Filter JavaDoc filter =
1228            new TranscoderFilter(readerSpi, writerSpi);
1229
1230        Iterator JavaDoc iter;
1231        // Ensure category is present
1232
try {
1233            iter = theRegistry.getServiceProviders(ImageTranscoderSpi JavaDoc.class,
1234                                            filter, true);
1235        } catch (IllegalArgumentException JavaDoc e) {
1236            return new HashSet JavaDoc().iterator();
1237        }
1238        return new ImageTranscoderIterator(iter);
1239    }
1240
1241    // All-in-one methods
1242

1243    /**
1244     * Returns a <code>BufferedImage</code> as the result of decoding
1245     * a supplied <code>File</code> with an <code>ImageReader</code>
1246     * chosen automatically from among those currently registered.
1247     * The <code>File</code> is wrapped in an
1248     * <code>ImageInputStream</code>. If no registered
1249     * <code>ImageReader</code> claims to be able to read the
1250     * resulting stream, <code>null</code> is returned.
1251     *
1252     * <p> The current cache settings from <code>getUseCache</code>and
1253     * <code>getCacheDirectory</code> will be used to control caching in the
1254     * <code>ImageInputStream</code> that is created.
1255     *
1256     * <p> Note that there is no <code>read</code> method that takes a
1257     * filename as a <code>String</code>; use this method instead after
1258     * creating a <code>File</code> from the filename.
1259     *
1260     * <p> This methods does not attempt to locate
1261     * <code>ImageReader</code>s that can read directly from a
1262     * <code>File</code>; that may be accomplished using
1263     * <code>IIORegistry</code> and <code>ImageReaderSpi</code>.
1264     *
1265     * @param input a <code>File</code> to read from.
1266     *
1267     * @return a <code>BufferedImage</code> containing the decoded
1268     * contents of the input, or <code>null</code>.
1269     *
1270     * @exception IllegalArgumentException if <code>input</code> is
1271     * <code>null</code>.
1272     * @exception IOException if an error occurs during reading.
1273     */

1274    public static BufferedImage JavaDoc read(File JavaDoc input) throws IOException JavaDoc {
1275        if (input == null) {
1276            throw new IllegalArgumentException JavaDoc("input == null!");
1277        }
1278        if (!input.canRead()) {
1279            throw new IIOException JavaDoc("Can't read input file!");
1280        }
1281
1282        ImageInputStream JavaDoc stream = createImageInputStream(input);
1283        if (stream == null) {
1284            throw new IIOException JavaDoc("Can't create an ImageInputStream!");
1285        }
1286        return read(stream);
1287    }
1288
1289    /**
1290     * Returns a <code>BufferedImage</code> as the result of decoding
1291     * a supplied <code>InputStream</code> with an <code>ImageReader</code>
1292     * chosen automatically from among those currently registered.
1293     * The <code>InputStream</code> is wrapped in an
1294     * <code>ImageInputStream</code>. If no registered
1295     * <code>ImageReader</code> claims to be able to read the
1296     * resulting stream, <code>null</code> is returned.
1297     *
1298     * <p> The current cache settings from <code>getUseCache</code>and
1299     * <code>getCacheDirectory</code> will be used to control caching in the
1300     * <code>ImageInputStream</code> that is created.
1301     *
1302     * <p> This methods does not attempt to locate
1303     * <code>ImageReader</code>s that can read directly from an
1304     * <code>InputStream</code>; that may be accomplished using
1305     * <code>IIORegistry</code> and <code>ImageReaderSpi</code>.
1306     *
1307     * @param input an <code>InputStream</code> to read from.
1308     *
1309     * @return a <code>BufferedImage</code> containing the decoded
1310     * contents of the input, or <code>null</code>.
1311     *
1312     * @exception IllegalArgumentException if <code>input</code> is
1313     * <code>null</code>.
1314     * @exception IOException if an error occurs during reading.
1315     */

1316    public static BufferedImage JavaDoc read(InputStream JavaDoc input) throws IOException JavaDoc {
1317        if (input == null) {
1318            throw new IllegalArgumentException JavaDoc("input == null!");
1319        }
1320
1321        ImageInputStream JavaDoc stream = createImageInputStream(input);
1322        return read(stream);
1323    }
1324
1325    /**
1326     * Returns a <code>BufferedImage</code> as the result of decoding
1327     * a supplied <code>URL</code> with an <code>ImageReader</code>
1328     * chosen automatically from among those currently registered. An
1329     * <code>InputStream</code> is obtained from the <code>URL</code>,
1330     * which is wrapped in an <code>ImageInputStream</code>. If no
1331     * registered <code>ImageReader</code> claims to be able to read
1332     * the resulting stream, <code>null</code> is returned.
1333     *
1334     * <p> The current cache settings from <code>getUseCache</code>and
1335     * <code>getCacheDirectory</code> will be used to control caching in the
1336     * <code>ImageInputStream</code> that is created.
1337     *
1338     * <p> This methods does not attempt to locate
1339     * <code>ImageReader</code>s that can read directly from a
1340     * <code>URL</code>; that may be accomplished using
1341     * <code>IIORegistry</code> and <code>ImageReaderSpi</code>.
1342     *
1343     * @param input a <code>URL</code> to read from.
1344     *
1345     * @return a <code>BufferedImage</code> containing the decoded
1346     * contents of the input, or <code>null</code>.
1347     *
1348     * @exception IllegalArgumentException if <code>input</code> is
1349     * <code>null</code>.
1350     * @exception IOException if an error occurs during reading.
1351     */

1352    public static BufferedImage JavaDoc read(URL JavaDoc input) throws IOException JavaDoc {
1353        if (input == null) {
1354            throw new IllegalArgumentException JavaDoc("input == null!");
1355        }
1356
1357        InputStream JavaDoc istream = null;
1358        try {
1359            istream = input.openStream();
1360        } catch (IOException JavaDoc e) {
1361            throw new IIOException JavaDoc("Can't get input stream from URL!", e);
1362        }
1363        ImageInputStream JavaDoc stream = createImageInputStream(istream);
1364        BufferedImage JavaDoc bi = read(stream);
1365        istream.close();
1366        return bi;
1367    }
1368
1369    /**
1370     * Returns a <code>BufferedImage</code> as the result of decoding
1371     * a supplied <code>ImageInputStream</code> with an
1372     * <code>ImageReader</code> chosen automatically from among those
1373     * currently registered. If no registered
1374     * <code>ImageReader</code> claims to be able to read the stream,
1375     * <code>null</code> is returned.
1376     *
1377     * @param stream an <code>ImageInputStream</code> to read from.
1378     *
1379     * @return a <code>BufferedImage</code> containing the decoded
1380     * contents of the input, or <code>null</code>.
1381     *
1382     * @exception IllegalArgumentException if <code>stream</code> is
1383     * <code>null</code>.
1384     * @exception IOException if an error occurs during reading.
1385     */

1386    public static BufferedImage JavaDoc read(ImageInputStream JavaDoc stream)
1387        throws IOException JavaDoc {
1388        if (stream == null) {
1389            throw new IllegalArgumentException JavaDoc("stream == null!");
1390        }
1391
1392        Iterator JavaDoc iter = getImageReaders(stream);
1393        if (!iter.hasNext()) {
1394            return null;
1395        }
1396
1397        ImageReader JavaDoc reader = (ImageReader JavaDoc)iter.next();
1398        ImageReadParam JavaDoc param = reader.getDefaultReadParam();
1399        reader.setInput(stream, true, true);
1400        BufferedImage JavaDoc bi = reader.read(0, param);
1401        stream.close();
1402        reader.dispose();
1403        return bi;
1404    }
1405
1406    /**
1407     * Writes an image using the an arbitrary <code>ImageWriter</code>
1408     * that supports the given format to an
1409     * <code>ImageOutputStream</code>. The image is written to the
1410     * <code>ImageOutputStream</code> starting at the current stream
1411     * pointer, overwriting existing stream data from that point
1412     * forward, if present.
1413     *
1414     * @param im a <code>RenderedImage</code> to be written.
1415     * @param formatName a <code>String</code> containg the informal
1416     * name of the format.
1417     * @param output an <code>ImageOutputStream</code> to be written to.
1418     *
1419     * @return <code>false</code> if no appropriate writer is found.
1420     *
1421     * @exception IllegalArgumentException if any parameter is
1422     * <code>null</code>.
1423     * @exception IOException if an error occurs during writing.
1424     */

1425    public static boolean write(RenderedImage JavaDoc im,
1426                                String JavaDoc formatName,
1427                                ImageOutputStream JavaDoc output) throws IOException JavaDoc {
1428        if (im == null) {
1429            throw new IllegalArgumentException JavaDoc("im == null!");
1430        }
1431        if (formatName == null) {
1432            throw new IllegalArgumentException JavaDoc("formatName == null!");
1433        }
1434        if (output == null) {
1435            throw new IllegalArgumentException JavaDoc("output == null!");
1436        }
1437
1438        ImageWriter JavaDoc writer = null;
1439        ImageTypeSpecifier JavaDoc type =
1440            ImageTypeSpecifier.createFromRenderedImage(im);
1441        Iterator JavaDoc iter = getImageWriters(type, formatName);
1442        if (iter.hasNext()) {
1443            writer = (ImageWriter JavaDoc)iter.next();
1444        }
1445        if (writer == null) {
1446            return false;
1447        }
1448
1449        writer.setOutput(output);
1450        writer.write(im);
1451        output.flush();
1452        writer.dispose();
1453        
1454        return true;
1455    }
1456
1457    /**
1458     * Writes an image using an arbitrary <code>ImageWriter</code>
1459     * that supports the given format to a <code>File</code>. If
1460     * there is already a <code>File</code> present, its contents are
1461     * discarded.
1462     *
1463     * @param im a <code>RenderedImage</code> to be written.
1464     * @param formatName a <code>String</code> containg the informal
1465     * name of the format.
1466     * @param output a <code>File</code> to be written to.
1467     *
1468     * @return <code>false</code> if no appropriate writer is found.
1469     *
1470     * @exception IllegalArgumentException if any parameter is
1471     * <code>null</code>.
1472     * @exception IOException if an error occurs during writing.
1473     */

1474    public static boolean write(RenderedImage JavaDoc im,
1475                                String JavaDoc formatName,
1476                                File JavaDoc output) throws IOException JavaDoc {
1477        if (output == null) {
1478            throw new IllegalArgumentException JavaDoc("output == null!");
1479        }
1480        ImageOutputStream JavaDoc stream = null;
1481        try {
1482            output.delete();
1483            stream = createImageOutputStream(output);
1484        } catch (IOException JavaDoc e) {
1485            throw new IIOException JavaDoc("Can't create output stream!", e);
1486        }
1487
1488        boolean val = write(im, formatName, stream);
1489        stream.close();
1490        return val;
1491    }
1492
1493    /**
1494     * Writes an image using an arbitrary <code>ImageWriter</code>
1495     * that supports the given format to an <code>OutputStream</code>.
1496     *
1497     * <p> The current cache settings from <code>getUseCache</code>and
1498     * <code>getCacheDirectory</code> will be used to control caching.
1499     *
1500     * @param im a <code>RenderedImage</code> to be written.
1501     * @param formatName a <code>String</code> containg the informal
1502     * name of the format.
1503     * @param output an <code>OutputStream</code> to be written to.
1504     *
1505     * @return <code>false</code> if no appropriate writer is found.
1506     *
1507     * @exception IllegalArgumentException if any parameter is
1508     * <code>null</code>.
1509     * @exception IOException if an error occurs during writing.
1510     */

1511    public static boolean write(RenderedImage JavaDoc im,
1512                                String JavaDoc formatName,
1513                                OutputStream JavaDoc output) throws IOException JavaDoc {
1514        if (output == null) {
1515            throw new IllegalArgumentException JavaDoc("output == null!");
1516        }
1517        ImageOutputStream JavaDoc stream = null;
1518        try {
1519            stream = createImageOutputStream(output);
1520        } catch (IOException JavaDoc e) {
1521            throw new IIOException JavaDoc("Can't create output stream!", e);
1522        }
1523
1524        boolean val = write(im, formatName, stream);
1525        stream.close();
1526        return val;
1527    }
1528}
1529
Popular Tags