Source Code Cross Referenced for ImageReader.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 1999-2004 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.Point;
0029        import java.awt.Rectangle;
0030        import java.awt.image.BufferedImage;
0031        import java.awt.image.Raster;
0032        import java.awt.image.RenderedImage;
0033        import java.io.IOException;
0034        import java.util.ArrayList;
0035        import java.util.Iterator;
0036        import java.util.List;
0037        import java.util.Locale;
0038        import java.util.MissingResourceException;
0039        import java.util.ResourceBundle;
0040        import java.util.Set;
0041        import javax.imageio.spi.ImageReaderSpi;
0042        import javax.imageio.event.IIOReadWarningListener;
0043        import javax.imageio.event.IIOReadProgressListener;
0044        import javax.imageio.event.IIOReadUpdateListener;
0045        import javax.imageio.metadata.IIOMetadata;
0046        import javax.imageio.metadata.IIOMetadataFormatImpl;
0047        import javax.imageio.stream.ImageInputStream;
0048
0049        /**
0050         * An abstract superclass for parsing and decoding of images.  This
0051         * class must be subclassed by classes that read in images in the
0052         * context of the Java Image I/O framework.
0053         *
0054         * <p> <code>ImageReader</code> objects are normally instantiated by
0055         * the service provider interface (SPI) class for the specific format.
0056         * Service provider classes (e.g., instances of
0057         * <code>ImageReaderSpi</code>) are registered with the
0058         * <code>IIORegistry</code>, which uses them for format recognition
0059         * and presentation of available format readers and writers.
0060         *
0061         * <p> When an input source is set (using the <code>setInput</code>
0062         * method), it may be marked as "seek forward only".  This setting
0063         * means that images contained within the input source will only be
0064         * read in order, possibly allowing the reader to avoid caching
0065         * portions of the input containing data associated with images that
0066         * have been read previously.
0067         *
0068         * @see ImageWriter
0069         * @see javax.imageio.spi.IIORegistry
0070         * @see javax.imageio.spi.ImageReaderSpi
0071         *
0072         * @version 0.5
0073         */
0074        public abstract class ImageReader {
0075
0076            /**
0077             * The <code>ImageReaderSpi</code> that instantiated this object,
0078             * or <code>null</code> if its identity is not known or none
0079             * exists.  By default it is initialized to <code>null</code>.
0080             */
0081            protected ImageReaderSpi originatingProvider;
0082
0083            /**
0084             * The <code>ImageInputStream</code> or other
0085             * <code>Object</code> by <code>setInput</code> and retrieved
0086             * by <code>getInput</code>.  By default it is initialized to
0087             * <code>null</code>.
0088             */
0089            protected Object input = null;
0090
0091            /**
0092             * <code>true</code> if the current input source has been marked
0093             * as allowing only forward seeking by <code>setInput</code>.  By
0094             * default, the value is <code>false</code>.
0095             *
0096             * @see #minIndex
0097             * @see #setInput
0098             */
0099            protected boolean seekForwardOnly = false;
0100
0101            /**
0102             * <code>true</code> if the current input source has been marked
0103             * as allowing metadata to be ignored by <code>setInput</code>.
0104             * By default, the value is <code>false</code>.
0105             *
0106             * @see #setInput
0107             */
0108            protected boolean ignoreMetadata = false;
0109
0110            /**
0111             * The smallest valid index for reading, initially 0.  When
0112             * <code>seekForwardOnly</code> is <code>true</code>, various methods
0113             * may throw an <code>IndexOutOfBoundsException</code> on an
0114             * attempt to access data associate with an image having a lower
0115             * index.
0116             *
0117             * @see #seekForwardOnly
0118             * @see #setInput
0119             */
0120            protected int minIndex = 0;
0121
0122            /**
0123             * An array of <code>Locale</code>s which may be used to localize
0124             * warning messages, or <code>null</code> if localization is not
0125             * supported.
0126             */
0127            protected Locale[] availableLocales = null;
0128
0129            /**
0130             * The current <code>Locale</code> to be used for localization, or
0131             * <code>null</code> if none has been set.
0132             */
0133            protected Locale locale = null;
0134
0135            /**
0136             * A <code>List</code> of currently registered
0137             * <code>IIOReadWarningListener</code>s, initialized by default to
0138             * <code>null</code>, which is synonymous with an empty
0139             * <code>List</code>.
0140             */
0141            protected List<IIOReadWarningListener> warningListeners = null;
0142
0143            /**
0144             * A <code>List</code> of the <code>Locale</code>s associated with
0145             * each currently registered <code>IIOReadWarningListener</code>,
0146             * initialized by default to <code>null</code>, which is
0147             * synonymous with an empty <code>List</code>.
0148             */
0149            protected List<Locale> warningLocales = null;
0150
0151            /**
0152             * A <code>List</code> of currently registered
0153             * <code>IIOReadProgressListener</code>s, initialized by default
0154             * to <code>null</code>, which is synonymous with an empty
0155             * <code>List</code>.
0156             */
0157            protected List<IIOReadProgressListener> progressListeners = null;
0158
0159            /**
0160             * A <code>List</code> of currently registered
0161             * <code>IIOReadUpdateListener</code>s, initialized by default to
0162             * <code>null</code>, which is synonymous with an empty
0163             * <code>List</code>.
0164             */
0165            protected List<IIOReadUpdateListener> updateListeners = null;
0166
0167            /**
0168             * If <code>true</code>, the current read operation should be
0169             * aborted.
0170             */
0171            private boolean abortFlag = false;
0172
0173            /**
0174             * Constructs an <code>ImageReader</code> and sets its
0175             * <code>originatingProvider</code> field to the supplied value.
0176             *
0177             * <p> Subclasses that make use of extensions should provide a
0178             * constructor with signature <code>(ImageReaderSpi,
0179             * Object)</code> in order to retrieve the extension object.  If
0180             * the extension object is unsuitable, an
0181             * <code>IllegalArgumentException</code> should be thrown.
0182             *
0183             * @param originatingProvider the <code>ImageReaderSpi</code> that is
0184             * invoking this constructor, or <code>null</code>.
0185             */
0186            protected ImageReader(ImageReaderSpi originatingProvider) {
0187                this .originatingProvider = originatingProvider;
0188            }
0189
0190            /**
0191             * Returns a <code>String</code> identifying the format of the
0192             * input source.
0193             *
0194             * <p> The default implementation returns
0195             * <code>originatingProvider.getFormatNames()[0]</code>.
0196             * Implementations that may not have an originating service
0197             * provider, or which desire a different naming policy should
0198             * override this method.
0199             *
0200             * @exception IOException if an error occurs reading the
0201             * information from the input source.
0202             *
0203             * @return the format name, as a <code>String</code>.
0204             */
0205            public String getFormatName() throws IOException {
0206                return originatingProvider.getFormatNames()[0];
0207            }
0208
0209            /**
0210             * Returns the <code>ImageReaderSpi</code> that was passed in on
0211             * the constructor.  Note that this value may be <code>null</code>.
0212             *
0213             * @return an <code>ImageReaderSpi</code>, or <code>null</code>.
0214             *
0215             * @see ImageReaderSpi
0216             */
0217            public ImageReaderSpi getOriginatingProvider() {
0218                return originatingProvider;
0219            }
0220
0221            /**
0222             * Sets the input source to use to the given
0223             * <code>ImageInputStream</code> or other <code>Object</code>.
0224             * The input source must be set before any of the query or read
0225             * methods are used.  If <code>input</code> is <code>null</code>,
0226             * any currently set input source will be removed.  In any case,
0227             * the value of <code>minIndex</code> will be initialized to 0.
0228             *
0229             * <p> The <code>seekForwardOnly</code> parameter controls whether
0230             * the value returned by <code>getMinIndex</code> will be
0231             * increased as each image (or thumbnail, or image metadata) is
0232             * read.  If <code>seekForwardOnly</code> is true, then a call to
0233             * <code>read(index)</code> will throw an
0234             * <code>IndexOutOfBoundsException</code> if <code>index &lt
0235             * this.minIndex</code>; otherwise, the value of
0236             * <code>minIndex</code> will be set to <code>index</code>.  If
0237             * <code>seekForwardOnly</code> is <code>false</code>, the value of
0238             * <code>minIndex</code> will remain 0 regardless of any read
0239             * operations.
0240             *
0241             * <p> The <code>ignoreMetadata</code> parameter, if set to
0242             * <code>true</code>, allows the reader to disregard any metadata
0243             * encountered during the read.  Subsequent calls to the
0244             * <code>getStreamMetadata</code> and
0245             * <code>getImageMetadata</code> methods may return
0246             * <code>null</code>, and an <code>IIOImage</code> returned from
0247             * <code>readAll</code> may return <code>null</code> from their
0248             * <code>getMetadata</code> method.  Setting this parameter may
0249             * allow the reader to work more efficiently.  The reader may
0250             * choose to disregard this setting and return metadata normally.
0251             *
0252             * <p> Subclasses should take care to remove any cached
0253             * information based on the previous stream, such as header
0254             * information or partially decoded image data.
0255             *
0256             * <p> Use of a general <code>Object</code> other than an
0257             * <code>ImageInputStream</code> is intended for readers that
0258             * interact directly with a capture device or imaging protocol.
0259             * The set of legal classes is advertised by the reader's service
0260             * provider's <code>getInputTypes</code> method; most readers
0261             * will return a single-element array containing only
0262             * <code>ImageInputStream.class</code> to indicate that they
0263             * accept only an <code>ImageInputStream</code>.
0264             *
0265             * <p> The default implementation checks the <code>input</code>
0266             * argument against the list returned by 
0267             * <code>originatingProvider.getInputTypes()</code> and fails
0268             * if the argument is not an instance of one of the classes
0269             * in the list.  If the originating provider is set to 
0270             * <code>null</code>, the input is accepted only if it is an
0271             * <code>ImageInputStream</code>.
0272             *
0273             * @param input the <code>ImageInputStream</code> or other
0274             * <code>Object</code> to use for future decoding.
0275             * @param seekForwardOnly if <code>true</code>, images and metadata
0276             * may only be read in ascending order from this input source.
0277             * @param ignoreMetadata if <code>true</code>, metadata
0278             * may be ignored during reads.
0279             *
0280             * @exception IllegalArgumentException if <code>input</code> is
0281             * not an instance of one of the classes returned by the
0282             * originating service provider's <code>getInputTypes</code>
0283             * method, or is not an <code>ImageInputStream</code>.
0284             *
0285             * @see ImageInputStream
0286             * @see #getInput
0287             * @see javax.imageio.spi.ImageReaderSpi#getInputTypes
0288             */
0289            public void setInput(Object input, boolean seekForwardOnly,
0290                    boolean ignoreMetadata) {
0291                if (input != null) {
0292                    boolean found = false;
0293                    if (originatingProvider != null) {
0294                        Class[] classes = originatingProvider.getInputTypes();
0295                        for (int i = 0; i < classes.length; i++) {
0296                            if (classes[i].isInstance(input)) {
0297                                found = true;
0298                                break;
0299                            }
0300                        }
0301                    } else {
0302                        if (input instanceof  ImageInputStream) {
0303                            found = true;
0304                        }
0305                    }
0306                    if (!found) {
0307                        throw new IllegalArgumentException(
0308                                "Incorrect input type!");
0309                    }
0310
0311                    this .seekForwardOnly = seekForwardOnly;
0312                    this .ignoreMetadata = ignoreMetadata;
0313                    this .minIndex = 0;
0314                }
0315
0316                this .input = input;
0317            }
0318
0319            /**
0320             * Sets the input source to use to the given
0321             * <code>ImageInputStream</code> or other <code>Object</code>.
0322             * The input source must be set before any of the query or read
0323             * methods are used.  If <code>input</code> is <code>null</code>,
0324             * any currently set input source will be removed.  In any case,
0325             * the value of <code>minIndex</code> will be initialized to 0.
0326             *
0327             * <p> The <code>seekForwardOnly</code> parameter controls whether
0328             * the value returned by <code>getMinIndex</code> will be
0329             * increased as each image (or thumbnail, or image metadata) is
0330             * read.  If <code>seekForwardOnly</code> is true, then a call to
0331             * <code>read(index)</code> will throw an
0332             * <code>IndexOutOfBoundsException</code> if <code>index &lt
0333             * this.minIndex</code>; otherwise, the value of
0334             * <code>minIndex</code> will be set to <code>index</code>.  If
0335             * <code>seekForwardOnly</code> is <code>false</code>, the value of
0336             * <code>minIndex</code> will remain 0 regardless of any read
0337             * operations.
0338             *
0339             * <p> This method is equivalent to <code>setInput(input,
0340             * seekForwardOnly, false)</code>.
0341             *
0342             * @param input the <code>ImageInputStream</code> or other
0343             * <code>Object</code> to use for future decoding.
0344             * @param seekForwardOnly if <code>true</code>, images and metadata
0345             * may only be read in ascending order from this input source.
0346             *
0347             * @exception IllegalArgumentException if <code>input</code> is
0348             * not an instance of one of the classes returned by the
0349             * originating service provider's <code>getInputTypes</code>
0350             * method, or is not an <code>ImageInputStream</code>.
0351             *
0352             * @see #getInput
0353             */
0354            public void setInput(Object input, boolean seekForwardOnly) {
0355                setInput(input, seekForwardOnly, false);
0356            }
0357
0358            /**
0359             * Sets the input source to use to the given
0360             * <code>ImageInputStream</code> or other <code>Object</code>.
0361             * The input source must be set before any of the query or read
0362             * methods are used.  If <code>input</code> is <code>null</code>,
0363             * any currently set input source will be removed.  In any case,
0364             * the value of <code>minIndex</code> will be initialized to 0.
0365             *
0366             * <p> This method is equivalent to <code>setInput(input, false,
0367             * false)</code>.
0368             *
0369             * @param input the <code>ImageInputStream</code> or other
0370             * <code>Object</code> to use for future decoding.
0371             *
0372             * @exception IllegalArgumentException if <code>input</code> is
0373             * not an instance of one of the classes returned by the
0374             * originating service provider's <code>getInputTypes</code>
0375             * method, or is not an <code>ImageInputStream</code>.
0376             *
0377             * @see #getInput
0378             */
0379            public void setInput(Object input) {
0380                setInput(input, false, false);
0381            }
0382
0383            /**
0384             * Returns the <code>ImageInputStream</code> or other
0385             * <code>Object</code> previously set as the input source.  If the
0386             * input source has not been set, <code>null</code> is returned.
0387             *
0388             * @return the <code>Object</code> that will be used for future
0389             * decoding, or <code>null</code>.
0390             *
0391             * @see ImageInputStream
0392             * @see #setInput
0393             */
0394            public Object getInput() {
0395                return input;
0396            }
0397
0398            /**
0399             * Returns <code>true</code> if the current input source has been
0400             * marked as seek forward only by passing <code>true</code> as the
0401             * <code>seekForwardOnly</code> argument to the
0402             * <code>setInput</code> method.
0403             *
0404             * @return <code>true</code> if the input source is seek forward
0405             * only.
0406             *
0407             * @see #setInput
0408             */
0409            public boolean isSeekForwardOnly() {
0410                return seekForwardOnly;
0411            }
0412
0413            /**
0414             * Returns <code>true</code> if the current input source has been
0415             * marked as allowing metadata to be ignored by passing
0416             * <code>true</code> as the <code>ignoreMetadata</code> argument
0417             * to the <code>setInput</code> method.
0418             *
0419             * @return <code>true</code> if the metadata may be ignored.
0420             *
0421             * @see #setInput
0422             */
0423            public boolean isIgnoringMetadata() {
0424                return ignoreMetadata;
0425            }
0426
0427            /**
0428             * Returns the lowest valid index for reading an image, thumbnail,
0429             * or image metadata.  If <code>seekForwardOnly()</code> is
0430             * <code>false</code>, this value will typically remain 0,
0431             * indicating that random access is possible.  Otherwise, it will
0432             * contain the value of the most recently accessed index, and
0433             * increase in a monotonic fashion.
0434             *
0435             * @return the minimum legal index for reading.
0436             */
0437            public int getMinIndex() {
0438                return minIndex;
0439            }
0440
0441            // Localization
0442
0443            /**
0444             * Returns an array of <code>Locale</code>s that may be used to
0445             * localize warning listeners and compression settings.  A return
0446             * value of <code>null</code> indicates that localization is not
0447             * supported.
0448             *
0449             * <p> The default implementation returns a clone of the
0450             * <code>availableLocales</code> instance variable if it is
0451             * non-<code>null</code>, or else returns <code>null</code>.
0452             *
0453             * @return an array of <code>Locale</code>s that may be used as
0454             * arguments to <code>setLocale</code>, or <code>null</code>.
0455             */
0456            public Locale[] getAvailableLocales() {
0457                if (availableLocales == null) {
0458                    return null;
0459                } else {
0460                    return (Locale[]) availableLocales.clone();
0461                }
0462            }
0463
0464            /**
0465             * Sets the current <code>Locale</code> of this
0466             * <code>ImageReader</code> to the given value.  A value of
0467             * <code>null</code> removes any previous setting, and indicates
0468             * that the reader should localize as it sees fit.
0469             *
0470             * @param locale the desired <code>Locale</code>, or
0471             * <code>null</code>.
0472             *
0473             * @exception IllegalArgumentException if <code>locale</code> is
0474             * non-<code>null</code> but is not one of the values returned by
0475             * <code>getAvailableLocales</code>.
0476             *
0477             * @see #getLocale
0478             */
0479            public void setLocale(Locale locale) {
0480                if (locale != null) {
0481                    Locale[] locales = getAvailableLocales();
0482                    boolean found = false;
0483                    if (locales != null) {
0484                        for (int i = 0; i < locales.length; i++) {
0485                            if (locale.equals(locales[i])) {
0486                                found = true;
0487                                break;
0488                            }
0489                        }
0490                    }
0491                    if (!found) {
0492                        throw new IllegalArgumentException("Invalid locale!");
0493                    }
0494                }
0495                this .locale = locale;
0496            }
0497
0498            /**
0499             * Returns the currently set <code>Locale</code>, or
0500             * <code>null</code> if none has been set.
0501             *
0502             * @return the current <code>Locale</code>, or <code>null</code>.
0503             *
0504             * @see #setLocale
0505             */
0506            public Locale getLocale() {
0507                return locale;
0508            }
0509
0510            // Image queries
0511
0512            /**
0513             * Returns the number of images, not including thumbnails, available
0514             * from the current input source.
0515             *
0516             * <p> Note that some image formats (such as animated GIF) do not
0517             * specify how many images are present in the stream.  Thus
0518             * determining the number of images will require the entire stream
0519             * to be scanned and may require memory for buffering.  If images
0520             * are to be processed in order, it may be more efficient to
0521             * simply call <code>read</code> with increasing indices until an
0522             * <code>IndexOutOfBoundsException</code> is thrown to indicate
0523             * that no more images are available.  The
0524             * <code>allowSearch</code> parameter may be set to
0525             * <code>false</code> to indicate that an exhaustive search is not
0526             * desired; the return value will be <code>-1</code> to indicate
0527             * that a search is necessary.  If the input has been specified
0528             * with <code>seekForwardOnly</code> set to <code>true</code>,
0529             * this method throws an <code>IllegalStateException</code> if
0530             * <code>allowSearch</code> is set to <code>true</code>.
0531             *
0532             * @param allowSearch if <code>true</code>, the true number of
0533             * images will be returned even if a search is required.  If
0534             * <code>false</code>, the reader may return <code>-1</code>
0535             * without performing the search.
0536             *
0537             * @return the number of images, as an <code>int</code>, or
0538             * <code>-1</code> if <code>allowSearch</code> is
0539             * <code>false</code> and a search would be required.
0540             *
0541             * @exception IllegalStateException if the input source has not been set,
0542             * or if the input has been specified with <code>seekForwardOnly</code>
0543             * set to <code>true</code>.
0544             * @exception IOException if an error occurs reading the
0545             * information from the input source.
0546             *
0547             * @see #setInput
0548             */
0549            public abstract int getNumImages(boolean allowSearch)
0550                    throws IOException;
0551
0552            /**
0553             * Returns the width in pixels of the given image within the input
0554             * source.
0555             *
0556             * <p> If the image can be rendered to a user-specified size, then
0557             * this method returns the default width.
0558             *
0559             * @param imageIndex the index of the image to be queried.
0560             *
0561             * @return the width of the image, as an <code>int</code>.
0562             *
0563             * @exception IllegalStateException if the input source has not been set.
0564             * @exception IndexOutOfBoundsException if the supplied index is
0565             * out of bounds.
0566             * @exception IOException if an error occurs reading the width
0567             * information from the input source.
0568             */
0569            public abstract int getWidth(int imageIndex) throws IOException;
0570
0571            /**
0572             * Returns the height in pixels of the given image within the
0573             * input source.
0574             *
0575             * <p> If the image can be rendered to a user-specified size, then
0576             * this method returns the default height.
0577             *
0578             * @param imageIndex the index of the image to be queried.
0579             *
0580             * @return the height of the image, as an <code>int</code>.
0581             *
0582             * @exception IllegalStateException if the input source has not been set.
0583             * @exception IndexOutOfBoundsException if the supplied index is
0584             * out of bounds.
0585             * @exception IOException if an error occurs reading the height
0586             * information from the input source.
0587             */
0588            public abstract int getHeight(int imageIndex) throws IOException;
0589
0590            /**
0591             * Returns <code>true</code> if the storage format of the given
0592             * image places no inherent impediment on random access to pixels.
0593             * For most compressed formats, such as JPEG, this method should
0594             * return <code>false</code>, as a large section of the image in
0595             * addition to the region of interest may need to be decoded.
0596             *
0597             * <p> This is merely a hint for programs that wish to be
0598             * efficient; all readers must be able to read arbitrary regions
0599             * as specified in an <code>ImageReadParam</code>.
0600             *
0601             * <p> Note that formats that return <code>false</code> from
0602             * this method may nonetheless allow tiling (<i>e.g.</i> Restart
0603             * Markers in JPEG), and random access will likely be reasonably
0604             * efficient on tiles.  See {@link #isImageTiled 
0605             * <code>isImageTiled</code>}.
0606             *
0607             * <p> A reader for which all images are guaranteed to support
0608             * easy random access, or are guaranteed not to support easy
0609             * random access, may return <code>true</code> or
0610             * <code>false</code> respectively without accessing any image
0611             * data.  In such cases, it is not necessary to throw an exception
0612             * even if no input source has been set or the image index is out
0613             * of bounds.
0614             *
0615             * <p> The default implementation returns <code>false</code>.
0616             *
0617             * @param imageIndex the index of the image to be queried.
0618             *
0619             * @return <code>true</code> if reading a region of interest of
0620             * the given image is likely to be efficient.
0621             *
0622             * @exception IllegalStateException if an input source is required
0623             * to determine the return value, but none has been set.
0624             * @exception IndexOutOfBoundsException if an image must be
0625             * accessed to determine the return value, but the supplied index
0626             * is out of bounds.
0627             * @exception IOException if an error occurs during reading.
0628             */
0629            public boolean isRandomAccessEasy(int imageIndex)
0630                    throws IOException {
0631                return false;
0632            }
0633
0634            /**
0635             * Returns the aspect ratio of the given image (that is, its width
0636             * divided by its height) as a <code>float</code>.  For images
0637             * that are inherently resizable, this method provides a way to
0638             * determine the appropriate width given a deired height, or vice
0639             * versa.  For non-resizable images, the true width and height
0640             * are used.
0641             *
0642             * <p> The default implementation simply returns
0643             * <code>(float)getWidth(imageIndex)/getHeight(imageIndex)</code>.
0644             *
0645             * @param imageIndex the index of the image to be queried.
0646             *
0647             * @return a <code>float</code> indicating the aspect ratio of the
0648             * given image.
0649             *
0650             * @exception IllegalStateException if the input source has not been set.
0651             * @exception IndexOutOfBoundsException if the supplied index is
0652             * out of bounds.
0653             * @exception IOException if an error occurs during reading.
0654             */
0655            public float getAspectRatio(int imageIndex) throws IOException {
0656                return (float) getWidth(imageIndex) / getHeight(imageIndex);
0657            }
0658
0659            /**
0660             * Returns an <code>ImageTypeSpecifier</code> indicating the
0661             * <code>SampleModel</code> and <code>ColorModel</code> which most
0662             * closely represents the "raw" internal format of the image.  For
0663             * example, for a JPEG image the raw type might have a YCbCr color
0664             * space even though the image would conventionally be transformed
0665             * into an RGB color space prior to display.  The returned value
0666             * should also be included in the list of values returned by
0667             * <code>getImageTypes</code>.
0668             *
0669             * <p> The default implementation simply returns the first entry
0670             * from the list provided by <code>getImageType</code>.
0671             *
0672             * @param imageIndex the index of the image to be queried.
0673             *
0674             * @return an <code>ImageTypeSpecifier</code>.
0675             *
0676             * @exception IllegalStateException if the input source has not been set.
0677             * @exception IndexOutOfBoundsException if the supplied index is
0678             * out of bounds.
0679             * @exception IOException if an error occurs reading the format
0680             * information from the input source.
0681             */
0682            public ImageTypeSpecifier getRawImageType(int imageIndex)
0683                    throws IOException {
0684                return (ImageTypeSpecifier) getImageTypes(imageIndex).next();
0685            }
0686
0687            /**    
0688             * Returns an <code>Iterator</code> containing possible image
0689             * types to which the given image may be decoded, in the form of
0690             * <code>ImageTypeSpecifiers</code>s.  At least one legal image
0691             * type will be returned.
0692             *
0693             * <p> The first element of the iterator should be the most
0694             * "natural" type for decoding the image with as little loss as
0695             * possible.  For example, for a JPEG image the first entry should
0696             * be an RGB image, even though the image data is stored
0697             * internally in a YCbCr color space.
0698             *
0699             * @param imageIndex the index of the image to be
0700             * <code>retrieved</code>.
0701             *
0702             * @return an <code>Iterator</code> containing at least one
0703             * <code>ImageTypeSpecifier</code> representing suggested image
0704             * types for decoding the current given image.
0705             *
0706             * @exception IllegalStateException if the input source has not been set.
0707             * @exception IndexOutOfBoundsException if the supplied index is
0708             * out of bounds.
0709             * @exception IOException if an error occurs reading the format
0710             * information from the input source.
0711             *
0712             * @see ImageReadParam#setDestination(BufferedImage)
0713             * @see ImageReadParam#setDestinationType(ImageTypeSpecifier)
0714             */
0715            public abstract Iterator<ImageTypeSpecifier> getImageTypes(
0716                    int imageIndex) throws IOException;
0717
0718            /**
0719             * Returns a default <code>ImageReadParam</code> object
0720             * appropriate for this format.  All subclasses should define a
0721             * set of default values for all parameters and return them with
0722             * this call.  This method may be called before the input source
0723             * is set.
0724             *
0725             * <p> The default implementation constructs and returns a new
0726             * <code>ImageReadParam</code> object that does not allow source
0727             * scaling (<i>i.e.</i>, it returns <code>new
0728             * ImageReadParam()</code>.
0729             *
0730             * @return an <code>ImageReadParam</code> object which may be used
0731             * to control the decoding process using a set of default settings.
0732             */
0733            public ImageReadParam getDefaultReadParam() {
0734                return new ImageReadParam();
0735            }
0736
0737            /**
0738             * Returns an <code>IIOMetadata</code> object representing the
0739             * metadata associated with the input source as a whole (i.e., not
0740             * associated with any particular image), or <code>null</code> if
0741             * the reader does not support reading metadata, is set to ignore
0742             * metadata, or if no metadata is available.
0743             *
0744             * @return an <code>IIOMetadata</code> object, or <code>null</code>.
0745             *
0746             * @exception IOException if an error occurs during reading.
0747             */
0748            public abstract IIOMetadata getStreamMetadata() throws IOException;
0749
0750            /**
0751             * Returns an <code>IIOMetadata</code> object representing the
0752             * metadata associated with the input source as a whole (i.e.,
0753             * not associated with any particular image).  If no such data
0754             * exists, <code>null</code> is returned.
0755             *
0756             * <p> The resuting metadata object is only responsible for
0757             * returning documents in the format named by
0758             * <code>formatName</code>.  Within any documents that are
0759             * returned, only nodes whose names are members of
0760             * <code>nodeNames</code> are required to be returned.  In this
0761             * way, the amount of metadata processing done by the reader may
0762             * be kept to a minimum, based on what information is actually
0763             * needed.
0764             *
0765             * <p> If <code>formatName</code> is not the name of a supported
0766             * metadata format, <code>null</code> is returned.
0767             *
0768             * <p> In all cases, it is legal to return a more capable metadata
0769             * object than strictly necessary.  The format name and node names
0770             * are merely hints that may be used to reduce the reader's
0771             * workload.
0772             *
0773             * <p> The default implementation simply returns the result of
0774             * calling <code>getStreamMetadata()</code>, after checking that
0775             * the format name is supported.  If it is not,
0776             * <code>null</code> is returned.
0777             *
0778             * @param formatName a metadata format name that may be used to retrieve
0779             * a document from the returned <code>IIOMetadata</code> object.
0780             * @param nodeNames a <code>Set</code> containing the names of 
0781             * nodes that may be contained in a retrieved document.
0782             *
0783             * @return an <code>IIOMetadata</code> object, or <code>null</code>.
0784             *
0785             * @exception IllegalArgumentException if <code>formatName</code>
0786             * is <code>null</code>.
0787             * @exception IllegalArgumentException if <code>nodeNames</code>
0788             * is <code>null</code>.
0789             * @exception IOException if an error occurs during reading.
0790             */
0791            public IIOMetadata getStreamMetadata(String formatName,
0792                    Set<String> nodeNames) throws IOException {
0793                return getMetadata(formatName, nodeNames, true, 0);
0794            }
0795
0796            private IIOMetadata getMetadata(String formatName, Set nodeNames,
0797                    boolean wantStream, int imageIndex) throws IOException {
0798                if (formatName == null) {
0799                    throw new IllegalArgumentException("formatName == null!");
0800                }
0801                if (nodeNames == null) {
0802                    throw new IllegalArgumentException("nodeNames == null!");
0803                }
0804                IIOMetadata metadata = wantStream ? getStreamMetadata()
0805                        : getImageMetadata(imageIndex);
0806                if (metadata != null) {
0807                    if (metadata.isStandardMetadataFormatSupported()
0808                            && formatName
0809                                    .equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {
0810                        return metadata;
0811                    }
0812                    String nativeName = metadata.getNativeMetadataFormatName();
0813                    if (nativeName != null && formatName.equals(nativeName)) {
0814                        return metadata;
0815                    }
0816                    String[] extraNames = metadata
0817                            .getExtraMetadataFormatNames();
0818                    if (extraNames != null) {
0819                        for (int i = 0; i < extraNames.length; i++) {
0820                            if (formatName.equals(extraNames[i])) {
0821                                return metadata;
0822                            }
0823                        }
0824                    }
0825                }
0826                return null;
0827            }
0828
0829            /**
0830             * Returns an <code>IIOMetadata</code> object containing metadata
0831             * associated with the given image, or <code>null</code> if the
0832             * reader does not support reading metadata, is set to ignore
0833             * metadata, or if no metadata is available.
0834             *
0835             * @param imageIndex the index of the image whose metadata is to
0836             * be retrieved. 
0837             *
0838             * @return an <code>IIOMetadata</code> object, or
0839             * <code>null</code>.
0840             *
0841             * @exception IllegalStateException if the input source has not been
0842             * set.
0843             * @exception IndexOutOfBoundsException if the supplied index is
0844             * out of bounds.
0845             * @exception IOException if an error occurs during reading.
0846             */
0847            public abstract IIOMetadata getImageMetadata(int imageIndex)
0848                    throws IOException;
0849
0850            /**
0851             * Returns an <code>IIOMetadata</code> object representing the
0852             * metadata associated with the given image, or <code>null</code> 
0853             * if the reader does not support reading metadata or none
0854             * is available.
0855             *
0856             * <p> The resuting metadata object is only responsible for
0857             * returning documents in the format named by
0858             * <code>formatName</code>.  Within any documents that are
0859             * returned, only nodes whose names are members of
0860             * <code>nodeNames</code> are required to be returned.  In this
0861             * way, the amount of metadata processing done by the reader may
0862             * be kept to a minimum, based on what information is actually
0863             * needed.
0864             *
0865             * <p> If <code>formatName</code> is not the name of a supported
0866             * metadata format, <code>null</code> may be returned.
0867             *
0868             * <p> In all cases, it is legal to return a more capable metadata
0869             * object than strictly necessary.  The format name and node names
0870             * are merely hints that may be used to reduce the reader's
0871             * workload.
0872             *
0873             * <p> The default implementation simply returns the result of
0874             * calling <code>getImageMetadata(imageIndex)</code>, after
0875             * checking that the format name is supported.  If it is not,
0876             * <code>null</code> is returned.
0877             *
0878             * @param imageIndex the index of the image whose metadata is to
0879             * be retrieved.
0880             * @param formatName a metadata format name that may be used to retrieve
0881             * a document from the returned <code>IIOMetadata</code> object.
0882             * @param nodeNames a <code>Set</code> containing the names of 
0883             * nodes that may be contained in a retrieved document.
0884             *
0885             * @return an <code>IIOMetadata</code> object, or <code>null</code>.
0886             *
0887             * @exception IllegalStateException if the input source has not been
0888             * set.
0889             * @exception IndexOutOfBoundsException if the supplied index is
0890             * out of bounds.
0891             * @exception IllegalArgumentException if <code>formatName</code>
0892             * is <code>null</code>.
0893             * @exception IllegalArgumentException if <code>nodeNames</code>
0894             * is <code>null</code>.
0895             * @exception IOException if an error occurs during reading.
0896             */
0897            public IIOMetadata getImageMetadata(int imageIndex,
0898                    String formatName, Set<String> nodeNames)
0899                    throws IOException {
0900                return getMetadata(formatName, nodeNames, false, imageIndex);
0901            }
0902
0903            /**
0904             * Reads the image indexed by <code>imageIndex</code> and returns
0905             * it as a complete <code>BufferedImage</code>, using a default
0906             * <code>ImageReadParam</code>.  This is a convenience method
0907             * that calls <code>read(imageIndex, null)</code>.
0908             *
0909             * <p> The image returned will be formatted according to the first
0910             * <code>ImageTypeSpecifier</code> returned from
0911             * <code>getImageTypes</code>.
0912             *
0913             * <p> Any registered <code>IIOReadProgressListener</code> objects
0914             * will be notified by calling their <code>imageStarted</code>
0915             * method, followed by calls to their <code>imageProgress</code>
0916             * method as the read progresses.  Finally their
0917             * <code>imageComplete</code> method will be called.
0918             * <code>IIOReadUpdateListener</code> objects may be updated at
0919             * other times during the read as pixels are decoded.  Finally,
0920             * <code>IIOReadWarningListener</code> objects will receive
0921             * notification of any non-fatal warnings that occur during
0922             * decoding.
0923             *
0924             * @param imageIndex the index of the image to be retrieved.
0925             *
0926             * @return the desired portion of the image as a
0927             * <code>BufferedImage</code>.
0928             *
0929             * @exception IllegalStateException if the input source has not been
0930             * set.
0931             * @exception IndexOutOfBoundsException if the supplied index is
0932             * out of bounds.
0933             * @exception IOException if an error occurs during reading.
0934             */
0935            public BufferedImage read(int imageIndex) throws IOException {
0936                return read(imageIndex, null);
0937            }
0938
0939            /**
0940             * Reads the image indexed by <code>imageIndex</code> and returns
0941             * it as a complete <code>BufferedImage</code>, using a supplied
0942             * <code>ImageReadParam</code>.
0943             *
0944             * <p> The actual <code>BufferedImage</code> returned will be
0945             * chosen using the algorithm defined by the
0946             * <code>getDestination</code> method.
0947             *
0948             * <p> Any registered <code>IIOReadProgressListener</code> objects
0949             * will be notified by calling their <code>imageStarted</code>
0950             * method, followed by calls to their <code>imageProgress</code>
0951             * method as the read progresses.  Finally their
0952             * <code>imageComplete</code> method will be called.
0953             * <code>IIOReadUpdateListener</code> objects may be updated at
0954             * other times during the read as pixels are decoded.  Finally,
0955             * <code>IIOReadWarningListener</code> objects will receive
0956             * notification of any non-fatal warnings that occur during
0957             * decoding.
0958             *
0959             * <p> The set of source bands to be read and destination bands to
0960             * be written is determined by calling <code>getSourceBands</code>
0961             * and <code>getDestinationBands</code> on the supplied
0962             * <code>ImageReadParam</code>.  If the lengths of the arrays
0963             * returned by these methods differ, the set of source bands
0964             * contains an index larger that the largest available source
0965             * index, or the set of destination bands contains an index larger
0966             * than the largest legal destination index, an
0967             * <code>IllegalArgumentException</code> is thrown.
0968             *
0969             * <p> If the supplied <code>ImageReadParam</code> contains
0970             * optional setting values not supported by this reader (<i>e.g.</i>
0971             * source render size or any format-specific settings), they will
0972             * be ignored.
0973             *
0974             * @param imageIndex the index of the image to be retrieved.
0975             * @param param an <code>ImageReadParam</code> used to control
0976             * the reading process, or <code>null</code>.
0977             *
0978             * @return the desired portion of the image as a
0979             * <code>BufferedImage</code>.
0980             *
0981             * @exception IllegalStateException if the input source has not been
0982             * set.
0983             * @exception IndexOutOfBoundsException if the supplied index is
0984             * out of bounds.
0985             * @exception IllegalArgumentException if the set of source and
0986             * destination bands specified by
0987             * <code>param.getSourceBands</code> and
0988             * <code>param.getDestinationBands</code> differ in length or
0989             * include indices that are out of bounds.
0990             * @exception IllegalArgumentException if the resulting image would
0991             * have a width or height less than 1.
0992             * @exception IOException if an error occurs during reading.
0993             */
0994            public abstract BufferedImage read(int imageIndex,
0995                    ImageReadParam param) throws IOException;
0996
0997            /**
0998             * Reads the image indexed by <code>imageIndex</code> and returns
0999             * an <code>IIOImage</code> containing the image, thumbnails, and
1000             * associated image metadata, using a supplied
1001             * <code>ImageReadParam</code>.
1002             *
1003             * <p> The actual <code>BufferedImage</code> referenced by the
1004             * returned <code>IIOImage</code> will be chosen using the
1005             * algorithm defined by the <code>getDestination</code> method.
1006             *
1007             * <p> Any registered <code>IIOReadProgressListener</code> objects
1008             * will be notified by calling their <code>imageStarted</code>
1009             * method, followed by calls to their <code>imageProgress</code>
1010             * method as the read progresses.  Finally their
1011             * <code>imageComplete</code> method will be called.
1012             * <code>IIOReadUpdateListener</code> objects may be updated at
1013             * other times during the read as pixels are decoded.  Finally,
1014             * <code>IIOReadWarningListener</code> objects will receive
1015             * notification of any non-fatal warnings that occur during
1016             * decoding.
1017             *
1018             * <p> The set of source bands to be read and destination bands to
1019             * be written is determined by calling <code>getSourceBands</code>
1020             * and <code>getDestinationBands</code> on the supplied
1021             * <code>ImageReadParam</code>.  If the lengths of the arrays
1022             * returned by these methods differ, the set of source bands
1023             * contains an index larger that the largest available source
1024             * index, or the set of destination bands contains an index larger
1025             * than the largest legal destination index, an
1026             * <code>IllegalArgumentException</code> is thrown.
1027             *
1028             * <p> Thumbnails will be returned in their entirety regardless of
1029             * the region settings.
1030             *
1031             * <p> If the supplied <code>ImageReadParam</code> contains
1032             * optional setting values not supported by this reader (<i>e.g.</i>
1033             * source render size or any format-specific settings), those
1034             * values will be ignored.
1035             *
1036             * @param imageIndex the index of the image to be retrieved.
1037             * @param param an <code>ImageReadParam</code> used to control
1038             * the reading process, or <code>null</code>.
1039             *
1040             * @return an <code>IIOImage</code> containing the desired portion
1041             * of the image, a set of thumbnails, and associated image
1042             * metadata.
1043             *
1044             * @exception IllegalStateException if the input source has not been
1045             * set.
1046             * @exception IndexOutOfBoundsException if the supplied index is
1047             * out of bounds.
1048             * @exception IllegalArgumentException if the set of source and
1049             * destination bands specified by
1050             * <code>param.getSourceBands</code> and
1051             * <code>param.getDestinationBands</code> differ in length or
1052             * include indices that are out of bounds.
1053             * @exception IllegalArgumentException if the resulting image
1054             * would have a width or height less than 1.
1055             * @exception IOException if an error occurs during reading.
1056             */
1057            public IIOImage readAll(int imageIndex, ImageReadParam param)
1058                    throws IOException {
1059                if (imageIndex < getMinIndex()) {
1060                    throw new IndexOutOfBoundsException(
1061                            "imageIndex < getMinIndex()!");
1062                }
1063
1064                BufferedImage im = read(imageIndex, param);
1065
1066                ArrayList thumbnails = null;
1067                int numThumbnails = getNumThumbnails(imageIndex);
1068                if (numThumbnails > 0) {
1069                    thumbnails = new ArrayList();
1070                    for (int j = 0; j < numThumbnails; j++) {
1071                        thumbnails.add(readThumbnail(imageIndex, j));
1072                    }
1073                }
1074
1075                IIOMetadata metadata = getImageMetadata(imageIndex);
1076                return new IIOImage(im, thumbnails, metadata);
1077            }
1078
1079            /**
1080             * Returns an <code>Iterator</code> containing all the images,
1081             * thumbnails, and metadata, starting at the index given by
1082             * <code>getMinIndex</code>, from the input source in the form of
1083             * <code>IIOImage</code> objects.  An <code>Iterator</code>
1084             * containing <code>ImageReadParam</code> objects is supplied; one
1085             * element is consumed for each image read from the input source
1086             * until no more images are available.  If the read param
1087             * <code>Iterator</code> runs out of elements, but there are still
1088             * more images available from the input source, default read
1089             * params are used for the remaining images.
1090             *
1091             * <p> If <code>params</code> is <code>null</code>, a default read
1092             * param will be used for all images.
1093             *
1094             * <p> The actual <code>BufferedImage</code> referenced by the
1095             * returned <code>IIOImage</code> will be chosen using the
1096             * algorithm defined by the <code>getDestination</code> method.
1097             *
1098             * <p> Any registered <code>IIOReadProgressListener</code> objects
1099             * will be notified by calling their <code>sequenceStarted</code>
1100             * method once.  Then, for each image decoded, there will be a
1101             * call to <code>imageStarted</code>, followed by calls to
1102             * <code>imageProgress</code> as the read progresses, and finally
1103             * to <code>imageComplete</code>.  The
1104             * <code>sequenceComplete</code> method will be called after the
1105             * last image has been decoded.
1106             * <code>IIOReadUpdateListener</code> objects may be updated at
1107             * other times during the read as pixels are decoded.  Finally,
1108             * <code>IIOReadWarningListener</code> objects will receive
1109             * notification of any non-fatal warnings that occur during
1110             * decoding.
1111             *
1112             * <p> The set of source bands to be read and destination bands to
1113             * be written is determined by calling <code>getSourceBands</code>
1114             * and <code>getDestinationBands</code> on the supplied
1115             * <code>ImageReadParam</code>.  If the lengths of the arrays
1116             * returned by these methods differ, the set of source bands
1117             * contains an index larger that the largest available source
1118             * index, or the set of destination bands contains an index larger
1119             * than the largest legal destination index, an
1120             * <code>IllegalArgumentException</code> is thrown.
1121             *
1122             * <p> Thumbnails will be returned in their entirety regardless of the
1123             * region settings.
1124             *
1125             * <p> If any of the supplied <code>ImageReadParam</code>s contain
1126             * optional setting values not supported by this reader (<i>e.g.</i>
1127             * source render size or any format-specific settings), they will
1128             * be ignored.
1129             *
1130             * @param params an <code>Iterator</code> containing
1131             * <code>ImageReadParam</code> objects.
1132             *
1133             * @return an <code>Iterator</code> representing the
1134             * contents of the input source as <code>IIOImage</code>s.
1135             *
1136             * @exception IllegalStateException if the input source has not been
1137             * set.
1138             * @exception IllegalArgumentException if any
1139             * non-<code>null</code> element of <code>params</code> is not an
1140             * <code>ImageReadParam</code>.
1141             * @exception IllegalArgumentException if the set of source and
1142             * destination bands specified by
1143             * <code>param.getSourceBands</code> and
1144             * <code>param.getDestinationBands</code> differ in length or
1145             * include indices that are out of bounds.
1146             * @exception IllegalArgumentException if a resulting image would
1147             * have a width or height less than 1.
1148             * @exception IOException if an error occurs during reading.
1149             *
1150             * @see ImageReadParam
1151             * @see IIOImage
1152             */
1153            public Iterator<IIOImage> readAll(
1154                    Iterator<? extends ImageReadParam> params)
1155                    throws IOException {
1156                List output = new ArrayList();
1157
1158                int imageIndex = getMinIndex();
1159
1160                // Inform IIOReadProgressListeners we're starting a sequence
1161                processSequenceStarted(imageIndex);
1162
1163                while (true) {
1164                    // Inform IIOReadProgressListeners and IIOReadUpdateListeners
1165                    // that we're starting a new image
1166
1167                    ImageReadParam param = null;
1168                    if (params != null && params.hasNext()) {
1169                        Object o = params.next();
1170                        if (o != null) {
1171                            if (o instanceof  ImageReadParam) {
1172                                param = (ImageReadParam) o;
1173                            } else {
1174                                throw new IllegalArgumentException(
1175                                        "Non-ImageReadParam supplied as part of params!");
1176                            }
1177                        }
1178                    }
1179
1180                    BufferedImage bi = null;
1181                    try {
1182                        bi = read(imageIndex, param);
1183                    } catch (IndexOutOfBoundsException e) {
1184                        break;
1185                    }
1186
1187                    ArrayList thumbnails = null;
1188                    int numThumbnails = getNumThumbnails(imageIndex);
1189                    if (numThumbnails > 0) {
1190                        thumbnails = new ArrayList();
1191                        for (int j = 0; j < numThumbnails; j++) {
1192                            thumbnails.add(readThumbnail(imageIndex, j));
1193                        }
1194                    }
1195
1196                    IIOMetadata metadata = getImageMetadata(imageIndex);
1197                    IIOImage im = new IIOImage(bi, thumbnails, metadata);
1198                    output.add(im);
1199
1200                    ++imageIndex;
1201                }
1202
1203                // Inform IIOReadProgressListeners we're ending a sequence
1204                processSequenceComplete();
1205
1206                return output.iterator();
1207            }
1208
1209            /**
1210             * Returns <code>true</code> if this plug-in supports reading
1211             * just a {@link java.awt.image.Raster <code>Raster</code>} of pixel data.
1212             * If this method returns <code>false</code>, calls to
1213             * {@link #readRaster <code>readRaster</code>} or {@link #readTileRaster
1214             * <code>readTileRaster</code>} will throw an 
1215             * <code>UnsupportedOperationException</code>.
1216             *
1217             * <p> The default implementation returns <code>false</code>.
1218             * 
1219             * @return <code>true</code> if this plug-in supports reading raw
1220             * <code>Raster</code>s.
1221             * 
1222             * @see #readRaster
1223             * @see #readTileRaster
1224             */
1225            public boolean canReadRaster() {
1226                return false;
1227            }
1228
1229            /**
1230             * Returns a new <code>Raster</code> object containing the raw pixel data
1231             * from the image stream, without any color conversion applied.  The 
1232             * application must determine how to interpret the pixel data by other
1233             * means.  Any destination or image-type parameters in the supplied
1234             * <code>ImageReadParam</code> object are ignored, but all other
1235             * parameters are used exactly as in the {@link #read <code>read</code>}
1236             * method, except that any destination offset is used as a logical rather
1237             * than a physical offset.  The size of the returned <code>Raster</code>
1238             * will always be that of the source region clipped to the actual image.
1239             * Logical offsets in the stream itself are ignored.
1240             *
1241             * <p> This method allows formats that normally apply a color
1242             * conversion, such as JPEG, and formats that do not normally have an
1243             * associated colorspace, such as remote sensing or medical imaging data,
1244             * to provide access to raw pixel data.
1245             *
1246             * <p> Any registered <code>readUpdateListener</code>s are ignored, as
1247             * there is no <code>BufferedImage</code>, but all other listeners are
1248             * called exactly as they are for the {@link #read <code>read</code>}
1249             * method.
1250             *
1251             * <p> If {@link #canReadRaster <code>canReadRaster()</code>} returns
1252             * <code>false</code>, this method throws an 
1253             * <code>UnsupportedOperationException</code>.
1254             *
1255             * <p> If the supplied <code>ImageReadParam</code> contains
1256             * optional setting values not supported by this reader (<i>e.g.</i>
1257             * source render size or any format-specific settings), they will
1258             * be ignored.
1259             *
1260             * <p> The default implementation throws an 
1261             * <code>UnsupportedOperationException</code>.
1262             *
1263             * @param imageIndex the index of the image to be read.
1264             * @param param an <code>ImageReadParam</code> used to control
1265             * the reading process, or <code>null</code>.
1266             *
1267             * @return the desired portion of the image as a
1268             * <code>Raster</code>.
1269             *
1270             * @exception UnsupportedOperationException if this plug-in does not
1271             * support reading raw <code>Raster</code>s.
1272             * @exception IllegalStateException if the input source has not been
1273             * set.
1274             * @exception IndexOutOfBoundsException if the supplied index is
1275             * out of bounds.
1276             * @exception IOException if an error occurs during reading.
1277             *
1278             * @see #canReadRaster
1279             * @see #read
1280             * @see java.awt.image.Raster
1281             */
1282            public Raster readRaster(int imageIndex, ImageReadParam param)
1283                    throws IOException {
1284                throw new UnsupportedOperationException(
1285                        "readRaster not supported!");
1286            }
1287
1288            /**
1289             * Returns <code>true</code> if the image is organized into
1290             * <i>tiles</i>, that is, equal-sized non-overlapping rectangles.
1291             *
1292             * <p> A reader plug-in may choose whether or not to expose tiling
1293             * that is present in the image as it is stored.  It may even
1294             * choose to advertise tiling when none is explicitly present.  In
1295             * general, tiling should only be advertised if there is some
1296             * advantage (in speed or space) to accessing individual tiles.
1297             * Regardless of whether the reader advertises tiling, it must be
1298             * capable of reading an arbitrary rectangular region specified in
1299             * an <code>ImageReadParam</code>.
1300             *
1301             * <p> A reader for which all images are guaranteed to be tiled,
1302             * or are guaranteed not to be tiled, may return <code>true</code>
1303             * or <code>false</code> respectively without accessing any image
1304             * data.  In such cases, it is not necessary to throw an exception
1305             * even if no input source has been set or the image index is out
1306             * of bounds.
1307             *
1308             * <p> The default implementation just returns <code>false</code>.
1309             *
1310             * @param imageIndex the index of the image to be queried.
1311             *
1312             * @return <code>true</code> if the image is tiled.
1313             *
1314             * @exception IllegalStateException if an input source is required
1315             * to determine the return value, but none has been set.
1316             * @exception IndexOutOfBoundsException if an image must be
1317             * accessed to determine the return value, but the supplied index
1318             * is out of bounds.
1319             * @exception IOException if an error occurs during reading.
1320             */
1321            public boolean isImageTiled(int imageIndex) throws IOException {
1322                return false;
1323            }
1324
1325            /**
1326             * Returns the width of a tile in the given image.
1327             *
1328             * <p> The default implementation simply returns
1329             * <code>getWidth(imageIndex)</code>, which is correct for
1330             * non-tiled images.  Readers that support tiling should override
1331             * this method.
1332             *
1333             * @return the width of a tile.
1334             *
1335             * @param imageIndex the index of the image to be queried.
1336             *
1337             * @exception IllegalStateException if the input source has not been set.
1338             * @exception IndexOutOfBoundsException if the supplied index is
1339             * out of bounds.
1340             * @exception IOException if an error occurs during reading.
1341             */
1342            public int getTileWidth(int imageIndex) throws IOException {
1343                return getWidth(imageIndex);
1344            }
1345
1346            /**
1347             * Returns the height of a tile in the given image.
1348             *
1349             * <p> The default implementation simply returns
1350             * <code>getHeight(imageIndex)</code>, which is correct for
1351             * non-tiled images.  Readers that support tiling should override
1352             * this method.
1353             *
1354             * @return the height of a tile.
1355             *
1356             * @param imageIndex the index of the image to be queried.
1357             *
1358             * @exception IllegalStateException if the input source has not been set.
1359             * @exception IndexOutOfBoundsException if the supplied index is
1360             * out of bounds.
1361             * @exception IOException if an error occurs during reading.
1362             */
1363            public int getTileHeight(int imageIndex) throws IOException {
1364                return getHeight(imageIndex);
1365            }
1366
1367            /**
1368             * Returns the X coordinate of the upper-left corner of tile (0,
1369             * 0) in the given image.
1370             *
1371             * <p> A reader for which the tile grid X offset always has the
1372             * same value (usually 0), may return the value without accessing
1373             * any image data.  In such cases, it is not necessary to throw an
1374             * exception even if no input source has been set or the image
1375             * index is out of bounds.
1376             *
1377             * <p> The default implementation simply returns 0, which is
1378             * correct for non-tiled images and tiled images in most formats.
1379             * Readers that support tiling with non-(0, 0) offsets should
1380             * override this method.
1381             *
1382             * @return the X offset of the tile grid.
1383             *
1384             * @param imageIndex the index of the image to be queried.
1385             *
1386             * @exception IllegalStateException if an input source is required
1387             * to determine the return value, but none has been set.
1388             * @exception IndexOutOfBoundsException if an image must be
1389             * accessed to determine the return value, but the supplied index
1390             * is out of bounds.
1391             * @exception IOException if an error occurs during reading.
1392             */
1393            public int getTileGridXOffset(int imageIndex) throws IOException {
1394                return 0;
1395            }
1396
1397            /**
1398             * Returns the Y coordinate of the upper-left corner of tile (0,
1399             * 0) in the given image.
1400             *
1401             * <p> A reader for which the tile grid Y offset always has the
1402             * same value (usually 0), may return the value without accessing
1403             * any image data.  In such cases, it is not necessary to throw an
1404             * exception even if no input source has been set or the image
1405             * index is out of bounds.
1406             *
1407             * <p> The default implementation simply returns 0, which is
1408             * correct for non-tiled images and tiled images in most formats.
1409             * Readers that support tiling with non-(0, 0) offsets should
1410             * override this method.
1411             *
1412             * @return the Y offset of the tile grid.
1413             *
1414             * @param imageIndex the index of the image to be queried.
1415             *
1416             * @exception IllegalStateException if an input source is required
1417             * to determine the return value, but none has been set.
1418             * @exception IndexOutOfBoundsException if an image must be
1419             * accessed to determine the return value, but the supplied index
1420             * is out of bounds.
1421             * @exception IOException if an error occurs during reading.
1422             */
1423            public int getTileGridYOffset(int imageIndex) throws IOException {
1424                return 0;
1425            }
1426
1427            /**
1428             * Reads the tile indicated by the <code>tileX</code> and
1429             * <code>tileY</code> arguments, returning it as a
1430             * <code>BufferedImage</code>.  If the arguments are out of range,
1431             * an <code>IllegalArgumentException</code> is thrown.  If the
1432             * image is not tiled, the values 0, 0 will return the entire
1433             * image; any other values will cause an
1434             * <code>IllegalArgumentException</code> to be thrown.
1435             *
1436             * <p> This method is merely a convenience equivalent to calling
1437             * <code>read(int, ImageReadParam)</code> with a read param
1438             * specifiying a source region having offsets of
1439             * <code>tileX*getTileWidth(imageIndex)</code>,
1440             * <code>tileY*getTileHeight(imageIndex)</code> and width and
1441             * height of <code>getTileWidth(imageIndex)</code>,
1442             * <code>getTileHeight(imageIndex)</code>; and subsampling
1443             * factors of 1 and offsets of 0.  To subsample a tile, call
1444             * <code>read</code> with a read param specifying this region
1445             * and different subsampling parameters.
1446             *
1447             * <p> The default implementation returns the entire image if 
1448             * <code>tileX</code> and <code>tileY</code> are 0, or throws
1449             * an <code>IllegalArgumentException</code> otherwise.
1450             *
1451             * @param imageIndex the index of the image to be retrieved.
1452             * @param tileX the column index (starting with 0) of the tile
1453             * to be retrieved.
1454             * @param tileY the row index (starting with 0) of the tile
1455             * to be retrieved.
1456             *
1457             * @return the tile as a <code>BufferedImage</code>.
1458             *
1459             * @exception IllegalStateException if the input source has not been
1460             * set.
1461             * @exception IndexOutOfBoundsException if <code>imageIndex</code>
1462             * is out of bounds.
1463             * @exception IllegalArgumentException if the tile indices are
1464             * out of bounds.
1465             * @exception IOException if an error occurs during reading.
1466             */
1467            public BufferedImage readTile(int imageIndex, int tileX, int tileY)
1468                    throws IOException {
1469                if ((tileX != 0) || (tileY != 0)) {
1470                    throw new IllegalArgumentException("Invalid tile indices");
1471                }
1472                return read(imageIndex);
1473            }
1474
1475            /**
1476             * Returns a new <code>Raster</code> object containing the raw
1477             * pixel data from the tile, without any color conversion applied.
1478             * The application must determine how to interpret the pixel data by other
1479             * means.  
1480             *
1481             * <p> If {@link #canReadRaster <code>canReadRaster()</code>} returns
1482             * <code>false</code>, this method throws an 
1483             * <code>UnsupportedOperationException</code>.
1484             *
1485             * <p> The default implementation checks if reading
1486             * <code>Raster</code>s is supported, and if so calls {@link
1487             * #readRaster <code>readRaster(imageIndex, null)</code>} if
1488             * <code>tileX</code> and <code>tileY</code> are 0, or throws an
1489             * <code>IllegalArgumentException</code> otherwise.
1490             *
1491             * @param imageIndex the index of the image to be retrieved.
1492             * @param tileX the column index (starting with 0) of the tile
1493             * to be retrieved.
1494             * @param tileY the row index (starting with 0) of the tile
1495             * to be retrieved.
1496             *
1497             * @return the tile as a <code>Raster</code>.
1498             *
1499             * @exception UnsupportedOperationException if this plug-in does not
1500             * support reading raw <code>Raster</code>s.
1501             * @exception IllegalArgumentException if the tile indices are
1502             * out of bounds.
1503             * @exception IllegalStateException if the input source has not been
1504             * set.
1505             * @exception IndexOutOfBoundsException if <code>imageIndex</code>
1506             * is out of bounds.
1507             * @exception IOException if an error occurs during reading.
1508             *
1509             * @see #readTile
1510             * @see #readRaster
1511             * @see java.awt.image.Raster
1512             */
1513            public Raster readTileRaster(int imageIndex, int tileX, int tileY)
1514                    throws IOException {
1515                if (!canReadRaster()) {
1516                    throw new UnsupportedOperationException(
1517                            "readTileRaster not supported!");
1518                }
1519                if ((tileX != 0) || (tileY != 0)) {
1520                    throw new IllegalArgumentException("Invalid tile indices");
1521                }
1522                return readRaster(imageIndex, null);
1523            }
1524
1525            // RenderedImages
1526
1527            /**
1528             * Returns a <code>RenderedImage</code> object that contains the
1529             * contents of the image indexed by <code>imageIndex</code>.  By
1530             * default, the returned image is simply the
1531             * <code>BufferedImage</code> returned by <code>read(imageIndex,
1532             * param)</code>.
1533             *
1534             * <p> The semantics of this method may differ from those of the
1535             * other <code>read</code> methods in several ways.  First, any
1536             * destination image and/or image type set in the
1537             * <code>ImageReadParam</code> may be ignored.  Second, the usual
1538             * listener calls are not guaranteed to be made, or to be
1539             * meaningful if they are.  This is because the returned image may
1540             * not be fully populated with pixel data at the time it is
1541             * returned, or indeed at any time.
1542             *
1543             * <p> If the supplied <code>ImageReadParam</code> contains
1544             * optional setting values not supported by this reader (<i>e.g.</i>
1545             * source render size or any format-specific settings), they will
1546             * be ignored.
1547             *
1548             * <p> The default implementation just calls {@link #read
1549             * <code>read(imageIndex, param)</code>}.
1550             *
1551             * @param imageIndex the index of the image to be retrieved.
1552             * @param param an <code>ImageReadParam</code> used to control
1553             * the reading process, or <code>null</code>.
1554             *
1555             * @return a <code>RenderedImage</code> object providing a view of
1556             * the image.
1557             *
1558             * @exception IllegalStateException if the input source has not been
1559             * set.
1560             * @exception IndexOutOfBoundsException if the supplied index is
1561             * out of bounds.
1562             * @exception IllegalArgumentException if the set of source and
1563             * destination bands specified by
1564             * <code>param.getSourceBands</code> and
1565             * <code>param.getDestinationBands</code> differ in length or
1566             * include indices that are out of bounds.
1567             * @exception IllegalArgumentException if the resulting image
1568             * would have a width or height less than 1.
1569             * @exception IOException if an error occurs during reading.
1570             */
1571            public RenderedImage readAsRenderedImage(int imageIndex,
1572                    ImageReadParam param) throws IOException {
1573                return read(imageIndex, param);
1574            }
1575
1576            // Thumbnails
1577
1578            /**
1579             * Returns <code>true</code> if the image format understood by
1580             * this reader supports thumbnail preview images associated with
1581             * it.  The default implementation returns <code>false</code>.
1582             *
1583             * <p> If this method returns <code>false</code>,
1584             * <code>hasThumbnails</code> and <code>getNumThumbnails</code>
1585             * will return <code>false</code> and <code>0</code>,
1586             * respectively, and <code>readThumbnail</code> will throw an
1587             * <code>UnsupportedOperationException</code>, regardless of their
1588             * arguments.
1589             *
1590             * <p> A reader that does not support thumbnails need not
1591             * implement any of the thumbnail-related methods.
1592             *
1593             * @return <code>true</code> if thumbnails are supported.
1594             */
1595            public boolean readerSupportsThumbnails() {
1596                return false;
1597            }
1598
1599            /**
1600             * Returns <code>true</code> if the given image has thumbnail
1601             * preview images associated with it.  If the format does not
1602             * support thumbnails (<code>readerSupportsThumbnails</code>
1603             * returns <code>false</code>), <code>false</code> will be
1604             * returned regardless of whether an input source has been set or
1605             * whether <code>imageIndex</code> is in bounds.
1606             *
1607             * <p> The default implementation returns <code>true</code> if
1608             * <code>getNumThumbnails</code> returns a value greater than 0.
1609             *
1610             * @param imageIndex the index of the image being queried.
1611             *
1612             * @return <code>true</code> if the given image has thumbnails.
1613             *
1614             * @exception IllegalStateException if the reader supports
1615             * thumbnails but the input source has not been set.
1616             * @exception IndexOutOfBoundsException if the reader supports
1617             * thumbnails but <code>imageIndex</code> is out of bounds.
1618             * @exception IOException if an error occurs during reading.
1619             */
1620            public boolean hasThumbnails(int imageIndex) throws IOException {
1621                return getNumThumbnails(imageIndex) > 0;
1622            }
1623
1624            /**
1625             * Returns the number of thumbnail preview images associated with
1626             * the given image.  If the format does not support thumbnails,
1627             * (<code>readerSupportsThumbnails</code> returns
1628             * <code>false</code>), <code>0</code> will be returned regardless
1629             * of whether an input source has been set or whether
1630             * <code>imageIndex</code> is in bounds.
1631             *
1632             * <p> The default implementation returns 0 without checking its
1633             * argument.
1634             *
1635             * @param imageIndex the index of the image being queried.
1636             *
1637             * @return the number of thumbnails associated with the given
1638             * image.
1639             *
1640             * @exception IllegalStateException if the reader supports
1641             * thumbnails but the input source has not been set.
1642             * @exception IndexOutOfBoundsException if the reader supports
1643             * thumbnails but <code>imageIndex</code> is out of bounds.
1644             * @exception IOException if an error occurs during reading.
1645             */
1646            public int getNumThumbnails(int imageIndex) throws IOException {
1647                return 0;
1648            }
1649
1650            /**
1651             * Returns the width of the thumbnail preview image indexed by
1652             * <code>thumbnailIndex</code>, associated with the image indexed
1653             * by <code>ImageIndex</code>.
1654             *
1655             * <p> If the reader does not support thumbnails,
1656             * (<code>readerSupportsThumbnails</code> returns
1657             * <code>false</code>), an <code>UnsupportedOperationException</code>
1658             * will be thrown.
1659             *
1660             * <p> The default implementation simply returns
1661             * <code>readThumbnail(imageindex,
1662             * thumbnailIndex).getWidth()</code>.  Subclasses should therefore
1663             * override this method if possible in order to avoid forcing the
1664             * thumbnail to be read.
1665             *
1666             * @param imageIndex the index of the image to be retrieved.
1667             * @param thumbnailIndex the index of the thumbnail to be retrieved.
1668             *
1669             * @return the width of the desired thumbnail as an <code>int</code>.
1670             *
1671             * @exception UnsupportedOperationException if thumbnails are not
1672             * supported.
1673             * @exception IllegalStateException if the input source has not been set.
1674             * @exception IndexOutOfBoundsException if either of the supplied
1675             * indices are out of bounds.
1676             * @exception IOException if an error occurs during reading.
1677             */
1678            public int getThumbnailWidth(int imageIndex, int thumbnailIndex)
1679                    throws IOException {
1680                return readThumbnail(imageIndex, thumbnailIndex).getWidth();
1681            }
1682
1683            /**
1684             * Returns the height of the thumbnail preview image indexed by
1685             * <code>thumbnailIndex</code>, associated with the image indexed
1686             * by <code>ImageIndex</code>.
1687             *
1688             * <p> If the reader does not support thumbnails,
1689             * (<code>readerSupportsThumbnails</code> returns
1690             * <code>false</code>), an <code>UnsupportedOperationException</code>
1691             * will be thrown.
1692             *
1693             * <p> The default implementation simply returns
1694             * <code>readThumbnail(imageindex,
1695             * thumbnailIndex).getHeight()</code>.  Subclasses should
1696             * therefore override this method if possible in order to avoid
1697             * forcing the thumbnail to be read.
1698             *
1699             * @param imageIndex the index of the image to be retrieved.
1700             * @param thumbnailIndex the index of the thumbnail to be retrieved.
1701             *
1702             * @return the height of the desired thumbnail as an <code>int</code>.
1703             * 
1704             * @exception UnsupportedOperationException if thumbnails are not
1705             * supported.
1706             * @exception IllegalStateException if the input source has not been set.
1707             * @exception IndexOutOfBoundsException if either of the supplied
1708             * indices are out of bounds.
1709             * @exception IOException if an error occurs during reading.
1710             */
1711            public int getThumbnailHeight(int imageIndex, int thumbnailIndex)
1712                    throws IOException {
1713                return readThumbnail(imageIndex, thumbnailIndex).getHeight();
1714            }
1715
1716            /**
1717             * Returns the thumbnail preview image indexed by
1718             * <code>thumbnailIndex</code>, associated with the image indexed
1719             * by <code>ImageIndex</code> as a <code>BufferedImage</code>.
1720             *
1721             * <p> Any registered <code>IIOReadProgressListener</code> objects
1722             * will be notified by calling their
1723             * <code>thumbnailStarted</code>, <code>thumbnailProgress</code>,
1724             * and <code>thumbnailComplete</code> methods.
1725             *
1726             * <p> If the reader does not support thumbnails,
1727             * (<code>readerSupportsThumbnails</code> returns
1728             * <code>false</code>), an <code>UnsupportedOperationException</code>
1729             * will be thrown regardless of whether an input source has been
1730             * set or whether the indices are in bounds.
1731             *
1732             * <p> The default implementation throws an
1733             * <code>UnsupportedOperationException</code>.
1734             *
1735             * @param imageIndex the index of the image to be retrieved.
1736             * @param thumbnailIndex the index of the thumbnail to be retrieved.
1737             *
1738             * @return the desired thumbnail as a <code>BufferedImage</code>.
1739             *
1740             * @exception UnsupportedOperationException if thumbnails are not
1741             * supported.
1742             * @exception IllegalStateException if the input source has not been set.
1743             * @exception IndexOutOfBoundsException if either of the supplied
1744             * indices are out of bounds.
1745             * @exception IOException if an error occurs during reading.
1746             */
1747            public BufferedImage readThumbnail(int imageIndex,
1748                    int thumbnailIndex) throws IOException {
1749                throw new UnsupportedOperationException(
1750                        "Thumbnails not supported!");
1751            }
1752
1753            // Abort
1754
1755            /**
1756             * Requests that any current read operation be aborted.  The
1757             * contents of the image following the abort will be undefined.
1758             *
1759             * <p> Readers should call <code>clearAbortRequest</code> at the
1760             * beginning of each read operation, and poll the value of
1761             * <code>abortRequested</code> regularly during the read.
1762             */
1763            public synchronized void abort() {
1764                this .abortFlag = true;
1765            }
1766
1767            /**
1768             * Returns <code>true</code> if a request to abort the current
1769             * read operation has been made since the reader was instantiated or
1770             * <code>clearAbortRequest</code> was called.
1771             *
1772             * @return <code>true</code> if the current read operation should
1773             * be aborted.
1774             *
1775             * @see #abort
1776             * @see #clearAbortRequest
1777             */
1778            protected synchronized boolean abortRequested() {
1779                return this .abortFlag;
1780            }
1781
1782            /**
1783             * Clears any previous abort request.  After this method has been
1784             * called, <code>abortRequested</code> will return
1785             * <code>false</code>.
1786             *
1787             * @see #abort
1788             * @see #abortRequested
1789             */
1790            protected synchronized void clearAbortRequest() {
1791                this .abortFlag = false;
1792            }
1793
1794            // Listeners
1795
1796            // Add an element to a list, creating a new list if the
1797            // existing list is null, and return the list.
1798            static List addToList(List l, Object elt) {
1799                if (l == null) {
1800                    l = new ArrayList();
1801                }
1802                l.add(elt);
1803                return l;
1804            }
1805
1806            // Remove an element from a list, discarding the list if the
1807            // resulting list is empty, and return the list or null.
1808            static List removeFromList(List l, Object elt) {
1809                if (l == null) {
1810                    return l;
1811                }
1812                l.remove(elt);
1813                if (l.size() == 0) {
1814                    l = null;
1815                }
1816                return l;
1817            }
1818
1819            /**
1820             * Adds an <code>IIOReadWarningListener</code> to the list of
1821             * registered warning listeners.  If <code>listener</code> is
1822             * <code>null</code>, no exception will be thrown and no action
1823             * will be taken.  Messages sent to the given listener will be
1824             * localized, if possible, to match the current
1825             * <code>Locale</code>.  If no <code>Locale</code> has been set,
1826             * warning messages may be localized as the reader sees fit.
1827             *
1828             * @param listener an <code>IIOReadWarningListener</code> to be registered.
1829             *
1830             * @see #removeIIOReadWarningListener
1831             */
1832            public void addIIOReadWarningListener(
1833                    IIOReadWarningListener listener) {
1834                if (listener == null) {
1835                    return;
1836                }
1837                warningListeners = addToList(warningListeners, listener);
1838                warningLocales = addToList(warningLocales, getLocale());
1839            }
1840
1841            /**
1842             * Removes an <code>IIOReadWarningListener</code> from the list of
1843             * registered error listeners.  If the listener was not previously
1844             * registered, or if <code>listener</code> is <code>null</code>,
1845             * no exception will be thrown and no action will be taken.
1846             *
1847             * @param listener an IIOReadWarningListener to be unregistered.
1848             *
1849             * @see #addIIOReadWarningListener
1850             */
1851            public void removeIIOReadWarningListener(
1852                    IIOReadWarningListener listener) {
1853                if (listener == null || warningListeners == null) {
1854                    return;
1855                }
1856                int index = warningListeners.indexOf(listener);
1857                if (index != -1) {
1858                    warningListeners.remove(index);
1859                    warningLocales.remove(index);
1860                    if (warningListeners.size() == 0) {
1861                        warningListeners = null;
1862                        warningLocales = null;
1863                    }
1864                }
1865            }
1866
1867            /**
1868             * Removes all currently registered
1869             * <code>IIOReadWarningListener</code> objects.
1870             *
1871             * <p> The default implementation sets the
1872             * <code>warningListeners</code> and <code>warningLocales</code>
1873             * instance variables to <code>null</code>.
1874             */
1875            public void removeAllIIOReadWarningListeners() {
1876                warningListeners = null;
1877                warningLocales = null;
1878            }
1879
1880            /**
1881             * Adds an <code>IIOReadProgressListener</code> to the list of
1882             * registered progress listeners.  If <code>listener</code> is
1883             * <code>null</code>, no exception will be thrown and no action
1884             * will be taken.
1885             *
1886             * @param listener an IIOReadProgressListener to be registered.
1887             *
1888             * @see #removeIIOReadProgressListener
1889             */
1890            public void addIIOReadProgressListener(
1891                    IIOReadProgressListener listener) {
1892                if (listener == null) {
1893                    return;
1894                }
1895                progressListeners = addToList(progressListeners, listener);
1896            }
1897
1898            /**
1899             * Removes an <code>IIOReadProgressListener</code> from the list
1900             * of registered progress listeners.  If the listener was not
1901             * previously registered, or if <code>listener</code> is
1902             * <code>null</code>, no exception will be thrown and no action
1903             * will be taken.
1904             *
1905             * @param listener an IIOReadProgressListener to be unregistered.
1906             *
1907             * @see #addIIOReadProgressListener
1908             */
1909            public void removeIIOReadProgressListener(
1910                    IIOReadProgressListener listener) {
1911                if (listener == null || progressListeners == null) {
1912                    return;
1913                }
1914                progressListeners = removeFromList(progressListeners, listener);
1915            }
1916
1917            /**
1918             * Removes all currently registered
1919             * <code>IIOReadProgressListener</code> objects.
1920             *
1921             * <p> The default implementation sets the
1922             * <code>progressListeners</code> instance variable to
1923             * <code>null</code>.
1924             */
1925            public void removeAllIIOReadProgressListeners() {
1926                progressListeners = null;
1927            }
1928
1929            /**
1930             * Adds an <code>IIOReadUpdateListener</code> to the list of
1931             * registered update listeners.  If <code>listener</code> is
1932             * <code>null</code>, no exception will be thrown and no action
1933             * will be taken.  The listener will receive notification of pixel
1934             * updates as images and thumbnails are decoded, including the
1935             * starts and ends of progressive passes.
1936             *
1937             * <p> If no update listeners are present, the reader may choose
1938             * to perform fewer updates to the pixels of the destination
1939             * images and/or thumbnails, which may result in more efficient
1940             * decoding.
1941             *
1942             * <p> For example, in progressive JPEG decoding each pass
1943             * contains updates to a set of coefficients, which would have to
1944             * be transformed into pixel values and converted to an RGB color
1945             * space for each pass if listeners are present.  If no listeners
1946             * are present, the coefficients may simply be accumulated and the
1947             * final results transformed and color converted one time only.
1948             *
1949             * <p> The final results of decoding will be the same whether or
1950             * not intermediate updates are performed.  Thus if only the final
1951             * image is desired it may be perferable not to register any
1952             * <code>IIOReadUpdateListener</code>s.  In general, progressive
1953             * updating is most effective when fetching images over a network
1954             * connection that is very slow compared to local CPU processing;
1955             * over a fast connection, progressive updates may actually slow
1956             * down the presentation of the image.
1957             *
1958             * @param listener an IIOReadUpdateListener to be registered.
1959             *
1960             * @see #removeIIOReadUpdateListener
1961             */
1962            public void addIIOReadUpdateListener(IIOReadUpdateListener listener) {
1963                if (listener == null) {
1964                    return;
1965                }
1966                updateListeners = addToList(updateListeners, listener);
1967            }
1968
1969            /**
1970             * Removes an <code>IIOReadUpdateListener</code> from the list of
1971             * registered update listeners.  If the listener was not
1972             * previously registered, or if <code>listener</code> is
1973             * <code>null</code>, no exception will be thrown and no action
1974             * will be taken.
1975             *
1976             * @param listener an IIOReadUpdateListener to be unregistered.
1977             *
1978             * @see #addIIOReadUpdateListener
1979             */
1980            public void removeIIOReadUpdateListener(
1981                    IIOReadUpdateListener listener) {
1982                if (listener == null || updateListeners == null) {
1983                    return;
1984                }
1985                updateListeners = removeFromList(updateListeners, listener);
1986            }
1987
1988            /**
1989             * Removes all currently registered
1990             * <code>IIOReadUpdateListener</code> objects.
1991             *
1992             * <p> The default implementation sets the
1993             * <code>updateListeners</code> instance variable to
1994             * <code>null</code>.
1995             */
1996            public void removeAllIIOReadUpdateListeners() {
1997                updateListeners = null;
1998            }
1999
2000            /**
2001             * Broadcasts the start of an sequence of image reads to all
2002             * registered <code>IIOReadProgressListener</code>s by calling
2003             * their <code>sequenceStarted</code> method.  Subclasses may use
2004             * this method as a convenience.
2005             *
2006             * @param minIndex the lowest index being read.
2007             */
2008            protected void processSequenceStarted(int minIndex) {
2009                if (progressListeners == null) {
2010                    return;
2011                }
2012                int numListeners = progressListeners.size();
2013                for (int i = 0; i < numListeners; i++) {
2014                    IIOReadProgressListener listener = (IIOReadProgressListener) progressListeners
2015                            .get(i);
2016                    listener.sequenceStarted(this , minIndex);
2017                }
2018            }
2019
2020            /**
2021             * Broadcasts the completion of an sequence of image reads to all
2022             * registered <code>IIOReadProgressListener</code>s by calling
2023             * their <code>sequenceComplete</code> method.  Subclasses may use
2024             * this method as a convenience.
2025             */
2026            protected void processSequenceComplete() {
2027                if (progressListeners == null) {
2028                    return;
2029                }
2030                int numListeners = progressListeners.size();
2031                for (int i = 0; i < numListeners; i++) {
2032                    IIOReadProgressListener listener = (IIOReadProgressListener) progressListeners
2033                            .get(i);
2034                    listener.sequenceComplete(this );
2035                }
2036            }
2037
2038            /**
2039             * Broadcasts the start of an image read to all registered
2040             * <code>IIOReadProgressListener</code>s by calling their
2041             * <code>imageStarted</code> method.  Subclasses may use this
2042             * method as a convenience.
2043             *
2044             * @param imageIndex the index of the image about to be read.
2045             */
2046            protected void processImageStarted(int imageIndex) {
2047                if (progressListeners == null) {
2048                    return;
2049                }
2050                int numListeners = progressListeners.size();
2051                for (int i = 0; i < numListeners; i++) {
2052                    IIOReadProgressListener listener = (IIOReadProgressListener) progressListeners
2053                            .get(i);
2054                    listener.imageStarted(this , imageIndex);
2055                }
2056            }
2057
2058            /**
2059             * Broadcasts the current percentage of image completion to all
2060             * registered <code>IIOReadProgressListener</code>s by calling
2061             * their <code>imageProgress</code> method.  Subclasses may use
2062             * this method as a convenience.
2063             *
2064             * @param percentageDone the current percentage of completion,
2065             * as a <code>float</code>.
2066             */
2067            protected void processImageProgress(float percentageDone) {
2068                if (progressListeners == null) {
2069                    return;
2070                }
2071                int numListeners = progressListeners.size();
2072                for (int i = 0; i < numListeners; i++) {
2073                    IIOReadProgressListener listener = (IIOReadProgressListener) progressListeners
2074                            .get(i);
2075                    listener.imageProgress(this , percentageDone);
2076                }
2077            }
2078
2079            /**
2080             * Broadcasts the completion of an image read to all registered
2081             * <code>IIOReadProgressListener</code>s by calling their
2082             * <code>imageComplete</code> method.  Subclasses may use this
2083             * method as a convenience.
2084             */
2085            protected void processImageComplete() {
2086                if (progressListeners == null) {
2087                    return;
2088                }
2089                int numListeners = progressListeners.size();
2090                for (int i = 0; i < numListeners; i++) {
2091                    IIOReadProgressListener listener = (IIOReadProgressListener) progressListeners
2092                            .get(i);
2093                    listener.imageComplete(this );
2094                }
2095            }
2096
2097            /**
2098             * Broadcasts the start of a thumbnail read to all registered
2099             * <code>IIOReadProgressListener</code>s by calling their
2100             * <code>thumbnailStarted</code> method.  Subclasses may use this
2101             * method as a convenience.
2102             *
2103             * @param imageIndex the index of the image associated with the
2104             * thumbnail.
2105             * @param thumbnailIndex the index of the thumbnail.
2106             */
2107            protected void processThumbnailStarted(int imageIndex,
2108                    int thumbnailIndex) {
2109                if (progressListeners == null) {
2110                    return;
2111                }
2112                int numListeners = progressListeners.size();
2113                for (int i = 0; i < numListeners; i++) {
2114                    IIOReadProgressListener listener = (IIOReadProgressListener) progressListeners
2115                            .get(i);
2116                    listener.thumbnailStarted(this , imageIndex, thumbnailIndex);
2117                }
2118            }
2119
2120            /**
2121             * Broadcasts the current percentage of thumbnail completion to
2122             * all registered <code>IIOReadProgressListener</code>s by calling
2123             * their <code>thumbnailProgress</code> method.  Subclasses may
2124             * use this method as a convenience.
2125             *
2126             * @param percentageDone the current percentage of completion,
2127             * as a <code>float</code>.
2128             */
2129            protected void processThumbnailProgress(float percentageDone) {
2130                if (progressListeners == null) {
2131                    return;
2132                }
2133                int numListeners = progressListeners.size();
2134                for (int i = 0; i < numListeners; i++) {
2135                    IIOReadProgressListener listener = (IIOReadProgressListener) progressListeners
2136                            .get(i);
2137                    listener.thumbnailProgress(this , percentageDone);
2138                }
2139            }
2140
2141            /**
2142             * Broadcasts the completion of a thumbnail read to all registered
2143             * <code>IIOReadProgressListener</code>s by calling their
2144             * <code>thumbnailComplete</code> method.  Subclasses may use this
2145             * method as a convenience.
2146             */
2147            protected void processThumbnailComplete() {
2148                if (progressListeners == null) {
2149                    return;
2150                }
2151                int numListeners = progressListeners.size();
2152                for (int i = 0; i < numListeners; i++) {
2153                    IIOReadProgressListener listener = (IIOReadProgressListener) progressListeners
2154                            .get(i);
2155                    listener.thumbnailComplete(this );
2156                }
2157            }
2158
2159            /**
2160             * Broadcasts that the read has been aborted to all registered
2161             * <code>IIOReadProgressListener</code>s by calling their
2162             * <code>readAborted</code> method.  Subclasses may use this
2163             * method as a convenience.
2164             */
2165            protected void processReadAborted() {
2166                if (progressListeners == null) {
2167                    return;
2168                }
2169                int numListeners = progressListeners.size();
2170                for (int i = 0; i < numListeners; i++) {
2171                    IIOReadProgressListener listener = (IIOReadProgressListener) progressListeners
2172                            .get(i);
2173                    listener.readAborted(this );
2174                }
2175            }
2176
2177            /**
2178             * Broadcasts the beginning of a progressive pass to all
2179             * registered <code>IIOReadUpdateListener</code>s by calling their
2180             * <code>passStarted</code> method.  Subclasses may use this
2181             * method as a convenience.
2182             *
2183             * @param theImage the <code>BufferedImage</code> being updated.
2184             * @param pass the index of the current pass, starting with 0.
2185             * @param minPass the index of the first pass that will be decoded.
2186             * @param maxPass the index of the last pass that will be decoded.
2187             * @param minX the X coordinate of the upper-left pixel included
2188             * in the pass.
2189             * @param minY the X coordinate of the upper-left pixel included
2190             * in the pass.
2191             * @param periodX the horizontal separation between pixels.
2192             * @param periodY the vertical separation between pixels.
2193             * @param bands an array of <code>int</code>s indicating the
2194             * set of affected bands of the destination.
2195             */
2196            protected void processPassStarted(BufferedImage theImage, int pass,
2197                    int minPass, int maxPass, int minX, int minY, int periodX,
2198                    int periodY, int[] bands) {
2199                if (updateListeners == null) {
2200                    return;
2201                }
2202                int numListeners = updateListeners.size();
2203                for (int i = 0; i < numListeners; i++) {
2204                    IIOReadUpdateListener listener = (IIOReadUpdateListener) updateListeners
2205                            .get(i);
2206                    listener.passStarted(this , theImage, pass, minPass,
2207                            maxPass, minX, minY, periodX, periodY, bands);
2208                }
2209            }
2210
2211            /**
2212             * Broadcasts the update of a set of samples to all registered
2213             * <code>IIOReadUpdateListener</code>s by calling their
2214             * <code>imageUpdate</code> method.  Subclasses may use this
2215             * method as a convenience.
2216             *
2217             * @param theImage the <code>BufferedImage</code> being updated.
2218             * @param minX the X coordinate of the upper-left pixel included
2219             * in the pass.
2220             * @param minY the X coordinate of the upper-left pixel included
2221             * in the pass.
2222             * @param width the total width of the area being updated, including
2223             * pixels being skipped if <code>periodX &gt; 1</code>.
2224             * @param height the total height of the area being updated,
2225             * including pixels being skipped if <code>periodY &gt; 1</code>.
2226             * @param periodX the horizontal separation between pixels.
2227             * @param periodY the vertical separation between pixels.
2228             * @param bands an array of <code>int</code>s indicating the
2229             * set of affected bands of the destination.
2230             */
2231            protected void processImageUpdate(BufferedImage theImage, int minX,
2232                    int minY, int width, int height, int periodX, int periodY,
2233                    int[] bands) {
2234                if (updateListeners == null) {
2235                    return;
2236                }
2237                int numListeners = updateListeners.size();
2238                for (int i = 0; i < numListeners; i++) {
2239                    IIOReadUpdateListener listener = (IIOReadUpdateListener) updateListeners
2240                            .get(i);
2241                    listener.imageUpdate(this , theImage, minX, minY, width,
2242                            height, periodX, periodY, bands);
2243                }
2244            }
2245
2246            /**
2247             * Broadcasts the end of a progressive pass to all
2248             * registered <code>IIOReadUpdateListener</code>s by calling their
2249             * <code>passComplete</code> method.  Subclasses may use this
2250             * method as a convenience.
2251             *
2252             * @param theImage the <code>BufferedImage</code> being updated.
2253             */
2254            protected void processPassComplete(BufferedImage theImage) {
2255                if (updateListeners == null) {
2256                    return;
2257                }
2258                int numListeners = updateListeners.size();
2259                for (int i = 0; i < numListeners; i++) {
2260                    IIOReadUpdateListener listener = (IIOReadUpdateListener) updateListeners
2261                            .get(i);
2262                    listener.passComplete(this , theImage);
2263                }
2264            }
2265
2266            /**
2267             * Broadcasts the beginning of a thumbnail progressive pass to all
2268             * registered <code>IIOReadUpdateListener</code>s by calling their
2269             * <code>thumbnailPassStarted</code> method.  Subclasses may use this
2270             * method as a convenience.
2271             *
2272             * @param theThumbnail the <code>BufferedImage</code> thumbnail
2273             * being updated.
2274             * @param pass the index of the current pass, starting with 0.
2275             * @param minPass the index of the first pass that will be decoded.
2276             * @param maxPass the index of the last pass that will be decoded.
2277             * @param minX the X coordinate of the upper-left pixel included
2278             * in the pass.
2279             * @param minY the X coordinate of the upper-left pixel included
2280             * in the pass.
2281             * @param periodX the horizontal separation between pixels.
2282             * @param periodY the vertical separation between pixels.
2283             * @param bands an array of <code>int</code>s indicating the
2284             * set of affected bands of the destination.
2285             */
2286            protected void processThumbnailPassStarted(
2287                    BufferedImage theThumbnail, int pass, int minPass,
2288                    int maxPass, int minX, int minY, int periodX, int periodY,
2289                    int[] bands) {
2290                if (updateListeners == null) {
2291                    return;
2292                }
2293                int numListeners = updateListeners.size();
2294                for (int i = 0; i < numListeners; i++) {
2295                    IIOReadUpdateListener listener = (IIOReadUpdateListener) updateListeners
2296                            .get(i);
2297                    listener.thumbnailPassStarted(this , theThumbnail, pass,
2298                            minPass, maxPass, minX, minY, periodX, periodY,
2299                            bands);
2300                }
2301            }
2302
2303            /**
2304             * Broadcasts the update of a set of samples in a thumbnail image
2305             * to all registered <code>IIOReadUpdateListener</code>s by
2306             * calling their <code>thumbnailUpdate</code> method.  Subclasses may
2307             * use this method as a convenience.
2308             *
2309             * @param theThumbnail the <code>BufferedImage</code> thumbnail
2310             * being updated.
2311             * @param minX the X coordinate of the upper-left pixel included
2312             * in the pass.
2313             * @param minY the X coordinate of the upper-left pixel included
2314             * in the pass.
2315             * @param width the total width of the area being updated, including
2316             * pixels being skipped if <code>periodX &gt; 1</code>.
2317             * @param height the total height of the area being updated,
2318             * including pixels being skipped if <code>periodY &gt; 1</code>.
2319             * @param periodX the horizontal separation between pixels.
2320             * @param periodY the vertical separation between pixels.
2321             * @param bands an array of <code>int</code>s indicating the
2322             * set of affected bands of the destination.
2323             */
2324            protected void processThumbnailUpdate(BufferedImage theThumbnail,
2325                    int minX, int minY, int width, int height, int periodX,
2326                    int periodY, int[] bands) {
2327                if (updateListeners == null) {
2328                    return;
2329                }
2330                int numListeners = updateListeners.size();
2331                for (int i = 0; i < numListeners; i++) {
2332                    IIOReadUpdateListener listener = (IIOReadUpdateListener) updateListeners
2333                            .get(i);
2334                    listener.thumbnailUpdate(this , theThumbnail, minX, minY,
2335                            width, height, periodX, periodY, bands);
2336                }
2337            }
2338
2339            /**
2340             * Broadcasts the end of a thumbnail progressive pass to all
2341             * registered <code>IIOReadUpdateListener</code>s by calling their
2342             * <code>thumbnailPassComplete</code> method.  Subclasses may use this
2343             * method as a convenience.
2344             *
2345             * @param theThumbnail the <code>BufferedImage</code> thumbnail
2346             * being updated.
2347             */
2348            protected void processThumbnailPassComplete(
2349                    BufferedImage theThumbnail) {
2350                if (updateListeners == null) {
2351                    return;
2352                }
2353                int numListeners = updateListeners.size();
2354                for (int i = 0; i < numListeners; i++) {
2355                    IIOReadUpdateListener listener = (IIOReadUpdateListener) updateListeners
2356                            .get(i);
2357                    listener.thumbnailPassComplete(this , theThumbnail);
2358                }
2359            }
2360
2361            /**
2362             * Broadcasts a warning message to all registered
2363             * <code>IIOReadWarningListener</code>s by calling their
2364             * <code>warningOccurred</code> method.  Subclasses may use this
2365             * method as a convenience.
2366             *
2367             * @param warning the warning message to send.
2368             *
2369             * @exception IllegalArgumentException if <code>warning</code>
2370             * is <code>null</code>.
2371             */
2372            protected void processWarningOccurred(String warning) {
2373                if (warningListeners == null) {
2374                    return;
2375                }
2376                if (warning == null) {
2377                    throw new IllegalArgumentException("warning == null!");
2378                }
2379                int numListeners = warningListeners.size();
2380                for (int i = 0; i < numListeners; i++) {
2381                    IIOReadWarningListener listener = (IIOReadWarningListener) warningListeners
2382                            .get(i);
2383
2384                    listener.warningOccurred(this , warning);
2385                }
2386            }
2387
2388            /**
2389             * Broadcasts a localized warning message to all registered
2390             * <code>IIOReadWarningListener</code>s by calling their
2391             * <code>warningOccurred</code> method with a string taken
2392             * from a <code>ResourceBundle</code>.  Subclasses may use this
2393             * method as a convenience.
2394             *
2395             * @param baseName the base name of a set of
2396             * <code>ResourceBundle</code>s containing localized warning
2397             * messages.
2398             * @param keyword the keyword used to index the warning message
2399             * within the set of <code>ResourceBundle</code>s.
2400             *
2401             * @exception IllegalArgumentException if <code>baseName</code>
2402             * is <code>null</code>.
2403             * @exception IllegalArgumentException if <code>keyword</code>
2404             * is <code>null</code>.
2405             * @exception IllegalArgumentException if no appropriate
2406             * <code>ResourceBundle</code> may be located.
2407             * @exception IllegalArgumentException if the named resource is
2408             * not found in the located <code>ResourceBundle</code>.
2409             * @exception IllegalArgumentException if the object retrieved
2410             * from the <code>ResourceBundle</code> is not a
2411             * <code>String</code>.
2412             */
2413            protected void processWarningOccurred(String baseName,
2414                    String keyword) {
2415                if (warningListeners == null) {
2416                    return;
2417                }
2418                if (baseName == null) {
2419                    throw new IllegalArgumentException("baseName == null!");
2420                }
2421                if (keyword == null) {
2422                    throw new IllegalArgumentException("keyword == null!");
2423                }
2424                int numListeners = warningListeners.size();
2425                for (int i = 0; i < numListeners; i++) {
2426                    IIOReadWarningListener listener = (IIOReadWarningListener) warningListeners
2427                            .get(i);
2428                    Locale locale = (Locale) warningLocales.get(i);
2429                    if (locale == null) {
2430                        locale = Locale.getDefault();
2431                    }
2432
2433                    /**
2434                     * If an applet supplies an implementation of ImageReader and
2435                     * resource bundles, then the resource bundle will need to be
2436                     * accessed via the applet class loader. So first try the context
2437                     * class loader to locate the resource bundle.
2438                     * If that throws MissingResourceException, then try the
2439                     * system class loader.
2440                     */
2441                    ClassLoader loader = (ClassLoader) java.security.AccessController
2442                            .doPrivileged(new java.security.PrivilegedAction() {
2443                                public Object run() {
2444                                    return Thread.currentThread()
2445                                            .getContextClassLoader();
2446                                }
2447                            });
2448
2449                    ResourceBundle bundle = null;
2450                    try {
2451                        bundle = ResourceBundle.getBundle(baseName, locale,
2452                                loader);
2453                    } catch (MissingResourceException mre) {
2454                        try {
2455                            bundle = ResourceBundle.getBundle(baseName, locale);
2456                        } catch (MissingResourceException mre1) {
2457                            throw new IllegalArgumentException(
2458                                    "Bundle not found!");
2459                        }
2460                    }
2461
2462                    String warning = null;
2463                    try {
2464                        warning = bundle.getString(keyword);
2465                    } catch (ClassCastException cce) {
2466                        throw new IllegalArgumentException(
2467                                "Resource is not a String!");
2468                    } catch (MissingResourceException mre) {
2469                        throw new IllegalArgumentException(
2470                                "Resource is missing!");
2471                    }
2472
2473                    listener.warningOccurred(this , warning);
2474                }
2475            }
2476
2477            // State management
2478
2479            /**
2480             * Restores the <code>ImageReader</code> to its initial state.
2481             *
2482             * <p> The default implementation calls <code>setInput(null,
2483             * false)</code>, <code>setLocale(null)</code>,
2484             * <code>removeAllIIOReadUpdateListeners()</code>,
2485             * <code>removeAllIIOReadWarningListeners()</code>,
2486             * <code>removeAllIIOReadProgressListeners()</code>, and
2487             * <code>clearAbortRequest</code>.
2488             */
2489            public void reset() {
2490                setInput(null, false, false);
2491                setLocale(null);
2492                removeAllIIOReadUpdateListeners();
2493                removeAllIIOReadProgressListeners();
2494                removeAllIIOReadWarningListeners();
2495                clearAbortRequest();
2496            }
2497
2498            /**
2499             * Allows any resources held by this object to be released.  The
2500             * result of calling any other method (other than
2501             * <code>finalize</code>) subsequent to a call to this method
2502             * is undefined.
2503             *
2504             * <p>It is important for applications to call this method when they
2505             * know they will no longer be using this <code>ImageReader</code>.
2506             * Otherwise, the reader may continue to hold on to resources
2507             * indefinitely.
2508             *
2509             * <p>The default implementation of this method in the superclass does
2510             * nothing.  Subclass implementations should ensure that all resources,
2511             * especially native resources, are released.
2512             */
2513            public void dispose() {
2514            }
2515
2516            // Utility methods
2517
2518            /**
2519             * A utility method that may be used by readers to compute the
2520             * region of the source image that should be read, taking into
2521             * account any source region and subsampling offset settings in
2522             * the supplied <code>ImageReadParam</code>.  The actual
2523             * subsampling factors, destination size, and destination offset
2524             * are <em>not</em> taken into consideration, thus further
2525             * clipping must take place.  The {@link #computeRegions
2526             * <code>computeRegions</code>} method performs all necessary
2527             * clipping.
2528             *
2529             * @param param the <code>ImageReadParam</code> being used, or
2530             * <code>null</code>.
2531             * @param srcWidth the width of the source image.
2532             * @param srcHeight the height of the source image.
2533             *
2534             * @return the source region as a <code>Rectangle</code>.
2535             */
2536            protected static Rectangle getSourceRegion(ImageReadParam param,
2537                    int srcWidth, int srcHeight) {
2538                Rectangle sourceRegion = new Rectangle(0, 0, srcWidth,
2539                        srcHeight);
2540                if (param != null) {
2541                    Rectangle region = param.getSourceRegion();
2542                    if (region != null) {
2543                        sourceRegion = sourceRegion.intersection(region);
2544                    }
2545
2546                    int subsampleXOffset = param.getSubsamplingXOffset();
2547                    int subsampleYOffset = param.getSubsamplingYOffset();
2548                    sourceRegion.x += subsampleXOffset;
2549                    sourceRegion.y += subsampleYOffset;
2550                    sourceRegion.width -= subsampleXOffset;
2551                    sourceRegion.height -= subsampleYOffset;
2552                }
2553
2554                return sourceRegion;
2555            }
2556
2557            /**
2558             * Computes the source region of interest and the destination
2559             * region of interest, taking the width and height of the source
2560             * image, an optional destination image, and an optional
2561             * <code>ImageReadParam</code> into account.  The source region
2562             * begins with the entire source image.  Then that is clipped to
2563             * the source region specified in the <code>ImageReadParam</code>,
2564             * if one is specified.
2565             *
2566             * <p> If either of the destination offsets are negative, the
2567             * source region is clipped so that its top left will coincide
2568             * with the top left of the destination image, taking subsampling
2569             * into account.  Then the result is clipped to the destination
2570             * image on the right and bottom, if one is specified, taking
2571             * subsampling and destination offsets into account.
2572             *
2573             * <p> Similarly, the destination region begins with the source
2574             * image, is translated to the destination offset given in the
2575             * <code>ImageReadParam</code> if there is one, and finally is
2576             * clipped to the destination image, if there is one.
2577             *
2578             * <p> If either the source or destination regions end up having a
2579             * width or height of 0, an <code>IllegalArgumentException</code>
2580             * is thrown.
2581             *
2582             * <p> The {@link #getSourceRegion <code>getSourceRegion</code>}
2583             * method may be used if only source clipping is desired.
2584             *
2585             * @param param an <code>ImageReadParam</code>, or <code>null</code>.
2586             * @param srcWidth the width of the source image.
2587             * @param srcHeight the height of the source image.
2588             * @param image a <code>BufferedImage</code> that will be the 
2589             * destination image, or <code>null</code>.
2590             * @param srcRegion a <code>Rectangle</code> that will be filled with
2591             * the source region of interest.
2592             * @param destRegion a <code>Rectangle</code> that will be filled with
2593             * the destination region of interest.
2594             * @exception IllegalArgumentException if <code>srcRegion</code>
2595             * is <code>null</code>.
2596             * @exception IllegalArgumentException if <code>dstRegion</code>
2597             * is <code>null</code>.
2598             * @exception IllegalArgumentException if the resulting source or
2599             * destination region is empty.
2600             */
2601            protected static void computeRegions(ImageReadParam param,
2602                    int srcWidth, int srcHeight, BufferedImage image,
2603                    Rectangle srcRegion, Rectangle destRegion) {
2604                if (srcRegion == null) {
2605                    throw new IllegalArgumentException("srcRegion == null!");
2606                }
2607                if (destRegion == null) {
2608                    throw new IllegalArgumentException("destRegion == null!");
2609                }
2610
2611                // Start with the entire source image
2612                srcRegion.setBounds(0, 0, srcWidth, srcHeight);
2613
2614                // Destination also starts with source image, as that is the
2615                // maximum extent if there is no subsampling
2616                destRegion.setBounds(0, 0, srcWidth, srcHeight);
2617
2618                // Clip that to the param region, if there is one
2619                int periodX = 1;
2620                int periodY = 1;
2621                int gridX = 0;
2622                int gridY = 0;
2623                if (param != null) {
2624                    Rectangle paramSrcRegion = param.getSourceRegion();
2625                    if (paramSrcRegion != null) {
2626                        srcRegion.setBounds(srcRegion
2627                                .intersection(paramSrcRegion));
2628                    }
2629                    periodX = param.getSourceXSubsampling();
2630                    periodY = param.getSourceYSubsampling();
2631                    gridX = param.getSubsamplingXOffset();
2632                    gridY = param.getSubsamplingYOffset();
2633                    srcRegion.translate(gridX, gridY);
2634                    srcRegion.width -= gridX;
2635                    srcRegion.height -= gridY;
2636                    destRegion.setLocation(param.getDestinationOffset());
2637                }
2638
2639                // Now clip any negative destination offsets, i.e. clip
2640                // to the top and left of the destination image
2641                if (destRegion.x < 0) {
2642                    int delta = -destRegion.x * periodX;
2643                    srcRegion.x += delta;
2644                    srcRegion.width -= delta;
2645                    destRegion.x = 0;
2646                }
2647                if (destRegion.y < 0) {
2648                    int delta = -destRegion.y * periodY;
2649                    srcRegion.y += delta;
2650                    srcRegion.height -= delta;
2651                    destRegion.y = 0;
2652                }
2653
2654                // Now clip the destination Region to the subsampled width and height
2655                int subsampledWidth = (srcRegion.width + periodX - 1) / periodX;
2656                int subsampledHeight = (srcRegion.height + periodY - 1)
2657                        / periodY;
2658                destRegion.width = subsampledWidth;
2659                destRegion.height = subsampledHeight;
2660
2661                // Now clip that to right and bottom of the destination image,
2662                // if there is one, taking subsampling into account
2663                if (image != null) {
2664                    Rectangle destImageRect = new Rectangle(0, 0, image
2665                            .getWidth(), image.getHeight());
2666                    destRegion
2667                            .setBounds(destRegion.intersection(destImageRect));
2668                    if (destRegion.isEmpty()) {
2669                        throw new IllegalArgumentException(
2670                                "Empty destination region!");
2671                    }
2672
2673                    int deltaX = destRegion.x + subsampledWidth
2674                            - image.getWidth();
2675                    if (deltaX > 0) {
2676                        srcRegion.width -= deltaX * periodX;
2677                    }
2678                    int deltaY = destRegion.y + subsampledHeight
2679                            - image.getHeight();
2680                    if (deltaY > 0) {
2681                        srcRegion.height -= deltaY * periodY;
2682                    }
2683                }
2684                if (srcRegion.isEmpty() || destRegion.isEmpty()) {
2685                    throw new IllegalArgumentException("Empty region!");
2686                }
2687            }
2688
2689            /**
2690             * A utility method that may be used by readers to test the
2691             * validity of the source and destination band settings of an
2692             * <code>ImageReadParam</code>.  This method may be called as soon
2693             * as the reader knows both the number of bands of the source
2694             * image as it exists in the input stream, and the number of bands
2695             * of the destination image that being written.
2696             *
2697             * <p> The method retrieves the source and destination band
2698             * setting arrays from param using the <code>getSourceBands</code>
2699             * and <code>getDestinationBands</code>methods (or considers them
2700             * to be <code>null</code> if <code>param</code> is
2701             * <code>null</code>).  If the source band setting array is
2702             * <code>null</code>, it is considered to be equal to the array
2703             * <code>{ 0, 1, ..., numSrcBands - 1 }</code>, and similarly for
2704             * the destination band setting array.
2705             *
2706             * <p> The method then tests that both arrays are equal in length,
2707             * and that neither array contains a value larger than the largest
2708             * available band index.
2709             *
2710             * <p> Any failure results in an
2711             * <code>IllegalArgumentException</code> being thrown; success
2712             * results in the method returning silently.
2713             *
2714             * @param param the <code>ImageReadParam</code> being used to read
2715             * the image.
2716             * @param numSrcBands the number of bands of the image as it exists
2717             * int the input source.
2718             * @param numDstBands the number of bands in the destination image
2719             * being written.
2720             *
2721             * @exception IllegalArgumentException if <code>param</code>
2722             * contains an invalid specification of a source and/or
2723             * destination band subset.
2724             */
2725            protected static void checkReadParamBandSettings(
2726                    ImageReadParam param, int numSrcBands, int numDstBands) {
2727                // A null param is equivalent to srcBands == dstBands == null.
2728                int[] srcBands = null;
2729                int[] dstBands = null;
2730                if (param != null) {
2731                    srcBands = param.getSourceBands();
2732                    dstBands = param.getDestinationBands();
2733                }
2734
2735                int paramSrcBandLength = (srcBands == null) ? numSrcBands
2736                        : srcBands.length;
2737                int paramDstBandLength = (dstBands == null) ? numDstBands
2738                        : dstBands.length;
2739
2740                if (paramSrcBandLength != paramDstBandLength) {
2741                    throw new IllegalArgumentException(
2742                            "ImageReadParam num source & dest bands differ!");
2743                }
2744
2745                if (srcBands != null) {
2746                    for (int i = 0; i < srcBands.length; i++) {
2747                        if (srcBands[i] >= numSrcBands) {
2748                            throw new IllegalArgumentException(
2749                                    "ImageReadParam source bands contains a value >= the number of source bands!");
2750                        }
2751                    }
2752                }
2753
2754                if (dstBands != null) {
2755                    for (int i = 0; i < dstBands.length; i++) {
2756                        if (dstBands[i] >= numDstBands) {
2757                            throw new IllegalArgumentException(
2758                                    "ImageReadParam dest bands contains a value >= the number of dest bands!");
2759                        }
2760                    }
2761                }
2762            }
2763
2764            /**
2765             * Returns the <code>BufferedImage</code> to which decoded pixel
2766             * data should be written.  The image is determined by inspecting
2767             * the supplied <code>ImageReadParam</code> if it is
2768             * non-<code>null</code>; if its <code>getDestination</code>
2769             * method returns a non-<code>null</code> value, that image is
2770             * simply returned.  Otherwise,
2771             * <code>param.getDestinationType</code> method is called to
2772             * determine if a particular image type has been specified.  If
2773             * so, the returned <code>ImageTypeSpecifier</code> is used after
2774             * checking that it is equal to one of those included in
2775             * <code>imageTypes</code>.
2776             *
2777             * <p> If <code>param</code> is <code>null</code> or the above
2778             * steps have not yielded an image or an
2779             * <code>ImageTypeSpecifier</code>, the first value obtained from
2780             * the <code>imageTypes</code> parameter is used.  Typically, the
2781             * caller will set <code>imageTypes</code> to the value of
2782             * <code>getImageTypes(imageIndex)</code>.
2783             *
2784             * <p> Next, the dimensions of the image are determined by a call
2785             * to <code>computeRegions</code>.  The actual width and height of
2786             * the image being decoded are passed in as the <code>width</code>
2787             * and <code>height</code> parameters.
2788             *
2789             * @param param an <code>ImageReadParam</code> to be used to get
2790             * the destination image or image type, or <code>null</code>.
2791             * @param imageTypes an <code>Iterator</code> of
2792             * <code>ImageTypeSpecifier</code>s indicating the legal image
2793             * types, with the default first.
2794             * @param width the true width of the image or tile begin decoded.
2795             * @param height the true width of the image or tile being decoded.
2796             *
2797             * @return the <code>BufferedImage</code> to which decoded pixel
2798             * data should be written.
2799             *
2800             * @exception IIOException if the <code>ImageTypeSpecifier</code>
2801             * specified by <code>param</code> does not match any of the legal
2802             * ones from <code>imageTypes</code>.
2803             * @exception IllegalArgumentException if <code>imageTypes</code>
2804             * is <code>null</code> or empty, or if an object not of type
2805             * <code>ImageTypeSpecifier</code> is retrieved from it.
2806             * @exception IllegalArgumentException if the resulting image would
2807             * have a width or height less than 1.
2808             * @exception IllegalArgumentException if the product of
2809             * <code>width</code> and <code>height</code> is greater than
2810             * <code>Integer.MAX_VALUE</code>.
2811             */
2812            protected static BufferedImage getDestination(ImageReadParam param,
2813                    Iterator<ImageTypeSpecifier> imageTypes, int width,
2814                    int height) throws IIOException {
2815                if (imageTypes == null || !imageTypes.hasNext()) {
2816                    throw new IllegalArgumentException(
2817                            "imageTypes null or empty!");
2818                }
2819                if ((long) width * height > Integer.MAX_VALUE) {
2820                    throw new IllegalArgumentException(
2821                            "width*height > Integer.MAX_VALUE!");
2822                }
2823
2824                BufferedImage dest = null;
2825                ImageTypeSpecifier imageType = null;
2826
2827                // If param is non-null, use it
2828                if (param != null) {
2829                    // Try to get the image itself
2830                    dest = param.getDestination();
2831                    if (dest != null) {
2832                        return dest;
2833                    }
2834
2835                    // No image, get the image type
2836                    imageType = param.getDestinationType();
2837                }
2838
2839                // No info from param, use fallback image type
2840                if (imageType == null) {
2841                    Object o = imageTypes.next();
2842                    if (!(o instanceof  ImageTypeSpecifier)) {
2843                        throw new IllegalArgumentException(
2844                                "Non-ImageTypeSpecifier retrieved from imageTypes!");
2845                    }
2846                    imageType = (ImageTypeSpecifier) o;
2847                } else {
2848                    boolean foundIt = false;
2849                    while (imageTypes.hasNext()) {
2850                        ImageTypeSpecifier type = (ImageTypeSpecifier) imageTypes
2851                                .next();
2852                        if (type.equals(imageType)) {
2853                            foundIt = true;
2854                            break;
2855                        }
2856                    }
2857
2858                    if (!foundIt) {
2859                        throw new IIOException(
2860                                "Destination type from ImageReadParam does not match!");
2861                    }
2862                }
2863
2864                Rectangle srcRegion = new Rectangle(0, 0, 0, 0);
2865                Rectangle destRegion = new Rectangle(0, 0, 0, 0);
2866                computeRegions(param, width, height, null, srcRegion,
2867                        destRegion);
2868
2869                int destWidth = destRegion.x + destRegion.width;
2870                int destHeight = destRegion.y + destRegion.height;
2871                // Create a new image based on the type specifier
2872                return imageType.createBufferedImage(destWidth, destHeight);
2873            }
2874        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.