Source Code Cross Referenced for ImageIO.java in  » 6.0-JDK-Core » image » javax » imageio » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
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
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » image » javax.imageio 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.imageio;
0027
0028        import java.awt.image.BufferedImage;
0029        import java.awt.image.RenderedImage;
0030        import java.io.File;
0031        import java.io.InputStream;
0032        import java.io.IOException;
0033        import java.io.OutputStream;
0034        import java.lang.reflect.Method;
0035        import java.net.URL;
0036        import java.security.AccessController;
0037        import java.util.Arrays;
0038        import java.util.Collections;
0039        import java.util.HashSet;
0040        import java.util.Iterator;
0041        import java.util.NoSuchElementException;
0042        import java.util.Set;
0043        import javax.imageio.spi.IIORegistry;
0044        import javax.imageio.spi.ImageReaderSpi;
0045        import javax.imageio.spi.ImageReaderWriterSpi;
0046        import javax.imageio.spi.ImageWriterSpi;
0047        import javax.imageio.spi.ImageInputStreamSpi;
0048        import javax.imageio.spi.ImageOutputStreamSpi;
0049        import javax.imageio.spi.ImageTranscoderSpi;
0050        import javax.imageio.spi.ServiceRegistry;
0051        import javax.imageio.stream.ImageInputStream;
0052        import javax.imageio.stream.ImageOutputStream;
0053        import sun.awt.AppContext;
0054        import sun.security.action.GetPropertyAction;
0055
0056        /**
0057         * A class containing static convenience methods for locating
0058         * <code>ImageReader</code>s and <code>ImageWriter</code>s, and
0059         * performing simple encoding and decoding.
0060         *
0061         * @version 0.5
0062         */
0063        public final class ImageIO {
0064
0065            private static final IIORegistry theRegistry = IIORegistry
0066                    .getDefaultInstance();
0067
0068            /**
0069             * Constructor is private to prevent instantiation.
0070             */
0071            private ImageIO() {
0072            }
0073
0074            /**
0075             * Scans for plug-ins on the application class path,
0076             * loads their service provider classes, and registers a service
0077             * provider instance for each one found with the
0078             * <code>IIORegistry</code>.
0079             * 
0080             * <p>This method is needed because the application class path can
0081             * theoretically change, or additional plug-ins may become available.
0082             * Rather than re-scanning the classpath on every invocation of the
0083             * API, the class path is scanned automatically only on the first
0084             * invocation. Clients can call this method to prompt a re-scan.
0085             * Thus this method need only be invoked by sophisticated applications
0086             * which dynamically make new plug-ins available at runtime.
0087             *
0088             * <p> The <code>getResources</code> method of the context
0089             * <code>ClassLoader</code> is used locate JAR files containing
0090             * files named
0091             * <code>META-INF/services/javax.imageio.spi.</code><i>classname</i>,
0092             * where <i>classname</i> is one of <code>ImageReaderSpi</code>,
0093             * <code>ImageWriterSpi</code>, <code>ImageTranscoderSpi</code>,
0094             * <code>ImageInputStreamSpi</code>, or
0095             * <code>ImageOutputStreamSpi</code>, along the application class
0096             * path.
0097             *
0098             * <p> The contents of the located files indicate the names of
0099             * actual implementation classes which implement the
0100             * aforementioned service provider interfaces; the default class
0101             * loader is then used to load each of these classes and to
0102             * instantiate an instance of each class, which is then placed
0103             * into the registry for later retrieval.
0104             *
0105             * <p> The exact set of locations searched depends on the
0106             * implementation of the Java runtime enviroment.
0107             * 
0108             * @see ClassLoader#getResources
0109             */
0110            public static void scanForPlugins() {
0111                theRegistry.registerApplicationClasspathSpis();
0112            }
0113
0114            // ImageInputStreams
0115
0116            /**
0117             * A class to hold information about caching.  Each
0118             * <code>ThreadGroup</code> will have its own copy
0119             * via the <code>AppContext</code> mechanism.
0120             */
0121            static class CacheInfo {
0122                boolean useCache = true;
0123                File cacheDirectory = null;
0124                Boolean hasPermission = null;
0125
0126                public CacheInfo() {
0127                }
0128
0129                public boolean getUseCache() {
0130                    return useCache;
0131                }
0132
0133                public void setUseCache(boolean useCache) {
0134                    this .useCache = useCache;
0135                }
0136
0137                public File getCacheDirectory() {
0138                    return cacheDirectory;
0139                }
0140
0141                public void setCacheDirectory(File cacheDirectory) {
0142                    this .cacheDirectory = cacheDirectory;
0143                }
0144
0145                public Boolean getHasPermission() {
0146                    return hasPermission;
0147                }
0148
0149                public void setHasPermission(Boolean hasPermission) {
0150                    this .hasPermission = hasPermission;
0151                }
0152            }
0153
0154            /**
0155             * Returns the <code>CacheInfo</code> object associated with this
0156             * <code>ThreadGroup</code>.
0157             */
0158            private static synchronized CacheInfo getCacheInfo() {
0159                AppContext context = AppContext.getAppContext();
0160                CacheInfo info = (CacheInfo) context.get(CacheInfo.class);
0161                if (info == null) {
0162                    info = new CacheInfo();
0163                    context.put(CacheInfo.class, info);
0164                }
0165                return info;
0166            }
0167
0168            /**
0169             * Returns the default temporary (cache) directory as defined by the
0170             * java.io.tmpdir system property.
0171             */
0172            private static String getTempDir() {
0173                GetPropertyAction a = new GetPropertyAction("java.io.tmpdir");
0174                return (String) AccessController.doPrivileged(a);
0175            }
0176
0177            /**
0178             * Determines whether the caller has write access to the cache
0179             * directory, stores the result in the <code>CacheInfo</code> object,
0180             * and returns the decision.  This method helps to prevent mysterious
0181             * SecurityExceptions to be thrown when this convenience class is used
0182             * in an applet, for example.
0183             */
0184            private static boolean hasCachePermission() {
0185                Boolean hasPermission = getCacheInfo().getHasPermission();
0186
0187                if (hasPermission != null) {
0188                    return hasPermission.booleanValue();
0189                } else {
0190                    try {
0191                        SecurityManager security = System.getSecurityManager();
0192                        if (security != null) {
0193                            File cachedir = getCacheDirectory();
0194                            String cachepath;
0195
0196                            if (cachedir != null) {
0197                                cachepath = cachedir.getPath();
0198                            } else {
0199                                cachepath = getTempDir();
0200
0201                                if (cachepath == null) {
0202                                    getCacheInfo().setHasPermission(
0203                                            Boolean.FALSE);
0204                                    return false;
0205                                }
0206                            }
0207
0208                            security.checkWrite(cachepath);
0209                        }
0210                    } catch (SecurityException e) {
0211                        getCacheInfo().setHasPermission(Boolean.FALSE);
0212                        return false;
0213                    }
0214
0215                    getCacheInfo().setHasPermission(Boolean.TRUE);
0216                    return true;
0217                }
0218            }
0219
0220            /**
0221             * Sets a flag indicating whether a disk-based cache file should
0222             * be used when creating <code>ImageInputStream</code>s and
0223             * <code>ImageOutputStream</code>s.
0224             *
0225             * <p> When reading from a standard <code>InputStream</code>>, it
0226             * may be necessary to save previously read information in a cache
0227             * since the underlying stream does not allow data to be re-read.
0228             * Similarly, when writing to a standard
0229             * <code>OutputStream</code>, a cache may be used to allow a
0230             * previously written value to be changed before flushing it to
0231             * the final destination.
0232             *
0233             * <p> The cache may reside in main memory or on disk.  Setting
0234             * this flag to <code>false</code> disallows the use of disk for
0235             * future streams, which may be advantageous when working with
0236             * small images, as the overhead of creating and destroying files
0237             * is removed.
0238             *
0239             * <p> On startup, the value is set to <code>true</code>.
0240             *
0241             * @param useCache a <code>boolean</code> indicating whether a
0242             * cache file should be used, in cases where it is optional.
0243             *
0244             * @see #getUseCache
0245             */
0246            public static void setUseCache(boolean useCache) {
0247                getCacheInfo().setUseCache(useCache);
0248            }
0249
0250            /**
0251             * Returns the current value set by <code>setUseCache</code>, or
0252             * <code>true</code> if no explicit setting has been made.
0253             *
0254             * @return true if a disk-based cache may be used for
0255             * <code>ImageInputStream</code>s and
0256             * <code>ImageOutputStream</code>s.
0257             *
0258             * @see #setUseCache
0259             */
0260            public static boolean getUseCache() {
0261                return getCacheInfo().getUseCache();
0262            }
0263
0264            /**
0265             * Sets the directory where cache files are to be created.  A
0266             * value of <code>null</code> indicates that the system-dependent
0267             * default temporary-file directory is to be used.  If
0268             * <code>getUseCache</code> returns false, this value is ignored.
0269             *
0270             * @param cacheDirectory a <code>File</code> specifying a directory.
0271             *
0272             * @see File#createTempFile(String, String, File)
0273             *
0274             * @exception SecurityException if the security manager denies
0275             * access to the directory.
0276             * @exception IllegalArgumentException if <code>cacheDir</code> is
0277             * non-<code>null</code> but is not a directory.
0278             *
0279             * @see #getCacheDirectory
0280             */
0281            public static void setCacheDirectory(File cacheDirectory) {
0282                if ((cacheDirectory != null) && !(cacheDirectory.isDirectory())) {
0283                    throw new IllegalArgumentException("Not a directory!");
0284                }
0285                getCacheInfo().setCacheDirectory(cacheDirectory);
0286                getCacheInfo().setHasPermission(null);
0287            }
0288
0289            /**
0290             * Returns the current value set by
0291             * <code>setCacheDirectory</code>, or <code>null</code> if no
0292             * explicit setting has been made.
0293             *
0294             * @return a <code>File</code> indicating the directory where
0295             * cache files will be created, or <code>null</code> to indicate
0296             * the system-dependent default temporary-file directory.
0297             *
0298             * @see #setCacheDirectory
0299             */
0300            public static File getCacheDirectory() {
0301                return getCacheInfo().getCacheDirectory();
0302            }
0303
0304            /**
0305             * Returns an <code>ImageInputStream</code> that will take its
0306             * input from the given <code>Object</code>.  The set of
0307             * <code>ImageInputStreamSpi</code>s registered with the
0308             * <code>IIORegistry</code> class is queried and the first one
0309             * that is able to take input from the supplied object is used to
0310             * create the returned <code>ImageInputStream</code>.  If no
0311             * suitable <code>ImageInputStreamSpi</code> exists,
0312             * <code>null</code> is returned.
0313             *
0314             * <p> The current cache settings from <code>getUseCache</code>and
0315             * <code>getCacheDirectory</code> will be used to control caching.
0316             *
0317             * @param input an <code>Object</code> to be used as an input
0318             * source, such as a <code>File</code>, readable
0319             * <code>RandomAccessFile</code>, or <code>InputStream</code>.
0320             *
0321             * @return an <code>ImageInputStream</code>, or <code>null</code>.
0322             *
0323             * @exception IllegalArgumentException if <code>input</code>
0324             * is <code>null</code>.
0325             * @exception IOException if a cache file is needed but cannot be
0326             * created.
0327             *
0328             * @see javax.imageio.spi.ImageInputStreamSpi
0329             */
0330            public static ImageInputStream createImageInputStream(Object input)
0331                    throws IOException {
0332                if (input == null) {
0333                    throw new IllegalArgumentException("input == null!");
0334                }
0335
0336                Iterator iter;
0337                // Ensure category is present
0338                try {
0339                    iter = theRegistry.getServiceProviders(
0340                            ImageInputStreamSpi.class, true);
0341                } catch (IllegalArgumentException e) {
0342                    return null;
0343                }
0344
0345                boolean usecache = getUseCache() && hasCachePermission();
0346
0347                while (iter.hasNext()) {
0348                    ImageInputStreamSpi spi = (ImageInputStreamSpi) iter.next();
0349                    if (spi.getInputClass().isInstance(input)) {
0350                        try {
0351                            return spi.createInputStreamInstance(input,
0352                                    usecache, getCacheDirectory());
0353                        } catch (IOException e) {
0354                            throw new IIOException("Can't create cache file!",
0355                                    e);
0356                        }
0357                    }
0358                }
0359
0360                return null;
0361            }
0362
0363            // ImageOutputStreams
0364
0365            /**
0366             * Returns an <code>ImageOutputStream</code> that will send its
0367             * output to the given <code>Object</code>.  The set of
0368             * <code>ImageOutputStreamSpi</code>s registered with the
0369             * <code>IIORegistry</code> class is queried and the first one
0370             * that is able to send output from the supplied object is used to
0371             * create the returned <code>ImageOutputStream</code>.  If no
0372             * suitable <code>ImageOutputStreamSpi</code> exists,
0373             * <code>null</code> is returned.
0374             *
0375             * <p> The current cache settings from <code>getUseCache</code>and
0376             * <code>getCacheDirectory</code> will be used to control caching.
0377             *
0378             * @param output an <code>Object</code> to be used as an output
0379             * destination, such as a <code>File</code>, writable
0380             * <code>RandomAccessFile</code>, or <code>OutputStream</code>.
0381             *
0382             * @return an <code>ImageOutputStream</code>, or
0383             * <code>null</code>.
0384             *
0385             * @exception IllegalArgumentException if <code>output</code> is
0386             * <code>null</code>.
0387             * @exception IOException if a cache file is needed but cannot be
0388             * created.
0389             *
0390             * @see javax.imageio.spi.ImageOutputStreamSpi
0391             */
0392            public static ImageOutputStream createImageOutputStream(
0393                    Object output) throws IOException {
0394                if (output == null) {
0395                    throw new IllegalArgumentException("output == null!");
0396                }
0397
0398                Iterator iter;
0399                // Ensure category is present
0400                try {
0401                    iter = theRegistry.getServiceProviders(
0402                            ImageOutputStreamSpi.class, true);
0403                } catch (IllegalArgumentException e) {
0404                    return null;
0405                }
0406
0407                boolean usecache = getUseCache() && hasCachePermission();
0408
0409                while (iter.hasNext()) {
0410                    ImageOutputStreamSpi spi = (ImageOutputStreamSpi) iter
0411                            .next();
0412                    if (spi.getOutputClass().isInstance(output)) {
0413                        try {
0414                            return spi.createOutputStreamInstance(output,
0415                                    usecache, getCacheDirectory());
0416                        } catch (IOException e) {
0417                            throw new IIOException("Can't create cache file!",
0418                                    e);
0419                        }
0420                    }
0421                }
0422
0423                return null;
0424            }
0425
0426            private static enum SpiInfo {
0427                FORMAT_NAMES {
0428                    @Override
0429                    String[] info(ImageReaderWriterSpi spi) {
0430                        return spi.getFormatNames();
0431                    }
0432                },
0433                MIME_TYPES {
0434                    @Override
0435                    String[] info(ImageReaderWriterSpi spi) {
0436                        return spi.getMIMETypes();
0437                    }
0438                },
0439                FILE_SUFFIXES {
0440                    @Override
0441                    String[] info(ImageReaderWriterSpi spi) {
0442                        return spi.getFileSuffixes();
0443                    }
0444                };
0445
0446                abstract String[] info(ImageReaderWriterSpi spi);
0447            }
0448
0449            private static <S extends ImageReaderWriterSpi> String[] getReaderWriterInfo(
0450                    Class<S> spiClass, SpiInfo spiInfo) {
0451                // Ensure category is present
0452                Iterator<S> iter;
0453                try {
0454                    iter = theRegistry.getServiceProviders(spiClass, true);
0455                } catch (IllegalArgumentException e) {
0456                    return new String[0];
0457                }
0458
0459                HashSet<String> s = new HashSet<String>();
0460                while (iter.hasNext()) {
0461                    ImageReaderWriterSpi spi = iter.next();
0462                    Collections.addAll(s, spiInfo.info(spi));
0463                }
0464
0465                return s.toArray(new String[s.size()]);
0466            }
0467
0468            // Readers
0469
0470            /**
0471             * Returns an array of <code>String</code>s listing all of the
0472             * informal format names understood by the current set of registered
0473             * readers.
0474             *
0475             * @return an array of <code>String</code>s.
0476             */
0477            public static String[] getReaderFormatNames() {
0478                return getReaderWriterInfo(ImageReaderSpi.class,
0479                        SpiInfo.FORMAT_NAMES);
0480            }
0481
0482            /**
0483             * Returns an array of <code>String</code>s listing all of the
0484             * MIME types understood by the current set of registered
0485             * readers.
0486             *
0487             * @return an array of <code>String</code>s.
0488             */
0489            public static String[] getReaderMIMETypes() {
0490                return getReaderWriterInfo(ImageReaderSpi.class,
0491                        SpiInfo.MIME_TYPES);
0492            }
0493
0494            /**
0495             * Returns an array of <code>String</code>s listing all of the
0496             * file suffixes associated with the formats understood
0497             * by the current set of registered readers.
0498             *
0499             * @return an array of <code>String</code>s.
0500             * @since 1.6
0501             */
0502            public static String[] getReaderFileSuffixes() {
0503                return getReaderWriterInfo(ImageReaderSpi.class,
0504                        SpiInfo.FILE_SUFFIXES);
0505            }
0506
0507            static class ImageReaderIterator implements  Iterator<ImageReader> {
0508                // Contains ImageReaderSpis
0509                public Iterator iter;
0510
0511                public ImageReaderIterator(Iterator iter) {
0512                    this .iter = iter;
0513                }
0514
0515                public boolean hasNext() {
0516                    return iter.hasNext();
0517                }
0518
0519                public ImageReader next() {
0520                    ImageReaderSpi spi = null;
0521                    try {
0522                        spi = (ImageReaderSpi) iter.next();
0523                        return spi.createReaderInstance();
0524                    } catch (IOException e) {
0525                        // Deregister the spi in this case, but only as
0526                        // an ImageReaderSpi
0527                        theRegistry.deregisterServiceProvider(spi,
0528                                ImageReaderSpi.class);
0529                    }
0530                    return null;
0531                }
0532
0533                public void remove() {
0534                    throw new UnsupportedOperationException();
0535                }
0536            }
0537
0538            static class CanDecodeInputFilter implements  ServiceRegistry.Filter {
0539
0540                Object input;
0541
0542                public CanDecodeInputFilter(Object input) {
0543                    this .input = input;
0544                }
0545
0546                public boolean filter(Object elt) {
0547                    try {
0548                        ImageReaderSpi spi = (ImageReaderSpi) elt;
0549                        ImageInputStream stream = null;
0550                        if (input instanceof  ImageInputStream) {
0551                            stream = (ImageInputStream) input;
0552                        }
0553
0554                        // Perform mark/reset as a defensive measure
0555                        // even though plug-ins are supposed to take
0556                        // care of it.
0557                        boolean canDecode = false;
0558                        if (stream != null) {
0559                            stream.mark();
0560                        }
0561                        canDecode = spi.canDecodeInput(input);
0562                        if (stream != null) {
0563                            stream.reset();
0564                        }
0565
0566                        return canDecode;
0567                    } catch (IOException e) {
0568                        return false;
0569                    }
0570                }
0571            }
0572
0573            static class CanEncodeImageAndFormatFilter implements 
0574                    ServiceRegistry.Filter {
0575
0576                ImageTypeSpecifier type;
0577                String formatName;
0578
0579                public CanEncodeImageAndFormatFilter(ImageTypeSpecifier type,
0580                        String formatName) {
0581                    this .type = type;
0582                    this .formatName = formatName;
0583                }
0584
0585                public boolean filter(Object elt) {
0586                    ImageWriterSpi spi = (ImageWriterSpi) elt;
0587                    return Arrays.asList(spi.getFormatNames()).contains(
0588                            formatName)
0589                            && spi.canEncodeImage(type);
0590                }
0591            }
0592
0593            static class ContainsFilter implements  ServiceRegistry.Filter {
0594
0595                Method method;
0596                String name;
0597
0598                // method returns an array of Strings
0599                public ContainsFilter(Method method, String name) {
0600                    this .method = method;
0601                    this .name = name;
0602                }
0603
0604                public boolean filter(Object elt) {
0605                    try {
0606                        return contains((String[]) method.invoke(elt), name);
0607                    } catch (Exception e) {
0608                        return false;
0609                    }
0610                }
0611            }
0612
0613            /**
0614             * Returns an <code>Iterator</code> containing all currently
0615             * registered <code>ImageReader</code>s that claim to be able to
0616             * decode the supplied <code>Object</code>, typically an
0617             * <code>ImageInputStream</code>.
0618             *
0619             * <p> The stream position is left at its prior position upon
0620             * exit from this method.
0621             *
0622             * @param input an <code>ImageInputStream</code> or other
0623             * <code>Object</code> containing encoded image data.
0624             *
0625             * @return an <code>Iterator</code> containing <code>ImageReader</code>s.
0626             *
0627             * @exception IllegalArgumentException if <code>input</code> is
0628             * <code>null</code>.
0629             *
0630             * @see javax.imageio.spi.ImageReaderSpi#canDecodeInput
0631             */
0632            public static Iterator<ImageReader> getImageReaders(Object input) {
0633                if (input == null) {
0634                    throw new IllegalArgumentException("input == null!");
0635                }
0636                Iterator iter;
0637                // Ensure category is present
0638                try {
0639                    iter = theRegistry.getServiceProviders(
0640                            ImageReaderSpi.class, new CanDecodeInputFilter(
0641                                    input), true);
0642                } catch (IllegalArgumentException e) {
0643                    return Collections.emptyIterator();
0644                }
0645
0646                return new ImageReaderIterator(iter);
0647            }
0648
0649            private static Method readerFormatNamesMethod;
0650            private static Method readerFileSuffixesMethod;
0651            private static Method readerMIMETypesMethod;
0652            private static Method writerFormatNamesMethod;
0653            private static Method writerFileSuffixesMethod;
0654            private static Method writerMIMETypesMethod;
0655
0656            static {
0657                try {
0658                    readerFormatNamesMethod = ImageReaderSpi.class
0659                            .getMethod("getFormatNames");
0660                    readerFileSuffixesMethod = ImageReaderSpi.class
0661                            .getMethod("getFileSuffixes");
0662                    readerMIMETypesMethod = ImageReaderSpi.class
0663                            .getMethod("getMIMETypes");
0664
0665                    writerFormatNamesMethod = ImageWriterSpi.class
0666                            .getMethod("getFormatNames");
0667                    writerFileSuffixesMethod = ImageWriterSpi.class
0668                            .getMethod("getFileSuffixes");
0669                    writerMIMETypesMethod = ImageWriterSpi.class
0670                            .getMethod("getMIMETypes");
0671                } catch (NoSuchMethodException e) {
0672                    e.printStackTrace();
0673                }
0674            }
0675
0676            /**
0677             * Returns an <code>Iterator</code> containing all currently
0678             * registered <code>ImageReader</code>s that claim to be able to
0679             * decode the named format.
0680             *
0681             * @param formatName a <code>String</code> containing the informal
0682             * name of a format (<i>e.g.</i>, "jpeg" or "tiff".
0683             *
0684             * @return an <code>Iterator</code> containing
0685             * <code>ImageReader</code>s.
0686             *
0687             * @exception IllegalArgumentException if <code>formatName</code>
0688             * is <code>null</code>.
0689             *
0690             * @see javax.imageio.spi.ImageReaderSpi#getFormatNames
0691             */
0692            public static Iterator<ImageReader> getImageReadersByFormatName(
0693                    String formatName) {
0694                if (formatName == null) {
0695                    throw new IllegalArgumentException("formatName == null!");
0696                }
0697                Iterator iter;
0698                // Ensure category is present
0699                try {
0700                    iter = theRegistry.getServiceProviders(
0701                            ImageReaderSpi.class, new ContainsFilter(
0702                                    readerFormatNamesMethod, formatName), true);
0703                } catch (IllegalArgumentException e) {
0704                    return Collections.emptyIterator();
0705                }
0706                return new ImageReaderIterator(iter);
0707            }
0708
0709            /**
0710             * Returns an <code>Iterator</code> containing all currently
0711             * registered <code>ImageReader</code>s that claim to be able to
0712             * decode files with the given suffix.
0713             *
0714             * @param fileSuffix a <code>String</code> containing a file
0715             * suffix (<i>e.g.</i>, "jpg" or "tiff").
0716             *
0717             * @return an <code>Iterator</code> containing
0718             * <code>ImageReader</code>s.
0719             *
0720             * @exception IllegalArgumentException if <code>fileSuffix</code>
0721             * is <code>null</code>.
0722             *
0723             * @see javax.imageio.spi.ImageReaderSpi#getFileSuffixes
0724             */
0725            public static Iterator<ImageReader> getImageReadersBySuffix(
0726                    String fileSuffix) {
0727                if (fileSuffix == null) {
0728                    throw new IllegalArgumentException("fileSuffix == null!");
0729                }
0730                // Ensure category is present
0731                Iterator iter;
0732                try {
0733                    iter = theRegistry
0734                            .getServiceProviders(ImageReaderSpi.class,
0735                                    new ContainsFilter(
0736                                            readerFileSuffixesMethod,
0737                                            fileSuffix), true);
0738                } catch (IllegalArgumentException e) {
0739                    return Collections.emptyIterator();
0740                }
0741                return new ImageReaderIterator(iter);
0742            }
0743
0744            /**
0745             * Returns an <code>Iterator</code> containing all currently
0746             * registered <code>ImageReader</code>s that claim to be able to
0747             * decode files with the given MIME type.
0748             *
0749             * @param MIMEType a <code>String</code> containing a file
0750             * suffix (<i>e.g.</i>, "image/jpeg" or "image/x-bmp").
0751             *
0752             * @return an <code>Iterator</code> containing
0753             * <code>ImageReader</code>s.
0754             *
0755             * @exception IllegalArgumentException if <code>MIMEType</code> is
0756             * <code>null</code>.
0757             *
0758             * @see javax.imageio.spi.ImageReaderSpi#getMIMETypes
0759             */
0760            public static Iterator<ImageReader> getImageReadersByMIMEType(
0761                    String MIMEType) {
0762                if (MIMEType == null) {
0763                    throw new IllegalArgumentException("MIMEType == null!");
0764                }
0765                // Ensure category is present
0766                Iterator iter;
0767                try {
0768                    iter = theRegistry.getServiceProviders(
0769                            ImageReaderSpi.class, new ContainsFilter(
0770                                    readerMIMETypesMethod, MIMEType), true);
0771                } catch (IllegalArgumentException e) {
0772                    return Collections.emptyIterator();
0773                }
0774                return new ImageReaderIterator(iter);
0775            }
0776
0777            // Writers
0778
0779            /**
0780             * Returns an array of <code>String</code>s listing all of the
0781             * informal format names understood by the current set of registered
0782             * writers.
0783             *
0784             * @return an array of <code>String</code>s.
0785             */
0786            public static String[] getWriterFormatNames() {
0787                return getReaderWriterInfo(ImageWriterSpi.class,
0788                        SpiInfo.FORMAT_NAMES);
0789            }
0790
0791            /**
0792             * Returns an array of <code>String</code>s listing all of the
0793             * MIME types understood by the current set of registered
0794             * writers.
0795             *
0796             * @return an array of <code>String</code>s.
0797             */
0798            public static String[] getWriterMIMETypes() {
0799                return getReaderWriterInfo(ImageWriterSpi.class,
0800                        SpiInfo.MIME_TYPES);
0801            }
0802
0803            /**
0804             * Returns an array of <code>String</code>s listing all of the
0805             * file suffixes associated with the formats understood
0806             * by the current set of registered writers.
0807             *
0808             * @return an array of <code>String</code>s.
0809             * @since 1.6
0810             */
0811            public static String[] getWriterFileSuffixes() {
0812                return getReaderWriterInfo(ImageWriterSpi.class,
0813                        SpiInfo.FILE_SUFFIXES);
0814            }
0815
0816            static class ImageWriterIterator implements  Iterator<ImageWriter> {
0817                // Contains ImageWriterSpis
0818                public Iterator iter;
0819
0820                public ImageWriterIterator(Iterator iter) {
0821                    this .iter = iter;
0822                }
0823
0824                public boolean hasNext() {
0825                    return iter.hasNext();
0826                }
0827
0828                public ImageWriter next() {
0829                    ImageWriterSpi spi = null;
0830                    try {
0831                        spi = (ImageWriterSpi) iter.next();
0832                        return spi.createWriterInstance();
0833                    } catch (IOException e) {
0834                        // Deregister the spi in this case, but only as a writerSpi
0835                        theRegistry.deregisterServiceProvider(spi,
0836                                ImageWriterSpi.class);
0837                    }
0838                    return null;
0839                }
0840
0841                public void remove() {
0842                    throw new UnsupportedOperationException();
0843                }
0844            }
0845
0846            private static boolean contains(String[] names, String name) {
0847                for (int i = 0; i < names.length; i++) {
0848                    if (name.equalsIgnoreCase(names[i])) {
0849                        return true;
0850                    }
0851                }
0852
0853                return false;
0854            }
0855
0856            /**
0857             * Returns an <code>Iterator</code> containing all currently
0858             * registered <code>ImageWriter</code>s that claim to be able to
0859             * encode the named format.
0860             *
0861             * @param formatName a <code>String</code> containing the informal
0862             * name of a format (<i>e.g.</i>, "jpeg" or "tiff".
0863             *
0864             * @return an <code>Iterator</code> containing
0865             * <code>ImageWriter</code>s.
0866             *
0867             * @exception IllegalArgumentException if <code>formatName</code> is
0868             * <code>null</code>.
0869             *
0870             * @see javax.imageio.spi.ImageWriterSpi#getFormatNames
0871             */
0872            public static Iterator<ImageWriter> getImageWritersByFormatName(
0873                    String formatName) {
0874                if (formatName == null) {
0875                    throw new IllegalArgumentException("formatName == null!");
0876                }
0877                Iterator iter;
0878                // Ensure category is present
0879                try {
0880                    iter = theRegistry.getServiceProviders(
0881                            ImageWriterSpi.class, new ContainsFilter(
0882                                    writerFormatNamesMethod, formatName), true);
0883                } catch (IllegalArgumentException e) {
0884                    return Collections.emptyIterator();
0885                }
0886                return new ImageWriterIterator(iter);
0887            }
0888
0889            /**
0890             * Returns an <code>Iterator</code> containing all currently
0891             * registered <code>ImageWriter</code>s that claim to be able to
0892             * encode files with the given suffix.
0893             *
0894             * @param fileSuffix a <code>String</code> containing a file
0895             * suffix (<i>e.g.</i>, "jpg" or "tiff").
0896             *
0897             * @return an <code>Iterator</code> containing <code>ImageWriter</code>s.
0898             *
0899             * @exception IllegalArgumentException if <code>fileSuffix</code> is
0900             * <code>null</code>.
0901             *
0902             * @see javax.imageio.spi.ImageWriterSpi#getFileSuffixes
0903             */
0904            public static Iterator<ImageWriter> getImageWritersBySuffix(
0905                    String fileSuffix) {
0906                if (fileSuffix == null) {
0907                    throw new IllegalArgumentException("fileSuffix == null!");
0908                }
0909                Iterator iter;
0910                // Ensure category is present
0911                try {
0912                    iter = theRegistry
0913                            .getServiceProviders(ImageWriterSpi.class,
0914                                    new ContainsFilter(
0915                                            writerFileSuffixesMethod,
0916                                            fileSuffix), true);
0917                } catch (IllegalArgumentException e) {
0918                    return Collections.emptyIterator();
0919                }
0920                return new ImageWriterIterator(iter);
0921            }
0922
0923            /**
0924             * Returns an <code>Iterator</code> containing all currently
0925             * registered <code>ImageWriter</code>s that claim to be able to
0926             * encode files with the given MIME type.
0927             *
0928             * @param MIMEType a <code>String</code> containing a file
0929             * suffix (<i>e.g.</i>, "image/jpeg" or "image/x-bmp").
0930             *
0931             * @return an <code>Iterator</code> containing <code>ImageWriter</code>s.
0932             *
0933             * @exception IllegalArgumentException if <code>MIMEType</code> is
0934             * <code>null</code>.
0935             *
0936             * @see javax.imageio.spi.ImageWriterSpi#getMIMETypes
0937             */
0938            public static Iterator<ImageWriter> getImageWritersByMIMEType(
0939                    String MIMEType) {
0940                if (MIMEType == null) {
0941                    throw new IllegalArgumentException("MIMEType == null!");
0942                }
0943                Iterator iter;
0944                // Ensure category is present
0945                try {
0946                    iter = theRegistry.getServiceProviders(
0947                            ImageWriterSpi.class, new ContainsFilter(
0948                                    writerMIMETypesMethod, MIMEType), true);
0949                } catch (IllegalArgumentException e) {
0950                    return Collections.emptyIterator();
0951                }
0952                return new ImageWriterIterator(iter);
0953            }
0954
0955            /**
0956             * Returns an <code>ImageWriter</code>corresponding to the given
0957             * <code>ImageReader</code>, if there is one, or <code>null</code>
0958             * if the plug-in for this <code>ImageReader</code> does not
0959             * specify a corresponding <code>ImageWriter</code>, or if the
0960             * given <code>ImageReader</code> is not registered.  This
0961             * mechanism may be used to obtain an <code>ImageWriter</code>
0962             * that will understand the internal structure of non-pixel
0963             * metadata (as encoded by <code>IIOMetadata</code> objects)
0964             * generated by the <code>ImageReader</code>.  By obtaining this
0965             * data from the <code>ImageReader</code> and passing it on to the
0966             * <code>ImageWriter</code> obtained with this method, a client
0967             * program can read an image, modify it in some way, and write it
0968             * back out preserving all metadata, without having to understand
0969             * anything about the structure of the metadata, or even about
0970             * the image format.  Note that this method returns the
0971             * "preferred" writer, which is the first in the list returned by
0972             * <code>javax.imageio.spi.ImageReaderSpi.getImageWriterSpiNames()</code>.
0973             *
0974             * @param reader an instance of a registered <code>ImageReader</code>.
0975             *
0976             * @return an <code>ImageWriter</code>, or null.
0977             *
0978             * @exception IllegalArgumentException if <code>reader</code> is
0979             * <code>null</code>.
0980             *
0981             * @see #getImageReader(ImageWriter)
0982             * @see javax.imageio.spi.ImageReaderSpi#getImageWriterSpiNames()
0983             */
0984            public static ImageWriter getImageWriter(ImageReader reader) {
0985                if (reader == null) {
0986                    throw new IllegalArgumentException("reader == null!");
0987                }
0988
0989                ImageReaderSpi readerSpi = reader.getOriginatingProvider();
0990                if (readerSpi == null) {
0991                    Iterator readerSpiIter;
0992                    // Ensure category is present
0993                    try {
0994                        readerSpiIter = theRegistry.getServiceProviders(
0995                                ImageReaderSpi.class, false);
0996                    } catch (IllegalArgumentException e) {
0997                        return null;
0998                    }
0999
1000                    while (readerSpiIter.hasNext()) {
1001                        ImageReaderSpi temp = (ImageReaderSpi) readerSpiIter
1002                                .next();
1003                        if (temp.isOwnReader(reader)) {
1004                            readerSpi = temp;
1005                            break;
1006                        }
1007                    }
1008                    if (readerSpi == null) {
1009                        return null;
1010                    }
1011                }
1012
1013                String[] writerNames = readerSpi.getImageWriterSpiNames();
1014                if (writerNames == null) {
1015                    return null;
1016                }
1017
1018                Class writerSpiClass = null;
1019                try {
1020                    writerSpiClass = Class.forName(writerNames[0], true,
1021                            ClassLoader.getSystemClassLoader());
1022                } catch (ClassNotFoundException e) {
1023                    return null;
1024                }
1025
1026                ImageWriterSpi writerSpi = (ImageWriterSpi) theRegistry
1027                        .getServiceProviderByClass(writerSpiClass);
1028                if (writerSpi == null) {
1029                    return null;
1030                }
1031
1032                try {
1033                    return writerSpi.createWriterInstance();
1034                } catch (IOException e) {
1035                    // Deregister the spi in this case, but only as a writerSpi
1036                    theRegistry.deregisterServiceProvider(writerSpi,
1037                            ImageWriterSpi.class);
1038                    return null;
1039                }
1040            }
1041
1042            /**
1043             * Returns an <code>ImageReader</code>corresponding to the given
1044             * <code>ImageWriter</code>, if there is one, or <code>null</code>
1045             * if the plug-in for this <code>ImageWriter</code> does not
1046             * specify a corresponding <code>ImageReader</code>, or if the
1047             * given <code>ImageWriter</code> is not registered.  This method
1048             * is provided principally for symmetry with
1049             * <code>getImageWriter(ImageReader)</code>.  Note that this
1050             * method returns the "preferred" reader, which is the first in
1051             * the list returned by
1052             * javax.imageio.spi.ImageWriterSpi.<code>getImageReaderSpiNames()</code>.
1053             *
1054             * @param writer an instance of a registered <code>ImageWriter</code>.
1055             *
1056             * @return an <code>ImageReader</code>, or null.
1057             *
1058             * @exception IllegalArgumentException if <code>writer</code> is
1059             * <code>null</code>.
1060             *
1061             * @see #getImageWriter(ImageReader)
1062             * @see javax.imageio.spi.ImageWriterSpi#getImageReaderSpiNames()
1063             */
1064            public static ImageReader getImageReader(ImageWriter writer) {
1065                if (writer == null) {
1066                    throw new IllegalArgumentException("writer == null!");
1067                }
1068
1069                ImageWriterSpi writerSpi = writer.getOriginatingProvider();
1070                if (writerSpi == null) {
1071                    Iterator writerSpiIter;
1072                    // Ensure category is present
1073                    try {
1074                        writerSpiIter = theRegistry.getServiceProviders(
1075                                ImageWriterSpi.class, false);
1076                    } catch (IllegalArgumentException e) {
1077                        return null;
1078                    }
1079
1080                    while (writerSpiIter.hasNext()) {
1081                        ImageWriterSpi temp = (ImageWriterSpi) writerSpiIter
1082                                .next();
1083                        if (temp.isOwnWriter(writer)) {
1084                            writerSpi = temp;
1085                            break;
1086                        }
1087                    }
1088                    if (writerSpi == null) {
1089                        return null;
1090                    }
1091                }
1092
1093                String[] readerNames = writerSpi.getImageReaderSpiNames();
1094                if (readerNames == null) {
1095                    return null;
1096                }
1097
1098                Class readerSpiClass = null;
1099                try {
1100                    readerSpiClass = Class.forName(readerNames[0], true,
1101                            ClassLoader.getSystemClassLoader());
1102                } catch (ClassNotFoundException e) {
1103                    return null;
1104                }
1105
1106                ImageReaderSpi readerSpi = (ImageReaderSpi) theRegistry
1107                        .getServiceProviderByClass(readerSpiClass);
1108                if (readerSpi == null) {
1109                    return null;
1110                }
1111
1112                try {
1113                    return readerSpi.createReaderInstance();
1114                } catch (IOException e) {
1115                    // Deregister the spi in this case, but only as a readerSpi
1116                    theRegistry.deregisterServiceProvider(readerSpi,
1117                            ImageReaderSpi.class);
1118                    return null;
1119                }
1120            }
1121
1122            /**
1123             * Returns an <code>Iterator</code> containing all currently
1124             * registered <code>ImageWriter</code>s that claim to be able to
1125             * encode images of the given layout (specified using an
1126             * <code>ImageTypeSpecifier</code>) in the given format.
1127             *
1128             * @param type an <code>ImageTypeSpecifier</code> indicating the
1129             * layout of the image to be written.
1130             * @param formatName the informal name of the <code>format</code>.
1131             *
1132             * @return an <code>Iterator</code> containing <code>ImageWriter</code>s.
1133             *
1134             * @exception IllegalArgumentException if any parameter is
1135             * <code>null</code>.
1136             *
1137             * @see javax.imageio.spi.ImageWriterSpi#canEncodeImage(ImageTypeSpecifier)
1138             */
1139            public static Iterator<ImageWriter> getImageWriters(
1140                    ImageTypeSpecifier type, String formatName) {
1141                if (type == null) {
1142                    throw new IllegalArgumentException("type == null!");
1143                }
1144                if (formatName == null) {
1145                    throw new IllegalArgumentException("formatName == null!");
1146                }
1147
1148                Iterator iter;
1149                // Ensure category is present
1150                try {
1151                    iter = theRegistry
1152                            .getServiceProviders(ImageWriterSpi.class,
1153                                    new CanEncodeImageAndFormatFilter(type,
1154                                            formatName), true);
1155                } catch (IllegalArgumentException e) {
1156                    return Collections.emptyIterator();
1157                }
1158
1159                return new ImageWriterIterator(iter);
1160            }
1161
1162            static class ImageTranscoderIterator implements 
1163                    Iterator<ImageTranscoder> {
1164                // Contains ImageTranscoderSpis
1165                public Iterator iter;
1166
1167                public ImageTranscoderIterator(Iterator iter) {
1168                    this .iter = iter;
1169                }
1170
1171                public boolean hasNext() {
1172                    return iter.hasNext();
1173                }
1174
1175                public ImageTranscoder next() {
1176                    ImageTranscoderSpi spi = null;
1177                    spi = (ImageTranscoderSpi) iter.next();
1178                    return spi.createTranscoderInstance();
1179                }
1180
1181                public void remove() {
1182                    throw new UnsupportedOperationException();
1183                }
1184            }
1185
1186            static class TranscoderFilter implements  ServiceRegistry.Filter {
1187
1188                String readerSpiName;
1189                String writerSpiName;
1190
1191                public TranscoderFilter(ImageReaderSpi readerSpi,
1192                        ImageWriterSpi writerSpi) {
1193                    this .readerSpiName = readerSpi.getClass().getName();
1194                    this .writerSpiName = writerSpi.getClass().getName();
1195                }
1196
1197                public boolean filter(Object elt) {
1198                    ImageTranscoderSpi spi = (ImageTranscoderSpi) elt;
1199                    String readerName = spi.getReaderServiceProviderName();
1200                    String writerName = spi.getWriterServiceProviderName();
1201                    return (readerName.equals(readerSpiName) && writerName
1202                            .equals(writerSpiName));
1203                }
1204            }
1205
1206            /**
1207             * Returns an <code>Iterator</code> containing all currently
1208             * registered <code>ImageTranscoder</code>s that claim to be
1209             * able to transcode between the metadata of the given
1210             * <code>ImageReader</code> and <code>ImageWriter</code>.
1211             *
1212             * @param reader an <code>ImageReader</code>.
1213             * @param writer an <code>ImageWriter</code>.
1214             *
1215             * @return an <code>Iterator</code> containing
1216             * <code>ImageTranscoder</code>s.
1217             *
1218             * @exception IllegalArgumentException if <code>reader</code> or
1219             * <code>writer</code> is <code>null</code>.
1220             */
1221            public static Iterator<ImageTranscoder> getImageTranscoders(
1222                    ImageReader reader, ImageWriter writer) {
1223                if (reader == null) {
1224                    throw new IllegalArgumentException("reader == null!");
1225                }
1226                if (writer == null) {
1227                    throw new IllegalArgumentException("writer == null!");
1228                }
1229                ImageReaderSpi readerSpi = reader.getOriginatingProvider();
1230                ImageWriterSpi writerSpi = writer.getOriginatingProvider();
1231                ServiceRegistry.Filter filter = new TranscoderFilter(readerSpi,
1232                        writerSpi);
1233
1234                Iterator iter;
1235                // Ensure category is present
1236                try {
1237                    iter = theRegistry.getServiceProviders(
1238                            ImageTranscoderSpi.class, filter, true);
1239                } catch (IllegalArgumentException e) {
1240                    return Collections.emptyIterator();
1241                }
1242                return new ImageTranscoderIterator(iter);
1243            }
1244
1245            // All-in-one methods
1246
1247            /**
1248             * Returns a <code>BufferedImage</code> as the result of decoding
1249             * a supplied <code>File</code> with an <code>ImageReader</code>
1250             * chosen automatically from among those currently registered.
1251             * The <code>File</code> is wrapped in an
1252             * <code>ImageInputStream</code>.  If no registered
1253             * <code>ImageReader</code> claims to be able to read the
1254             * resulting stream, <code>null</code> is returned.
1255             *
1256             * <p> The current cache settings from <code>getUseCache</code>and
1257             * <code>getCacheDirectory</code> will be used to control caching in the
1258             * <code>ImageInputStream</code> that is created.
1259             *
1260             * <p> Note that there is no <code>read</code> method that takes a
1261             * filename as a <code>String</code>; use this method instead after
1262             * creating a <code>File</code> from the filename.
1263             *
1264             * <p> This method does not attempt to locate
1265             * <code>ImageReader</code>s that can read directly from a
1266             * <code>File</code>; that may be accomplished using
1267             * <code>IIORegistry</code> and <code>ImageReaderSpi</code>.
1268             *
1269             * @param input a <code>File</code> to read from.
1270             *
1271             * @return a <code>BufferedImage</code> containing the decoded
1272             * contents of the input, or <code>null</code>.
1273             *
1274             * @exception IllegalArgumentException if <code>input</code> is 
1275             * <code>null</code>.
1276             * @exception IOException if an error occurs during reading.
1277             */
1278            public static BufferedImage read(File input) throws IOException {
1279                if (input == null) {
1280                    throw new IllegalArgumentException("input == null!");
1281                }
1282                if (!input.canRead()) {
1283                    throw new IIOException("Can't read input file!");
1284                }
1285
1286                ImageInputStream stream = createImageInputStream(input);
1287                if (stream == null) {
1288                    throw new IIOException("Can't create an ImageInputStream!");
1289                }
1290                BufferedImage bi = read(stream);
1291                if (bi == null) {
1292                    stream.close();
1293                }
1294                return bi;
1295            }
1296
1297            /**
1298             * Returns a <code>BufferedImage</code> as the result of decoding
1299             * a supplied <code>InputStream</code> with an <code>ImageReader</code>
1300             * chosen automatically from among those currently registered.
1301             * The <code>InputStream</code> is wrapped in an
1302             * <code>ImageInputStream</code>.  If no registered
1303             * <code>ImageReader</code> claims to be able to read the
1304             * resulting stream, <code>null</code> is returned.
1305             *
1306             * <p> The current cache settings from <code>getUseCache</code>and
1307             * <code>getCacheDirectory</code> will be used to control caching in the
1308             * <code>ImageInputStream</code> that is created.
1309             *
1310             * <p> This method does not attempt to locate
1311             * <code>ImageReader</code>s that can read directly from an
1312             * <code>InputStream</code>; that may be accomplished using
1313             * <code>IIORegistry</code> and <code>ImageReaderSpi</code>.
1314             *
1315             * <p> This method <em>does not</em> close the provided
1316             * <code>InputStream</code> after the read operation has completed;
1317             * it is the responsibility of the caller to close the stream, if desired.
1318             *
1319             * @param input an <code>InputStream</code> to read from.
1320             *
1321             * @return a <code>BufferedImage</code> containing the decoded
1322             * contents of the input, or <code>null</code>.
1323             *
1324             * @exception IllegalArgumentException if <code>input</code> is 
1325             * <code>null</code>.
1326             * @exception IOException if an error occurs during reading.
1327             */
1328            public static BufferedImage read(InputStream input)
1329                    throws IOException {
1330                if (input == null) {
1331                    throw new IllegalArgumentException("input == null!");
1332                }
1333
1334                ImageInputStream stream = createImageInputStream(input);
1335                BufferedImage bi = read(stream);
1336                if (bi == null) {
1337                    stream.close();
1338                }
1339                return bi;
1340            }
1341
1342            /**
1343             * Returns a <code>BufferedImage</code> as the result of decoding
1344             * a supplied <code>URL</code> with an <code>ImageReader</code>
1345             * chosen automatically from among those currently registered.  An
1346             * <code>InputStream</code> is obtained from the <code>URL</code>,
1347             * which is wrapped in an <code>ImageInputStream</code>.  If no
1348             * registered <code>ImageReader</code> claims to be able to read
1349             * the resulting stream, <code>null</code> is returned.
1350             *
1351             * <p> The current cache settings from <code>getUseCache</code>and
1352             * <code>getCacheDirectory</code> will be used to control caching in the
1353             * <code>ImageInputStream</code> that is created.
1354             *
1355             * <p> This method does not attempt to locate
1356             * <code>ImageReader</code>s that can read directly from a
1357             * <code>URL</code>; that may be accomplished using
1358             * <code>IIORegistry</code> and <code>ImageReaderSpi</code>.
1359             *
1360             * @param input a <code>URL</code> to read from.
1361             *
1362             * @return a <code>BufferedImage</code> containing the decoded
1363             * contents of the input, or <code>null</code>.
1364             *
1365             * @exception IllegalArgumentException if <code>input</code> is 
1366             * <code>null</code>.
1367             * @exception IOException if an error occurs during reading.
1368             */
1369            public static BufferedImage read(URL input) throws IOException {
1370                if (input == null) {
1371                    throw new IllegalArgumentException("input == null!");
1372                }
1373
1374                InputStream istream = null;
1375                try {
1376                    istream = input.openStream();
1377                } catch (IOException e) {
1378                    throw new IIOException("Can't get input stream from URL!",
1379                            e);
1380                }
1381                ImageInputStream stream = createImageInputStream(istream);
1382                BufferedImage bi;
1383                try {
1384                    bi = read(stream);
1385                    if (bi == null) {
1386                        stream.close();
1387                    }
1388                } finally {
1389                    istream.close();
1390                }
1391                return bi;
1392            }
1393
1394            /**
1395             * Returns a <code>BufferedImage</code> as the result of decoding
1396             * a supplied <code>ImageInputStream</code> with an
1397             * <code>ImageReader</code> chosen automatically from among those
1398             * currently registered.  If no registered
1399             * <code>ImageReader</code> claims to be able to read the stream,
1400             * <code>null</code> is returned.
1401             *
1402             * <p> Unlike most other methods in this class, this method <em>does</em>
1403             * close the provided <code>ImageInputStream</code> after the read
1404             * operation has completed, unless <code>null</code> is returned,
1405             * in which case this method <em>does not</em> close the stream.
1406             *
1407             * @param stream an <code>ImageInputStream</code> to read from.
1408             *
1409             * @return a <code>BufferedImage</code> containing the decoded
1410             * contents of the input, or <code>null</code>.
1411             *
1412             * @exception IllegalArgumentException if <code>stream</code> is 
1413             * <code>null</code>.
1414             * @exception IOException if an error occurs during reading.
1415             */
1416            public static BufferedImage read(ImageInputStream stream)
1417                    throws IOException {
1418                if (stream == null) {
1419                    throw new IllegalArgumentException("stream == null!");
1420                }
1421
1422                Iterator iter = getImageReaders(stream);
1423                if (!iter.hasNext()) {
1424                    return null;
1425                }
1426
1427                ImageReader reader = (ImageReader) iter.next();
1428                ImageReadParam param = reader.getDefaultReadParam();
1429                reader.setInput(stream, true, true);
1430                BufferedImage bi;
1431                try {
1432                    bi = reader.read(0, param);
1433                } finally {
1434                    reader.dispose();
1435                    stream.close();
1436                }
1437                return bi;
1438            }
1439
1440            /**
1441             * Writes an image using the an arbitrary <code>ImageWriter</code>
1442             * that supports the given format to an
1443             * <code>ImageOutputStream</code>.  The image is written to the
1444             * <code>ImageOutputStream</code> starting at the current stream
1445             * pointer, overwriting existing stream data from that point
1446             * forward, if present.
1447             *
1448             * <p> This method <em>does not</em> close the provided
1449             * <code>ImageOutputStream</code> after the write operation has completed;
1450             * it is the responsibility of the caller to close the stream, if desired.
1451             *
1452             * @param im a <code>RenderedImage</code> to be written.
1453             * @param formatName a <code>String</code> containg the informal
1454             * name of the format.
1455             * @param output an <code>ImageOutputStream</code> to be written to.
1456             *
1457             * @return <code>false</code> if no appropriate writer is found.
1458             *
1459             * @exception IllegalArgumentException if any parameter is
1460             * <code>null</code>.
1461             * @exception IOException if an error occurs during writing.
1462             */
1463            public static boolean write(RenderedImage im, String formatName,
1464                    ImageOutputStream output) throws IOException {
1465                if (im == null) {
1466                    throw new IllegalArgumentException("im == null!");
1467                }
1468                if (formatName == null) {
1469                    throw new IllegalArgumentException("formatName == null!");
1470                }
1471                if (output == null) {
1472                    throw new IllegalArgumentException("output == null!");
1473                }
1474
1475                ImageWriter writer = null;
1476                ImageTypeSpecifier type = ImageTypeSpecifier
1477                        .createFromRenderedImage(im);
1478                Iterator iter = getImageWriters(type, formatName);
1479                if (iter.hasNext()) {
1480                    writer = (ImageWriter) iter.next();
1481                }
1482                if (writer == null) {
1483                    return false;
1484                }
1485
1486                writer.setOutput(output);
1487                try {
1488                    writer.write(im);
1489                } finally {
1490                    writer.dispose();
1491                    output.flush();
1492                }
1493
1494                return true;
1495            }
1496
1497            /**
1498             * Writes an image using an arbitrary <code>ImageWriter</code>
1499             * that supports the given format to a <code>File</code>.  If
1500             * there is already a <code>File</code> present, its contents are
1501             * discarded.
1502             *
1503             * @param im a <code>RenderedImage</code> to be written.
1504             * @param formatName a <code>String</code> containg the informal
1505             * name of the format.
1506             * @param output a <code>File</code> to be written to.
1507             *
1508             * @return <code>false</code> if no appropriate writer is found.
1509             *
1510             * @exception IllegalArgumentException if any parameter is
1511             * <code>null</code>.
1512             * @exception IOException if an error occurs during writing.
1513             */
1514            public static boolean write(RenderedImage im, String formatName,
1515                    File output) throws IOException {
1516                if (output == null) {
1517                    throw new IllegalArgumentException("output == null!");
1518                }
1519                ImageOutputStream stream = null;
1520                try {
1521                    output.delete();
1522                    stream = createImageOutputStream(output);
1523                } catch (IOException e) {
1524                    throw new IIOException("Can't create output stream!", e);
1525                }
1526
1527                boolean val;
1528                try {
1529                    val = write(im, formatName, stream);
1530                } finally {
1531                    stream.close();
1532                }
1533                return val;
1534            }
1535
1536            /**
1537             * Writes an image using an arbitrary <code>ImageWriter</code>
1538             * that supports the given format to an <code>OutputStream</code>.
1539             *
1540             * <p> This method <em>does not</em> close the provided
1541             * <code>OutputStream</code> after the write operation has completed;
1542             * it is the responsibility of the caller to close the stream, if desired.
1543             *
1544             * <p> The current cache settings from <code>getUseCache</code>and
1545             * <code>getCacheDirectory</code> will be used to control caching.
1546             *
1547             * @param im a <code>RenderedImage</code> to be written.
1548             * @param formatName a <code>String</code> containg the informal
1549             * name of the format.
1550             * @param output an <code>OutputStream</code> to be written to.
1551             *
1552             * @return <code>false</code> if no appropriate writer is found.
1553             *
1554             * @exception IllegalArgumentException if any parameter is
1555             * <code>null</code>.
1556             * @exception IOException if an error occurs during writing.
1557             */
1558            public static boolean write(RenderedImage im, String formatName,
1559                    OutputStream output) throws IOException {
1560                if (output == null) {
1561                    throw new IllegalArgumentException("output == null!");
1562                }
1563                ImageOutputStream stream = null;
1564                try {
1565                    stream = createImageOutputStream(output);
1566                } catch (IOException e) {
1567                    throw new IIOException("Can't create output stream!", e);
1568                }
1569
1570                boolean val;
1571                try {
1572                    val = write(im, formatName, stream);
1573                } finally {
1574                    stream.close();
1575                }
1576                return val;
1577            }
1578        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.