/*
 * Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.imageio;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.event.IIOReadWarningListener;
import javax.imageio.event.IIOReadProgressListener;
import javax.imageio.event.IIOReadUpdateListener;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.stream.ImageInputStream;

/**
 * An abstract superclass for parsing and decoding of images.  This
 * class must be subclassed by classes that read in images in the
 * context of the Java Image I/O framework.
 *
 * <p> <code>ImageReader</code> objects are normally instantiated by
 * the service provider interface (SPI) class for the specific format.
 * Service provider classes (e.g., instances of
 * <code>ImageReaderSpi</code>) are registered with the
 * <code>IIORegistry</code>, which uses them for format recognition
 * and presentation of available format readers and writers.
 *
 * <p> When an input source is set (using the <code>setInput</code>
 * method), it may be marked as "seek forward only".  This setting
 * means that images contained within the input source will only be
 * read in order, possibly allowing the reader to avoid caching
 * portions of the input containing data associated with images that
 * have been read previously.
 *
 * @see ImageWriter
 * @see javax.imageio.spi.IIORegistry
 * @see javax.imageio.spi.ImageReaderSpi
 *
 */
public abstract class ImageReader {

    /**
     * The <code>ImageReaderSpi</code> that instantiated this object,
     * or <code>null</code> if its identity is not known or none
     * exists.  By default it is initialized to <code>null</code>.
     */
    protected ImageReaderSpi originatingProvider;

    /**
     * The <code>ImageInputStream</code> or other
     * <code>Object</code> by <code>setInput</code> and retrieved
     * by <code>getInput</code>.  By default it is initialized to
     * <code>null</code>.
     */
    protected Object input = null;

    /**
     * <code>true</code> if the current input source has been marked
     * as allowing only forward seeking by <code>setInput</code>.  By
     * default, the value is <code>false</code>.
     *
     * @see #minIndex
     * @see #setInput
     */
    protected boolean seekForwardOnly = false;

    /**
     * <code>true</code> if the current input source has been marked
     * as allowing metadata to be ignored by <code>setInput</code>.
     * By default, the value is <code>false</code>.
     *
     * @see #setInput
     */
    protected boolean ignoreMetadata = false;

    /**
     * The smallest valid index for reading, initially 0.  When
     * <code>seekForwardOnly</code> is <code>true</code>, various methods
     * may throw an <code>IndexOutOfBoundsException</code> on an
     * attempt to access data associate with an image having a lower
     * index.
     *
     * @see #seekForwardOnly
     * @see #setInput
     */
    protected int minIndex = 0;

    /**
     * An array of <code>Locale</code>s which may be used to localize
     * warning messages, or <code>null</code> if localization is not
     * supported.
     */
    protected Locale[] availableLocales = null;

    /**
     * The current <code>Locale</code> to be used for localization, or
     * <code>null</code> if none has been set.
     */
    protected Locale locale = null;

    /**
     * A <code>List</code> of currently registered
     * <code>IIOReadWarningListener</code>s, initialized by default to
     * <code>null</code>, which is synonymous with an empty
     * <code>List</code>.
     */
    protected List<IIOReadWarningListener> warningListeners = null;

    /**
     * A <code>List</code> of the <code>Locale</code>s associated with
     * each currently registered <code>IIOReadWarningListener</code>,
     * initialized by default to <code>null</code>, which is
     * synonymous with an empty <code>List</code>.
     */
    protected List<Locale> warningLocales = null;

    /**
     * A <code>List</code> of currently registered
     * <code>IIOReadProgressListener</code>s, initialized by default
     * to <code>null</code>, which is synonymous with an empty
     * <code>List</code>.
     */
    protected List<IIOReadProgressListener> progressListeners = null;

    /**
     * A <code>List</code> of currently registered
     * <code>IIOReadUpdateListener</code>s, initialized by default to
     * <code>null</code>, which is synonymous with an empty
     * <code>List</code>.
     */
    protected List<IIOReadUpdateListener> updateListeners = null;

    /**
     * If <code>true</code>, the current read operation should be
     * aborted.
     */
    private boolean abortFlag = false;

    /**
     * Constructs an <code>ImageReader</code> and sets its
     * <code>originatingProvider</code> field to the supplied value.
     *
     * <p> Subclasses that make use of extensions should provide a
     * constructor with signature <code>(ImageReaderSpi,
     * Object)</code> in order to retrieve the extension object.  If
     * the extension object is unsuitable, an
     * <code>IllegalArgumentException</code> should be thrown.
     *
     * @param originatingProvider the <code>ImageReaderSpi</code> that is
     * invoking this constructor, or <code>null</code>.
     */
    protected ImageReader(ImageReaderSpi originatingProvider) {
        this.originatingProvider = originatingProvider;
    }

    /**
     * Returns a <code>String</code> identifying the format of the
     * input source.
     *
     * <p> The default implementation returns
     * <code>originatingProvider.getFormatNames()[0]</code>.
     * Implementations that may not have an originating service
     * provider, or which desire a different naming policy should
     * override this method.
     *
     * @exception IOException if an error occurs reading the
     * information from the input source.
     *
     * @return the format name, as a <code>String</code>.
     */
    public String getFormatName() throws IOException {
        return originatingProvider.getFormatNames()[0];
    }

    /**
     * Returns the <code>ImageReaderSpi</code> that was passed in on
     * the constructor.  Note that this value may be <code>null</code>.
     *
     * @return an <code>ImageReaderSpi</code>, or <code>null</code>.
     *
     * @see ImageReaderSpi
     */
    public ImageReaderSpi getOriginatingProvider() {
        return originatingProvider;
    }

    /**
     * Sets the input source to use to the given
     * <code>ImageInputStream</code> or other <code>Object</code>.
     * The input source must be set before any of the query or read
     * methods are used.  If <code>input</code> is <code>null</code>,
     * any currently set input source will be removed.  In any case,
     * the value of <code>minIndex</code> will be initialized to 0.
     *
     * <p> The <code>seekForwardOnly</code> parameter controls whether
     * the value returned by <code>getMinIndex</code> will be
     * increased as each image (or thumbnail, or image metadata) is
     * read.  If <code>seekForwardOnly</code> is true, then a call to
     * <code>read(index)</code> will throw an
     * <code>IndexOutOfBoundsException</code> if <code>index &lt
     * this.minIndex</code>; otherwise, the value of
     * <code>minIndex</code> will be set to <code>index</code>.  If
     * <code>seekForwardOnly</code> is <code>false</code>, the value of
     * <code>minIndex</code> will remain 0 regardless of any read
     * operations.
     *
     * <p> The <code>ignoreMetadata</code> parameter, if set to
     * <code>true</code>, allows the reader to disregard any metadata
     * encountered during the read.  Subsequent calls to the
     * <code>getStreamMetadata</code> and
     * <code>getImageMetadata</code> methods may return
     * <code>null</code>, and an <code>IIOImage</code> returned from
     * <code>readAll</code> may return <code>null</code> from their
     * <code>getMetadata</code> method.  Setting this parameter may
     * allow the reader to work more efficiently.  The reader may
     * choose to disregard this setting and return metadata normally.
     *
     * <p> Subclasses should take care to remove any cached
     * information based on the previous stream, such as header
     * information or partially decoded image data.
     *
     * <p> Use of a general <code>Object</code> other than an
     * <code>ImageInputStream</code> is intended for readers that
     * interact directly with a capture device or imaging protocol.
     * The set of legal classes is advertised by the reader's service
     * provider's <code>getInputTypes</code> method; most readers
     * will return a single-element array containing only
     * <code>ImageInputStream.class</code> to indicate that they
     * accept only an <code>ImageInputStream</code>.
     *
     * <p> The default implementation checks the <code>input</code>
     * argument against the list returned by
     * <code>originatingProvider.getInputTypes()</code> and fails
     * if the argument is not an instance of one of the classes
     * in the list.  If the originating provider is set to
     * <code>null</code>, the input is accepted only if it is an
     * <code>ImageInputStream</code>.
     *
     * @param input the <code>ImageInputStream</code> or other
     * <code>Object</code> to use for future decoding.
     * @param seekForwardOnly if <code>true</code>, images and metadata
     * may only be read in ascending order from this input source.
     * @param ignoreMetadata if <code>true</code>, metadata
     * may be ignored during reads.
     *
     * @exception IllegalArgumentException if <code>input</code> is
     * not an instance of one of the classes returned by the
     * originating service provider's <code>getInputTypes</code>
     * method, or is not an <code>ImageInputStream</code>.
     *
     * @see ImageInputStream
     * @see #getInput
     * @see javax.imageio.spi.ImageReaderSpi#getInputTypes
     */
    public void setInput(Object input,
                         boolean seekForwardOnly,
                         boolean ignoreMetadata) {
        if (input != null) {
            boolean found = false;
            if (originatingProvider != null) {
                Class[] classes = originatingProvider.getInputTypes();
                for (int i = 0; i < classes.length; i++) {
                    if (classes[i].isInstance(input)) {
                        found = true;
                        break;
                    }
                }
            } else {
                if (input instanceof ImageInputStream) {
                    found = true;
                }
            }
            if (!found) {
                throw new IllegalArgumentException("Incorrect input type!");
            }

            this.seekForwardOnly = seekForwardOnly;
            this.ignoreMetadata = ignoreMetadata;
            this.minIndex = 0;
        }

        this.input = input;
    }

    /**
     * Sets the input source to use to the given
     * <code>ImageInputStream</code> or other <code>Object</code>.
     * The input source must be set before any of the query or read
     * methods are used.  If <code>input</code> is <code>null</code>,
     * any currently set input source will be removed.  In any case,
     * the value of <code>minIndex</code> will be initialized to 0.
     *
     * <p> The <code>seekForwardOnly</code> parameter controls whether
     * the value returned by <code>getMinIndex</code> will be
     * increased as each image (or thumbnail, or image metadata) is
     * read.  If <code>seekForwardOnly</code> is true, then a call to
     * <code>read(index)</code> will throw an
     * <code>IndexOutOfBoundsException</code> if <code>index &lt
     * this.minIndex</code>; otherwise, the value of
     * <code>minIndex</code> will be set to <code>index</code>.  If
     * <code>seekForwardOnly</code> is <code>false</code>, the value of
     * <code>minIndex</code> will remain 0 regardless of any read
     * operations.
     *
     * <p> This method is equivalent to <code>setInput(input,
     * seekForwardOnly, false)</code>.
     *
     * @param input the <code>ImageInputStream</code> or other
     * <code>Object</code> to use for future decoding.
     * @param seekForwardOnly if <code>true</code>, images and metadata
     * may only be read in ascending order from this input source.
     *
     * @exception IllegalArgumentException if <code>input</code> is
     * not an instance of one of the classes returned by the
     * originating service provider's <code>getInputTypes</code>
     * method, or is not an <code>ImageInputStream</code>.
     *
     * @see #getInput
     */
    public void setInput(Object input,
                         boolean seekForwardOnly) {
        setInput(input, seekForwardOnly, false);
    }

    /**
     * Sets the input source to use to the given
     * <code>ImageInputStream</code> or other <code>Object</code>.
     * The input source must be set before any of the query or read
     * methods are used.  If <code>input</code> is <code>null</code>,
     * any currently set input source will be removed.  In any case,
     * the value of <code>minIndex</code> will be initialized to 0.
     *
     * <p> This method is equivalent to <code>setInput(input, false,
     * false)</code>.
     *
     * @param input the <code>ImageInputStream</code> or other
     * <code>Object</code> to use for future decoding.
     *
     * @exception IllegalArgumentException if <code>input</code> is
     * not an instance of one of the classes returned by the
     * originating service provider's <code>getInputTypes</code>
     * method, or is not an <code>ImageInputStream</code>.
     *
     * @see #getInput
     */
    public void setInput(Object input) {
        setInput(input, false, false);
    }

    /**
     * Returns the <code>ImageInputStream</code> or other
     * <code>Object</code> previously set as the input source.  If the
     * input source has not been set, <code>null</code> is returned.
     *
     * @return the <code>Object</code> that will be used for future
     * decoding, or <code>null</code>.
     *
     * @see ImageInputStream
     * @see #setInput
     */
    public Object getInput() {
        return input;
    }

    /**
     * Returns <code>true</code> if the current input source has been
     * marked as seek forward only by passing <code>true</code> as the
     * <code>seekForwardOnly</code> argument to the
     * <code>setInput</code> method.
     *
     * @return <code>true</code> if the input source is seek forward
     * only.
     *
     * @see #setInput
     */
    public boolean isSeekForwardOnly() {
        return seekForwardOnly;
    }

    /**
     * Returns <code>true</code> if the current input source has been
     * marked as allowing metadata to be ignored by passing
     * <code>true</code> as the <code>ignoreMetadata</code> argument
     * to the <code>setInput</code> method.
     *
     * @return <code>true</code> if the metadata may be ignored.
     *
     * @see #setInput
     */
    public boolean isIgnoringMetadata() {
        return ignoreMetadata;
    }

    /**
     * Returns the lowest valid index for reading an image, thumbnail,
     * or image metadata.  If <code>seekForwardOnly()</code> is
     * <code>false</code>, this value will typically remain 0,
     * indicating that random access is possible.  Otherwise, it will
     * contain the value of the most recently accessed index, and
     * increase in a monotonic fashion.
     *
     * @return the minimum legal index for reading.
     */
    public int getMinIndex() {
        return minIndex;
    }

    // Localization

    /**
     * Returns an array of <code>Locale</code>s that may be used to
     * localize warning listeners and compression settings.  A return
     * value of <code>null</code> indicates that localization is not
     * supported.
     *
     * <p> The default implementation returns a clone of the
     * <code>availableLocales</code> instance variable if it is
     * non-<code>null</code>, or else returns <code>null</code>.
     *
     * @return an array of <code>Locale</code>s that may be used as
     * arguments to <code>setLocale</code>, or <code>null</code>.
     */
    public Locale[] getAvailableLocales() {
        if (availableLocales == null) {
            return null;
        } else {
            return (Locale[])availableLocales.clone();
        }
    }

    /**
     * Sets the current <code>Locale</code> of this
     * <code>ImageReader</code> to the given value.  A value of
     * <code>null</code> removes any previous setting, and indicates
     * that the reader should localize as it sees fit.
     *
     * @param locale the desired <code>Locale</code>, or
     * <code>null</code>.
     *
     * @exception IllegalArgumentException if <code>locale</code> is
     * non-<code>null</code> but is not one of the values returned by
     * <code>getAvailableLocales</code>.
     *
     * @see #getLocale
     */
    public void setLocale(Locale locale) {
        if (locale != null) {
            Locale[] locales = getAvailableLocales();
            boolean found = false;
            if (locales != null) {
                for (int i = 0; i < locales.length; i++) {
                    if (locale.equals(locales[i])) {
                        found = true;
                        break;
                    }
                }
            }
            if (!found) {
                throw new IllegalArgumentException("Invalid locale!");
            }
        }
        this.locale = locale;
    }

    /**
     * Returns the currently set <code>Locale</code>, or
     * <code>null</code> if none has been set.
     *
     * @return the current <code>Locale</code>, or <code>null</code>.
     *
     * @see #setLocale
     */
    public Locale getLocale() {
        return locale;
    }

    // Image queries

    /**
     * Returns the number of images, not including thumbnails, available
     * from the current input source.
     *
     * <p> Note that some image formats (such as animated GIF) do not
     * specify how many images are present in the stream.  Thus
     * determining the number of images will require the entire stream
     * to be scanned and may require memory for buffering.  If images
     * are to be processed in order, it may be more efficient to
     * simply call <code>read</code> with increasing indices until an
     * <code>IndexOutOfBoundsException</code> is thrown to indicate
     * that no more images are available.  The
     * <code>allowSearch</code> parameter may be set to
     * <code>false</code> to indicate that an exhaustive search is not
     * desired; the return value will be <code>-1</code> to indicate
     * that a search is necessary.  If the input has been specified
     * with <code>seekForwardOnly</code> set to <code>true</code>,
     * this method throws an <code>IllegalStateException</code> if
     * <code>allowSearch</code> is set to <code>true</code>.
     *
     * @param allowSearch if <code>true</code>, the true number of
     * images will be returned even if a search is required.  If
     * <code>false</code>, the reader may return <code>-1</code>
     * without performing the search.
     *
     * @return the number of images, as an <code>int</code>, or
     * <code>-1</code> if <code>allowSearch</code> is
     * <code>false</code> and a search would be required.
     *
     * @exception IllegalStateException if the input source has not been set,
     * or if the input has been specified with <code>seekForwardOnly</code>
     * set to <code>true</code>.
     * @exception IOException if an error occurs reading the
     * information from the input source.
     *
     * @see #setInput
     */
    public abstract int getNumImages(boolean allowSearch) throws IOException;

    /**
     * Returns the width in pixels of the given image within the input
     * source.
     *
     * <p> If the image can be rendered to a user-specified size, then
     * this method returns the default width.
     *
     * @param imageIndex the index of the image to be queried.
     *
     * @return the width of the image, as an <code>int</code>.
     *
     * @exception IllegalStateException if the input source has not been set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IOException if an error occurs reading the width
     * information from the input source.
     */
    public abstract int getWidth(int imageIndex) throws IOException;

    /**
     * Returns the height in pixels of the given image within the
     * input source.
     *
     * <p> If the image can be rendered to a user-specified size, then
     * this method returns the default height.
     *
     * @param imageIndex the index of the image to be queried.
     *
     * @return the height of the image, as an <code>int</code>.
     *
     * @exception IllegalStateException if the input source has not been set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IOException if an error occurs reading the height
     * information from the input source.
     */
    public abstract int getHeight(int imageIndex) throws IOException;

    /**
     * Returns <code>true</code> if the storage format of the given
     * image places no inherent impediment on random access to pixels.
     * For most compressed formats, such as JPEG, this method should
     * return <code>false</code>, as a large section of the image in
     * addition to the region of interest may need to be decoded.
     *
     * <p> This is merely a hint for programs that wish to be
     * efficient; all readers must be able to read arbitrary regions
     * as specified in an <code>ImageReadParam</code>.
     *
     * <p> Note that formats that return <code>false</code> from
     * this method may nonetheless allow tiling (<i>e.g.</i> Restart
     * Markers in JPEG), and random access will likely be reasonably
     * efficient on tiles.  See {@link #isImageTiled
     * <code>isImageTiled</code>}.
     *
     * <p> A reader for which all images are guaranteed to support
     * easy random access, or are guaranteed not to support easy
     * random access, may return <code>true</code> or
     * <code>false</code> respectively without accessing any image
     * data.  In such cases, it is not necessary to throw an exception
     * even if no input source has been set or the image index is out
     * of bounds.
     *
     * <p> The default implementation returns <code>false</code>.
     *
     * @param imageIndex the index of the image to be queried.
     *
     * @return <code>true</code> if reading a region of interest of
     * the given image is likely to be efficient.
     *
     * @exception IllegalStateException if an input source is required
     * to determine the return value, but none has been set.
     * @exception IndexOutOfBoundsException if an image must be
     * accessed to determine the return value, but the supplied index
     * is out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public boolean isRandomAccessEasy(int imageIndex) throws IOException {
        return false;
    }

    /**
     * Returns the aspect ratio of the given image (that is, its width
     * divided by its height) as a <code>float</code>.  For images
     * that are inherently resizable, this method provides a way to
     * determine the appropriate width given a deired height, or vice
     * versa.  For non-resizable images, the true width and height
     * are used.
     *
     * <p> The default implementation simply returns
     * <code>(float)getWidth(imageIndex)/getHeight(imageIndex)</code>.
     *
     * @param imageIndex the index of the image to be queried.
     *
     * @return a <code>float</code> indicating the aspect ratio of the
     * given image.
     *
     * @exception IllegalStateException if the input source has not been set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public float getAspectRatio(int imageIndex) throws IOException {
        return (float)getWidth(imageIndex)/getHeight(imageIndex);
    }

    /**
     * Returns an <code>ImageTypeSpecifier</code> indicating the
     * <code>SampleModel</code> and <code>ColorModel</code> which most
     * closely represents the "raw" internal format of the image.  For
     * example, for a JPEG image the raw type might have a YCbCr color
     * space even though the image would conventionally be transformed
     * into an RGB color space prior to display.  The returned value
     * should also be included in the list of values returned by
     * <code>getImageTypes</code>.
     *
     * <p> The default implementation simply returns the first entry
     * from the list provided by <code>getImageType</code>.
     *
     * @param imageIndex the index of the image to be queried.
     *
     * @return an <code>ImageTypeSpecifier</code>.
     *
     * @exception IllegalStateException if the input source has not been set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IOException if an error occurs reading the format
     * information from the input source.
     */
    public ImageTypeSpecifier getRawImageType(int imageIndex)
        throws IOException {
        return (ImageTypeSpecifier)getImageTypes(imageIndex).next();
    }

    /**
     * Returns an <code>Iterator</code> containing possible image
     * types to which the given image may be decoded, in the form of
     * <code>ImageTypeSpecifiers</code>s.  At least one legal image
     * type will be returned.
     *
     * <p> The first element of the iterator should be the most
     * "natural" type for decoding the image with as little loss as
     * possible.  For example, for a JPEG image the first entry should
     * be an RGB image, even though the image data is stored
     * internally in a YCbCr color space.
     *
     * @param imageIndex the index of the image to be
     * <code>retrieved</code>.
     *
     * @return an <code>Iterator</code> containing at least one
     * <code>ImageTypeSpecifier</code> representing suggested image
     * types for decoding the current given image.
     *
     * @exception IllegalStateException if the input source has not been set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IOException if an error occurs reading the format
     * information from the input source.
     *
     * @see ImageReadParam#setDestination(BufferedImage)
     * @see ImageReadParam#setDestinationType(ImageTypeSpecifier)
     */
    public abstract Iterator<ImageTypeSpecifier>
        getImageTypes(int imageIndex) throws IOException;

    /**
     * Returns a default <code>ImageReadParam</code> object
     * appropriate for this format.  All subclasses should define a
     * set of default values for all parameters and return them with
     * this call.  This method may be called before the input source
     * is set.
     *
     * <p> The default implementation constructs and returns a new
     * <code>ImageReadParam</code> object that does not allow source
     * scaling (<i>i.e.</i>, it returns <code>new
     * ImageReadParam()</code>.
     *
     * @return an <code>ImageReadParam</code> object which may be used
     * to control the decoding process using a set of default settings.
     */
    public ImageReadParam getDefaultReadParam() {
        return new ImageReadParam();
    }

    /**
     * Returns an <code>IIOMetadata</code> object representing the
     * metadata associated with the input source as a whole (i.e., not
     * associated with any particular image), or <code>null</code> if
     * the reader does not support reading metadata, is set to ignore
     * metadata, or if no metadata is available.
     *
     * @return an <code>IIOMetadata</code> object, or <code>null</code>.
     *
     * @exception IOException if an error occurs during reading.
     */
    public abstract IIOMetadata getStreamMetadata() throws IOException;

    /**
     * Returns an <code>IIOMetadata</code> object representing the
     * metadata associated with the input source as a whole (i.e.,
     * not associated with any particular image).  If no such data
     * exists, <code>null</code> is returned.
     *
     * <p> The resuting metadata object is only responsible for
     * returning documents in the format named by
     * <code>formatName</code>.  Within any documents that are
     * returned, only nodes whose names are members of
     * <code>nodeNames</code> are required to be returned.  In this
     * way, the amount of metadata processing done by the reader may
     * be kept to a minimum, based on what information is actually
     * needed.
     *
     * <p> If <code>formatName</code> is not the name of a supported
     * metadata format, <code>null</code> is returned.
     *
     * <p> In all cases, it is legal to return a more capable metadata
     * object than strictly necessary.  The format name and node names
     * are merely hints that may be used to reduce the reader's
     * workload.
     *
     * <p> The default implementation simply returns the result of
     * calling <code>getStreamMetadata()</code>, after checking that
     * the format name is supported.  If it is not,
     * <code>null</code> is returned.
     *
     * @param formatName a metadata format name that may be used to retrieve
     * a document from the returned <code>IIOMetadata</code> object.
     * @param nodeNames a <code>Set</code> containing the names of
     * nodes that may be contained in a retrieved document.
     *
     * @return an <code>IIOMetadata</code> object, or <code>null</code>.
     *
     * @exception IllegalArgumentException if <code>formatName</code>
     * is <code>null</code>.
     * @exception IllegalArgumentException if <code>nodeNames</code>
     * is <code>null</code>.
     * @exception IOException if an error occurs during reading.
     */
    public IIOMetadata getStreamMetadata(String formatName,
                                         Set<String> nodeNames)
        throws IOException
    {
        return getMetadata(formatName, nodeNames, true, 0);
    }

    private IIOMetadata getMetadata(String formatName,
                                    Set nodeNames,
                                    boolean wantStream,
                                    int imageIndex) throws IOException {
        if (formatName == null) {
            throw new IllegalArgumentException("formatName == null!");
        }
        if (nodeNames == null) {
            throw new IllegalArgumentException("nodeNames == null!");
        }
        IIOMetadata metadata =
            wantStream
            ? getStreamMetadata()
            : getImageMetadata(imageIndex);
        if (metadata != null) {
            if (metadata.isStandardMetadataFormatSupported() &&
                formatName.equals
                (IIOMetadataFormatImpl.standardMetadataFormatName)) {
                return metadata;
            }
            String nativeName = metadata.getNativeMetadataFormatName();
            if (nativeName != null && formatName.equals(nativeName)) {
                return metadata;
            }
            String[] extraNames = metadata.getExtraMetadataFormatNames();
            if (extraNames != null) {
                for (int i = 0; i < extraNames.length; i++) {
                    if (formatName.equals(extraNames[i])) {
                        return metadata;
                    }
                }
            }
        }
        return null;
    }

    /**
     * Returns an <code>IIOMetadata</code> object containing metadata
     * associated with the given image, or <code>null</code> if the
     * reader does not support reading metadata, is set to ignore
     * metadata, or if no metadata is available.
     *
     * @param imageIndex the index of the image whose metadata is to
     * be retrieved.
     *
     * @return an <code>IIOMetadata</code> object, or
     * <code>null</code>.
     *
     * @exception IllegalStateException if the input source has not been
     * set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public abstract IIOMetadata getImageMetadata(int imageIndex)
        throws IOException;

    /**
     * Returns an <code>IIOMetadata</code> object representing the
     * metadata associated with the given image, or <code>null</code>
     * if the reader does not support reading metadata or none
     * is available.
     *
     * <p> The resuting metadata object is only responsible for
     * returning documents in the format named by
     * <code>formatName</code>.  Within any documents that are
     * returned, only nodes whose names are members of
     * <code>nodeNames</code> are required to be returned.  In this
     * way, the amount of metadata processing done by the reader may
     * be kept to a minimum, based on what information is actually
     * needed.
     *
     * <p> If <code>formatName</code> is not the name of a supported
     * metadata format, <code>null</code> may be returned.
     *
     * <p> In all cases, it is legal to return a more capable metadata
     * object than strictly necessary.  The format name and node names
     * are merely hints that may be used to reduce the reader's
     * workload.
     *
     * <p> The default implementation simply returns the result of
     * calling <code>getImageMetadata(imageIndex)</code>, after
     * checking that the format name is supported.  If it is not,
     * <code>null</code> is returned.
     *
     * @param imageIndex the index of the image whose metadata is to
     * be retrieved.
     * @param formatName a metadata format name that may be used to retrieve
     * a document from the returned <code>IIOMetadata</code> object.
     * @param nodeNames a <code>Set</code> containing the names of
     * nodes that may be contained in a retrieved document.
     *
     * @return an <code>IIOMetadata</code> object, or <code>null</code>.
     *
     * @exception IllegalStateException if the input source has not been
     * set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IllegalArgumentException if <code>formatName</code>
     * is <code>null</code>.
     * @exception IllegalArgumentException if <code>nodeNames</code>
     * is <code>null</code>.
     * @exception IOException if an error occurs during reading.
     */
    public IIOMetadata getImageMetadata(int imageIndex,
                                        String formatName,
                                        Set<String> nodeNames)
        throws IOException {
        return getMetadata(formatName, nodeNames, false, imageIndex);
    }

    /**
     * Reads the image indexed by <code>imageIndex</code> and returns
     * it as a complete <code>BufferedImage</code>, using a default
     * <code>ImageReadParam</code>.  This is a convenience method
     * that calls <code>read(imageIndex, null)</code>.
     *
     * <p> The image returned will be formatted according to the first
     * <code>ImageTypeSpecifier</code> returned from
     * <code>getImageTypes</code>.
     *
     * <p> Any registered <code>IIOReadProgressListener</code> objects
     * will be notified by calling their <code>imageStarted</code>
     * method, followed by calls to their <code>imageProgress</code>
     * method as the read progresses.  Finally their
     * <code>imageComplete</code> method will be called.
     * <code>IIOReadUpdateListener</code> objects may be updated at
     * other times during the read as pixels are decoded.  Finally,
     * <code>IIOReadWarningListener</code> objects will receive
     * notification of any non-fatal warnings that occur during
     * decoding.
     *
     * @param imageIndex the index of the image to be retrieved.
     *
     * @return the desired portion of the image as a
     * <code>BufferedImage</code>.
     *
     * @exception IllegalStateException if the input source has not been
     * set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public BufferedImage read(int imageIndex) throws IOException {
        return read(imageIndex, null);
    }

    /**
     * Reads the image indexed by <code>imageIndex</code> and returns
     * it as a complete <code>BufferedImage</code>, using a supplied
     * <code>ImageReadParam</code>.
     *
     * <p> The actual <code>BufferedImage</code> returned will be
     * chosen using the algorithm defined by the
     * <code>getDestination</code> method.
     *
     * <p> Any registered <code>IIOReadProgressListener</code> objects
     * will be notified by calling their <code>imageStarted</code>
     * method, followed by calls to their <code>imageProgress</code>
     * method as the read progresses.  Finally their
     * <code>imageComplete</code> method will be called.
     * <code>IIOReadUpdateListener</code> objects may be updated at
     * other times during the read as pixels are decoded.  Finally,
     * <code>IIOReadWarningListener</code> objects will receive
     * notification of any non-fatal warnings that occur during
     * decoding.
     *
     * <p> The set of source bands to be read and destination bands to
     * be written is determined by calling <code>getSourceBands</code>
     * and <code>getDestinationBands</code> on the supplied
     * <code>ImageReadParam</code>.  If the lengths of the arrays
     * returned by these methods differ, the set of source bands
     * contains an index larger that the largest available source
     * index, or the set of destination bands contains an index larger
     * than the largest legal destination index, an
     * <code>IllegalArgumentException</code> is thrown.
     *
     * <p> If the supplied <code>ImageReadParam</code> contains
     * optional setting values not supported by this reader (<i>e.g.</i>
     * source render size or any format-specific settings), they will
     * be ignored.
     *
     * @param imageIndex the index of the image to be retrieved.
     * @param param an <code>ImageReadParam</code> used to control
     * the reading process, or <code>null</code>.
     *
     * @return the desired portion of the image as a
     * <code>BufferedImage</code>.
     *
     * @exception IllegalStateException if the input source has not been
     * set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IllegalArgumentException if the set of source and
     * destination bands specified by
     * <code>param.getSourceBands</code> and
     * <code>param.getDestinationBands</code> differ in length or
     * include indices that are out of bounds.
     * @exception IllegalArgumentException if the resulting image would
     * have a width or height less than 1.
     * @exception IOException if an error occurs during reading.
     */
    public abstract BufferedImage read(int imageIndex, ImageReadParam param)
        throws IOException;

    /**
     * Reads the image indexed by <code>imageIndex</code> and returns
     * an <code>IIOImage</code> containing the image, thumbnails, and
     * associated image metadata, using a supplied
     * <code>ImageReadParam</code>.
     *
     * <p> The actual <code>BufferedImage</code> referenced by the
     * returned <code>IIOImage</code> will be chosen using the
     * algorithm defined by the <code>getDestination</code> method.
     *
     * <p> Any registered <code>IIOReadProgressListener</code> objects
     * will be notified by calling their <code>imageStarted</code>
     * method, followed by calls to their <code>imageProgress</code>
     * method as the read progresses.  Finally their
     * <code>imageComplete</code> method will be called.
     * <code>IIOReadUpdateListener</code> objects may be updated at
     * other times during the read as pixels are decoded.  Finally,
     * <code>IIOReadWarningListener</code> objects will receive
     * notification of any non-fatal warnings that occur during
     * decoding.
     *
     * <p> The set of source bands to be read and destination bands to
     * be written is determined by calling <code>getSourceBands</code>
     * and <code>getDestinationBands</code> on the supplied
     * <code>ImageReadParam</code>.  If the lengths of the arrays
     * returned by these methods differ, the set of source bands
     * contains an index larger that the largest available source
     * index, or the set of destination bands contains an index larger
     * than the largest legal destination index, an
     * <code>IllegalArgumentException</code> is thrown.
     *
     * <p> Thumbnails will be returned in their entirety regardless of
     * the region settings.
     *
     * <p> If the supplied <code>ImageReadParam</code> contains
     * optional setting values not supported by this reader (<i>e.g.</i>
     * source render size or any format-specific settings), those
     * values will be ignored.
     *
     * @param imageIndex the index of the image to be retrieved.
     * @param param an <code>ImageReadParam</code> used to control
     * the reading process, or <code>null</code>.
     *
     * @return an <code>IIOImage</code> containing the desired portion
     * of the image, a set of thumbnails, and associated image
     * metadata.
     *
     * @exception IllegalStateException if the input source has not been
     * set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IllegalArgumentException if the set of source and
     * destination bands specified by
     * <code>param.getSourceBands</code> and
     * <code>param.getDestinationBands</code> differ in length or
     * include indices that are out of bounds.
     * @exception IllegalArgumentException if the resulting image
     * would have a width or height less than 1.
     * @exception IOException if an error occurs during reading.
     */
    public IIOImage readAll(int imageIndex, ImageReadParam param)
        throws IOException {
        if (imageIndex < getMinIndex()) {
            throw new IndexOutOfBoundsException("imageIndex < getMinIndex()!");
        }

        BufferedImage im = read(imageIndex, param);

        ArrayList thumbnails = null;
        int numThumbnails = getNumThumbnails(imageIndex);
        if (numThumbnails > 0) {
            thumbnails = new ArrayList();
            for (int j = 0; j < numThumbnails; j++) {
                thumbnails.add(readThumbnail(imageIndex, j));
            }
        }

        IIOMetadata metadata = getImageMetadata(imageIndex);
        return new IIOImage(im, thumbnails, metadata);
    }

    /**
     * Returns an <code>Iterator</code> containing all the images,
     * thumbnails, and metadata, starting at the index given by
     * <code>getMinIndex</code>, from the input source in the form of
     * <code>IIOImage</code> objects.  An <code>Iterator</code>
     * containing <code>ImageReadParam</code> objects is supplied; one
     * element is consumed for each image read from the input source
     * until no more images are available.  If the read param
     * <code>Iterator</code> runs out of elements, but there are still
     * more images available from the input source, default read
     * params are used for the remaining images.
     *
     * <p> If <code>params</code> is <code>null</code>, a default read
     * param will be used for all images.
     *
     * <p> The actual <code>BufferedImage</code> referenced by the
     * returned <code>IIOImage</code> will be chosen using the
     * algorithm defined by the <code>getDestination</code> method.
     *
     * <p> Any registered <code>IIOReadProgressListener</code> objects
     * will be notified by calling their <code>sequenceStarted</code>
     * method once.  Then, for each image decoded, there will be a
     * call to <code>imageStarted</code>, followed by calls to
     * <code>imageProgress</code> as the read progresses, and finally
     * to <code>imageComplete</code>.  The
     * <code>sequenceComplete</code> method will be called after the
     * last image has been decoded.
     * <code>IIOReadUpdateListener</code> objects may be updated at
     * other times during the read as pixels are decoded.  Finally,
     * <code>IIOReadWarningListener</code> objects will receive
     * notification of any non-fatal warnings that occur during
     * decoding.
     *
     * <p> The set of source bands to be read and destination bands to
     * be written is determined by calling <code>getSourceBands</code>
     * and <code>getDestinationBands</code> on the supplied
     * <code>ImageReadParam</code>.  If the lengths of the arrays
     * returned by these methods differ, the set of source bands
     * contains an index larger that the largest available source
     * index, or the set of destination bands contains an index larger
     * than the largest legal destination index, an
     * <code>IllegalArgumentException</code> is thrown.
     *
     * <p> Thumbnails will be returned in their entirety regardless of the
     * region settings.
     *
     * <p> If any of the supplied <code>ImageReadParam</code>s contain
     * optional setting values not supported by this reader (<i>e.g.</i>
     * source render size or any format-specific settings), they will
     * be ignored.
     *
     * @param params an <code>Iterator</code> containing
     * <code>ImageReadParam</code> objects.
     *
     * @return an <code>Iterator</code> representing the
     * contents of the input source as <code>IIOImage</code>s.
     *
     * @exception IllegalStateException if the input source has not been
     * set.
     * @exception IllegalArgumentException if any
     * non-<code>null</code> element of <code>params</code> is not an
     * <code>ImageReadParam</code>.
     * @exception IllegalArgumentException if the set of source and
     * destination bands specified by
     * <code>param.getSourceBands</code> and
     * <code>param.getDestinationBands</code> differ in length or
     * include indices that are out of bounds.
     * @exception IllegalArgumentException if a resulting image would
     * have a width or height less than 1.
     * @exception IOException if an error occurs during reading.
     *
     * @see ImageReadParam
     * @see IIOImage
     */
    public Iterator<IIOImage>
        readAll(Iterator<? extends ImageReadParam> params)
        throws IOException
    {
        List output = new ArrayList();

        int imageIndex = getMinIndex();

        // Inform IIOReadProgressListeners we're starting a sequence
        processSequenceStarted(imageIndex);

        while (true) {
            // Inform IIOReadProgressListeners and IIOReadUpdateListeners
            // that we're starting a new image

            ImageReadParam param = null;
            if (params != null && params.hasNext()) {
                Object o = params.next();
                if (o != null) {
                    if (o instanceof ImageReadParam) {
                        param = (ImageReadParam)o;
                    } else {
                        throw new IllegalArgumentException
                            ("Non-ImageReadParam supplied as part of params!");
                    }
                }
            }

            BufferedImage bi = null;
            try {
                bi = read(imageIndex, param);
            } catch (IndexOutOfBoundsException e) {
                break;
            }

            ArrayList thumbnails = null;
            int numThumbnails = getNumThumbnails(imageIndex);
            if (numThumbnails > 0) {
                thumbnails = new ArrayList();
                for (int j = 0; j < numThumbnails; j++) {
                    thumbnails.add(readThumbnail(imageIndex, j));
                }
            }

            IIOMetadata metadata = getImageMetadata(imageIndex);
            IIOImage im = new IIOImage(bi, thumbnails, metadata);
            output.add(im);

            ++imageIndex;
        }

        // Inform IIOReadProgressListeners we're ending a sequence
        processSequenceComplete();

        return output.iterator();
    }

    /**
     * Returns <code>true</code> if this plug-in supports reading
     * just a {@link java.awt.image.Raster <code>Raster</code>} of pixel data.
     * If this method returns <code>false</code>, calls to
     * {@link #readRaster <code>readRaster</code>} or {@link #readTileRaster
     * <code>readTileRaster</code>} will throw an
     * <code>UnsupportedOperationException</code>.
     *
     * <p> The default implementation returns <code>false</code>.
     *
     * @return <code>true</code> if this plug-in supports reading raw
     * <code>Raster</code>s.
     *
     * @see #readRaster
     * @see #readTileRaster
     */
    public boolean canReadRaster() {
        return false;
    }

    /**
     * Returns a new <code>Raster</code> object containing the raw pixel data
     * from the image stream, without any color conversion applied.  The
     * application must determine how to interpret the pixel data by other
     * means.  Any destination or image-type parameters in the supplied
     * <code>ImageReadParam</code> object are ignored, but all other
     * parameters are used exactly as in the {@link #read <code>read</code>}
     * method, except that any destination offset is used as a logical rather
     * than a physical offset.  The size of the returned <code>Raster</code>
     * will always be that of the source region clipped to the actual image.
     * Logical offsets in the stream itself are ignored.
     *
     * <p> This method allows formats that normally apply a color
     * conversion, such as JPEG, and formats that do not normally have an
     * associated colorspace, such as remote sensing or medical imaging data,
     * to provide access to raw pixel data.
     *
     * <p> Any registered <code>readUpdateListener</code>s are ignored, as
     * there is no <code>BufferedImage</code>, but all other listeners are
     * called exactly as they are for the {@link #read <code>read</code>}
     * method.
     *
     * <p> If {@link #canReadRaster <code>canReadRaster()</code>} returns
     * <code>false</code>, this method throws an
     * <code>UnsupportedOperationException</code>.
     *
     * <p> If the supplied <code>ImageReadParam</code> contains
     * optional setting values not supported by this reader (<i>e.g.</i>
     * source render size or any format-specific settings), they will
     * be ignored.
     *
     * <p> The default implementation throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param imageIndex the index of the image to be read.
     * @param param an <code>ImageReadParam</code> used to control
     * the reading process, or <code>null</code>.
     *
     * @return the desired portion of the image as a
     * <code>Raster</code>.
     *
     * @exception UnsupportedOperationException if this plug-in does not
     * support reading raw <code>Raster</code>s.
     * @exception IllegalStateException if the input source has not been
     * set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IOException if an error occurs during reading.
     *
     * @see #canReadRaster
     * @see #read
     * @see java.awt.image.Raster
     */
    public Raster readRaster(int imageIndex, ImageReadParam param)
        throws IOException {
        throw new UnsupportedOperationException("readRaster not supported!");
    }

    /**
     * Returns <code>true</code> if the image is organized into
     * <i>tiles</i>, that is, equal-sized non-overlapping rectangles.
     *
     * <p> A reader plug-in may choose whether or not to expose tiling
     * that is present in the image as it is stored.  It may even
     * choose to advertise tiling when none is explicitly present.  In
     * general, tiling should only be advertised if there is some
     * advantage (in speed or space) to accessing individual tiles.
     * Regardless of whether the reader advertises tiling, it must be
     * capable of reading an arbitrary rectangular region specified in
     * an <code>ImageReadParam</code>.
     *
     * <p> A reader for which all images are guaranteed to be tiled,
     * or are guaranteed not to be tiled, may return <code>true</code>
     * or <code>false</code> respectively without accessing any image
     * data.  In such cases, it is not necessary to throw an exception
     * even if no input source has been set or the image index is out
     * of bounds.
     *
     * <p> The default implementation just returns <code>false</code>.
     *
     * @param imageIndex the index of the image to be queried.
     *
     * @return <code>true</code> if the image is tiled.
     *
     * @exception IllegalStateException if an input source is required
     * to determine the return value, but none has been set.
     * @exception IndexOutOfBoundsException if an image must be
     * accessed to determine the return value, but the supplied index
     * is out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public boolean isImageTiled(int imageIndex) throws IOException {
        return false;
    }

    /**
     * Returns the width of a tile in the given image.
     *
     * <p> The default implementation simply returns
     * <code>getWidth(imageIndex)</code>, which is correct for
     * non-tiled images.  Readers that support tiling should override
     * this method.
     *
     * @return the width of a tile.
     *
     * @param imageIndex the index of the image to be queried.
     *
     * @exception IllegalStateException if the input source has not been set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public int getTileWidth(int imageIndex) throws IOException {
        return getWidth(imageIndex);
    }

    /**
     * Returns the height of a tile in the given image.
     *
     * <p> The default implementation simply returns
     * <code>getHeight(imageIndex)</code>, which is correct for
     * non-tiled images.  Readers that support tiling should override
     * this method.
     *
     * @return the height of a tile.
     *
     * @param imageIndex the index of the image to be queried.
     *
     * @exception IllegalStateException if the input source has not been set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public int getTileHeight(int imageIndex) throws IOException {
        return getHeight(imageIndex);
    }

    /**
     * Returns the X coordinate of the upper-left corner of tile (0,
     * 0) in the given image.
     *
     * <p> A reader for which the tile grid X offset always has the
     * same value (usually 0), may return the value without accessing
     * any image data.  In such cases, it is not necessary to throw an
     * exception even if no input source has been set or the image
     * index is out of bounds.
     *
     * <p> The default implementation simply returns 0, which is
     * correct for non-tiled images and tiled images in most formats.
     * Readers that support tiling with non-(0, 0) offsets should
     * override this method.
     *
     * @return the X offset of the tile grid.
     *
     * @param imageIndex the index of the image to be queried.
     *
     * @exception IllegalStateException if an input source is required
     * to determine the return value, but none has been set.
     * @exception IndexOutOfBoundsException if an image must be
     * accessed to determine the return value, but the supplied index
     * is out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public int getTileGridXOffset(int imageIndex) throws IOException {
        return 0;
    }

    /**
     * Returns the Y coordinate of the upper-left corner of tile (0,
     * 0) in the given image.
     *
     * <p> A reader for which the tile grid Y offset always has the
     * same value (usually 0), may return the value without accessing
     * any image data.  In such cases, it is not necessary to throw an
     * exception even if no input source has been set or the image
     * index is out of bounds.
     *
     * <p> The default implementation simply returns 0, which is
     * correct for non-tiled images and tiled images in most formats.
     * Readers that support tiling with non-(0, 0) offsets should
     * override this method.
     *
     * @return the Y offset of the tile grid.
     *
     * @param imageIndex the index of the image to be queried.
     *
     * @exception IllegalStateException if an input source is required
     * to determine the return value, but none has been set.
     * @exception IndexOutOfBoundsException if an image must be
     * accessed to determine the return value, but the supplied index
     * is out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public int getTileGridYOffset(int imageIndex) throws IOException {
        return 0;
    }

    /**
     * Reads the tile indicated by the <code>tileX</code> and
     * <code>tileY</code> arguments, returning it as a
     * <code>BufferedImage</code>.  If the arguments are out of range,
     * an <code>IllegalArgumentException</code> is thrown.  If the
     * image is not tiled, the values 0, 0 will return the entire
     * image; any other values will cause an
     * <code>IllegalArgumentException</code> to be thrown.
     *
     * <p> This method is merely a convenience equivalent to calling
     * <code>read(int, ImageReadParam)</code> with a read param
     * specifiying a source region having offsets of
     * <code>tileX*getTileWidth(imageIndex)</code>,
     * <code>tileY*getTileHeight(imageIndex)</code> and width and
     * height of <code>getTileWidth(imageIndex)</code>,
     * <code>getTileHeight(imageIndex)</code>; and subsampling
     * factors of 1 and offsets of 0.  To subsample a tile, call
     * <code>read</code> with a read param specifying this region
     * and different subsampling parameters.
     *
     * <p> The default implementation returns the entire image if
     * <code>tileX</code> and <code>tileY</code> are 0, or throws
     * an <code>IllegalArgumentException</code> otherwise.
     *
     * @param imageIndex the index of the image to be retrieved.
     * @param tileX the column index (starting with 0) of the tile
     * to be retrieved.
     * @param tileY the row index (starting with 0) of the tile
     * to be retrieved.
     *
     * @return the tile as a <code>BufferedImage</code>.
     *
     * @exception IllegalStateException if the input source has not been
     * set.
     * @exception IndexOutOfBoundsException if <code>imageIndex</code>
     * is out of bounds.
     * @exception IllegalArgumentException if the tile indices are
     * out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public BufferedImage readTile(int imageIndex,
                                  int tileX, int tileY) throws IOException {
        if ((tileX != 0) || (tileY != 0)) {
            throw new IllegalArgumentException("Invalid tile indices");
        }
        return read(imageIndex);
    }

    /**
     * Returns a new <code>Raster</code> object containing the raw
     * pixel data from the tile, without any color conversion applied.
     * The application must determine how to interpret the pixel data by other
     * means.
     *
     * <p> If {@link #canReadRaster <code>canReadRaster()</code>} returns
     * <code>false</code>, this method throws an
     * <code>UnsupportedOperationException</code>.
     *
     * <p> The default implementation checks if reading
     * <code>Raster</code>s is supported, and if so calls {@link
     * #readRaster <code>readRaster(imageIndex, null)</code>} if
     * <code>tileX</code> and <code>tileY</code> are 0, or throws an
     * <code>IllegalArgumentException</code> otherwise.
     *
     * @param imageIndex the index of the image to be retrieved.
     * @param tileX the column index (starting with 0) of the tile
     * to be retrieved.
     * @param tileY the row index (starting with 0) of the tile
     * to be retrieved.
     *
     * @return the tile as a <code>Raster</code>.
     *
     * @exception UnsupportedOperationException if this plug-in does not
     * support reading raw <code>Raster</code>s.
     * @exception IllegalArgumentException if the tile indices are
     * out of bounds.
     * @exception IllegalStateException if the input source has not been
     * set.
     * @exception IndexOutOfBoundsException if <code>imageIndex</code>
     * is out of bounds.
     * @exception IOException if an error occurs during reading.
     *
     * @see #readTile
     * @see #readRaster
     * @see java.awt.image.Raster
     */
    public Raster readTileRaster(int imageIndex,
                                 int tileX, int tileY) throws IOException {
        if (!canReadRaster()) {
            throw new UnsupportedOperationException
                ("readTileRaster not supported!");
        }
        if ((tileX != 0) || (tileY != 0)) {
            throw new IllegalArgumentException("Invalid tile indices");
        }
        return readRaster(imageIndex, null);
    }

    // RenderedImages

    /**
     * Returns a <code>RenderedImage</code> object that contains the
     * contents of the image indexed by <code>imageIndex</code>.  By
     * default, the returned image is simply the
     * <code>BufferedImage</code> returned by <code>read(imageIndex,
     * param)</code>.
     *
     * <p> The semantics of this method may differ from those of the
     * other <code>read</code> methods in several ways.  First, any
     * destination image and/or image type set in the
     * <code>ImageReadParam</code> may be ignored.  Second, the usual
     * listener calls are not guaranteed to be made, or to be
     * meaningful if they are.  This is because the returned image may
     * not be fully populated with pixel data at the time it is
     * returned, or indeed at any time.
     *
     * <p> If the supplied <code>ImageReadParam</code> contains
     * optional setting values not supported by this reader (<i>e.g.</i>
     * source render size or any format-specific settings), they will
     * be ignored.
     *
     * <p> The default implementation just calls {@link #read
     * <code>read(imageIndex, param)</code>}.
     *
     * @param imageIndex the index of the image to be retrieved.
     * @param param an <code>ImageReadParam</code> used to control
     * the reading process, or <code>null</code>.
     *
     * @return a <code>RenderedImage</code> object providing a view of
     * the image.
     *
     * @exception IllegalStateException if the input source has not been
     * set.
     * @exception IndexOutOfBoundsException if the supplied index is
     * out of bounds.
     * @exception IllegalArgumentException if the set of source and
     * destination bands specified by
     * <code>param.getSourceBands</code> and
     * <code>param.getDestinationBands</code> differ in length or
     * include indices that are out of bounds.
     * @exception IllegalArgumentException if the resulting image
     * would have a width or height less than 1.
     * @exception IOException if an error occurs during reading.
     */
    public RenderedImage readAsRenderedImage(int imageIndex,
                                             ImageReadParam param)
        throws IOException {
        return read(imageIndex, param);
    }

    // Thumbnails

    /**
     * Returns <code>true</code> if the image format understood by
     * this reader supports thumbnail preview images associated with
     * it.  The default implementation returns <code>false</code>.
     *
     * <p> If this method returns <code>false</code>,
     * <code>hasThumbnails</code> and <code>getNumThumbnails</code>
     * will return <code>false</code> and <code>0</code>,
     * respectively, and <code>readThumbnail</code> will throw an
     * <code>UnsupportedOperationException</code>, regardless of their
     * arguments.
     *
     * <p> A reader that does not support thumbnails need not
     * implement any of the thumbnail-related methods.
     *
     * @return <code>true</code> if thumbnails are supported.
     */
    public boolean readerSupportsThumbnails() {
        return false;
    }

    /**
     * Returns <code>true</code> if the given image has thumbnail
     * preview images associated with it.  If the format does not
     * support thumbnails (<code>readerSupportsThumbnails</code>
     * returns <code>false</code>), <code>false</code> will be
     * returned regardless of whether an input source has been set or
     * whether <code>imageIndex</code> is in bounds.
     *
     * <p> The default implementation returns <code>true</code> if
     * <code>getNumThumbnails</code> returns a value greater than 0.
     *
     * @param imageIndex the index of the image being queried.
     *
     * @return <code>true</code> if the given image has thumbnails.
     *
     * @exception IllegalStateException if the reader supports
     * thumbnails but the input source has not been set.
     * @exception IndexOutOfBoundsException if the reader supports
     * thumbnails but <code>imageIndex</code> is out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public boolean hasThumbnails(int imageIndex) throws IOException {
        return getNumThumbnails(imageIndex) > 0;
    }

    /**
     * Returns the number of thumbnail preview images associated with
     * the given image.  If the format does not support thumbnails,
     * (<code>readerSupportsThumbnails</code> returns
     * <code>false</code>), <code>0</code> will be returned regardless
     * of whether an input source has been set or whether
     * <code>imageIndex</code> is in bounds.
     *
     * <p> The default implementation returns 0 without checking its
     * argument.
     *
     * @param imageIndex the index of the image being queried.
     *
     * @return the number of thumbnails associated with the given
     * image.
     *
     * @exception IllegalStateException if the reader supports
     * thumbnails but the input source has not been set.
     * @exception IndexOutOfBoundsException if the reader supports
     * thumbnails but <code>imageIndex</code> is out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public int getNumThumbnails(int imageIndex)
        throws IOException {
        return 0;
    }

    /**
     * Returns the width of the thumbnail preview image indexed by
     * <code>thumbnailIndex</code>, associated with the image indexed
     * by <code>ImageIndex</code>.
     *
     * <p> If the reader does not support thumbnails,
     * (<code>readerSupportsThumbnails</code> returns
     * <code>false</code>), an <code>UnsupportedOperationException</code>
     * will be thrown.
     *
     * <p> The default implementation simply returns
     * <code>readThumbnail(imageindex,
     * thumbnailIndex).getWidth()</code>.  Subclasses should therefore
     * override this method if possible in order to avoid forcing the
     * thumbnail to be read.
     *
     * @param imageIndex the index of the image to be retrieved.
     * @param thumbnailIndex the index of the thumbnail to be retrieved.
     *
     * @return the width of the desired thumbnail as an <code>int</code>.
     *
     * @exception UnsupportedOperationException if thumbnails are not
     * supported.
     * @exception IllegalStateException if the input source has not been set.
     * @exception IndexOutOfBoundsException if either of the supplied
     * indices are out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public int getThumbnailWidth(int imageIndex, int thumbnailIndex)
        throws IOException {
        return readThumbnail(imageIndex, thumbnailIndex).getWidth();
    }

    /**
     * Returns the height of the thumbnail preview image indexed by
     * <code>thumbnailIndex</code>, associated with the image indexed
     * by <code>ImageIndex</code>.
     *
     * <p> If the reader does not support thumbnails,
     * (<code>readerSupportsThumbnails</code> returns
     * <code>false</code>), an <code>UnsupportedOperationException</code>
     * will be thrown.
     *
     * <p> The default implementation simply returns
     * <code>readThumbnail(imageindex,
     * thumbnailIndex).getHeight()</code>.  Subclasses should
     * therefore override this method if possible in order to avoid
     * forcing the thumbnail to be read.
     *
     * @param imageIndex the index of the image to be retrieved.
     * @param thumbnailIndex the index of the thumbnail to be retrieved.
     *
     * @return the height of the desired thumbnail as an <code>int</code>.
     *
     * @exception UnsupportedOperationException if thumbnails are not
     * supported.
     * @exception IllegalStateException if the input source has not been set.
     * @exception IndexOutOfBoundsException if either of the supplied
     * indices are out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public int getThumbnailHeight(int imageIndex, int thumbnailIndex)
        throws IOException {
        return readThumbnail(imageIndex, thumbnailIndex).getHeight();
    }

    /**
     * Returns the thumbnail preview image indexed by
     * <code>thumbnailIndex</code>, associated with the image indexed
     * by <code>ImageIndex</code> as a <code>BufferedImage</code>.
     *
     * <p> Any registered <code>IIOReadProgressListener</code> objects
     * will be notified by calling their
     * <code>thumbnailStarted</code>, <code>thumbnailProgress</code>,
     * and <code>thumbnailComplete</code> methods.
     *
     * <p> If the reader does not support thumbnails,
     * (<code>readerSupportsThumbnails</code> returns
     * <code>false</code>), an <code>UnsupportedOperationException</code>
     * will be thrown regardless of whether an input source has been
     * set or whether the indices are in bounds.
     *
     * <p> The default implementation throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param imageIndex the index of the image to be retrieved.
     * @param thumbnailIndex the index of the thumbnail to be retrieved.
     *
     * @return the desired thumbnail as a <code>BufferedImage</code>.
     *
     * @exception UnsupportedOperationException if thumbnails are not
     * supported.
     * @exception IllegalStateException if the input source has not been set.
     * @exception IndexOutOfBoundsException if either of the supplied
     * indices are out of bounds.
     * @exception IOException if an error occurs during reading.
     */
    public BufferedImage readThumbnail(int imageIndex,
                                       int thumbnailIndex)
        throws IOException {
        throw new UnsupportedOperationException("Thumbnails not supported!");
    }

    // Abort

    /**
     * Requests that any current read operation be aborted.  The
     * contents of the image following the abort will be undefined.
     *
     * <p> Readers should call <code>clearAbortRequest</code> at the
     * beginning of each read operation, and poll the value of
     * <code>abortRequested</code> regularly during the read.
     */
    public synchronized void abort() {
        this.abortFlag = true;
    }

    /**
     * Returns <code>true</code> if a request to abort the current
     * read operation has been made since the reader was instantiated or
     * <code>clearAbortRequest</code> was called.
     *
     * @return <code>true</code> if the current read operation should
     * be aborted.
     *
     * @see #abort
     * @see #clearAbortRequest
     */
    protected synchronized boolean abortRequested() {
        return this.abortFlag;
    }

    /**
     * Clears any previous abort request.  After this method has been
     * called, <code>abortRequested</code> will return
     * <code>false</code>.
     *
     * @see #abort
     * @see #abortRequested
     */
    protected synchronized void clearAbortRequest() {
        this.abortFlag = false;
    }

    // Listeners

    // Add an element to a list, creating a new list if the
    // existing list is null, and return the list.
    static List addToList(List l, Object elt) {
        if (l == null) {
            l = new ArrayList();
        }
        l.add(elt);
        return l;
    }


    // Remove an element from a list, discarding the list if the
    // resulting list is empty, and return the list or null.
    static List removeFromList(List l, Object elt) {
        if (l == null) {
            return l;
        }
        l.remove(elt);
        if (l.size() == 0) {
            l = null;
        }
        return l;
    }

    /**
     * Adds an <code>IIOReadWarningListener</code> to the list of
     * registered warning listeners.  If <code>listener</code> is
     * <code>null</code>, no exception will be thrown and no action
     * will be taken.  Messages sent to the given listener will be
     * localized, if possible, to match the current
     * <code>Locale</code>.  If no <code>Locale</code> has been set,
     * warning messages may be localized as the reader sees fit.
     *
     * @param listener an <code>IIOReadWarningListener</code> to be registered.
     *
     * @see #removeIIOReadWarningListener
     */
    public void addIIOReadWarningListener(IIOReadWarningListener listener) {
        if (listener == null) {
            return;
        }
        warningListeners = addToList(warningListeners, listener);
        warningLocales = addToList(warningLocales, getLocale());
    }

    /**
     * Removes an <code>IIOReadWarningListener</code> from the list of
     * registered error listeners.  If the listener was not previously
     * registered, or if <code>listener</code> is <code>null</code>,
     * no exception will be thrown and no action will be taken.
     *
     * @param listener an IIOReadWarningListener to be unregistered.
     *
     * @see #addIIOReadWarningListener
     */
    public void removeIIOReadWarningListener(IIOReadWarningListener listener) {
        if (listener == null || warningListeners == null) {
            return;
        }
        int index = warningListeners.indexOf(listener);
        if (index != -1) {
            warningListeners.remove(index);
            warningLocales.remove(index);
            if (warningListeners.size() == 0) {
                warningListeners = null;
                warningLocales = null;
            }
        }
    }

    /**
     * Removes all currently registered
     * <code>IIOReadWarningListener</code> objects.
     *
     * <p> The default implementation sets the
     * <code>warningListeners</code> and <code>warningLocales</code>
     * instance variables to <code>null</code>.
     */
    public void removeAllIIOReadWarningListeners() {
        warningListeners = null;
        warningLocales = null;
    }

    /**
     * Adds an <code>IIOReadProgressListener</code> to the list of
     * registered progress listeners.  If <code>listener</code> is
     * <code>null</code>, no exception will be thrown and no action
     * will be taken.
     *
     * @param listener an IIOReadProgressListener to be registered.
     *
     * @see #removeIIOReadProgressListener
     */
    public void addIIOReadProgressListener(IIOReadProgressListener listener) {
        if (listener == null) {
            return;
        }
        progressListeners = addToList(progressListeners, listener);
    }

    /**
     * Removes an <code>IIOReadProgressListener</code> from the list
     * of registered progress listeners.  If the listener was not
     * previously registered, or if <code>listener</code> is
     * <code>null</code>, no exception will be thrown and no action
     * will be taken.
     *
     * @param listener an IIOReadProgressListener to be unregistered.
     *
     * @see #addIIOReadProgressListener
     */
    public void
        removeIIOReadProgressListener (IIOReadProgressListener listener) {
        if (listener == null || progressListeners == null) {
            return;
        }
        progressListeners = removeFromList(progressListeners, listener);
    }

    /**
     * Removes all currently registered
     * <code>IIOReadProgressListener</code> objects.
     *
     * <p> The default implementation sets the
     * <code>progressListeners</code> instance variable to
     * <code>null</code>.
     */
    public void removeAllIIOReadProgressListeners() {
        progressListeners = null;
    }

    /**
     * Adds an <code>IIOReadUpdateListener</code> to the list of
     * registered update listeners.  If <code>listener</code> is
     * <code>null</code>, no exception will be thrown and no action
     * will be taken.  The listener will receive notification of pixel
     * updates as images and thumbnails are decoded, including the
     * starts and ends of progressive passes.
     *
     * <p> If no update listeners are present, the reader may choose
     * to perform fewer updates to the pixels of the destination
     * images and/or thumbnails, which may result in more efficient
     * decoding.
     *
     * <p> For example, in progressive JPEG decoding each pass
     * contains updates to a set of coefficients, which would have to
     * be transformed into pixel values and converted to an RGB color
     * space for each pass if listeners are present.  If no listeners
     * are present, the coefficients may simply be accumulated and the
     * final results transformed and color converted one time only.
     *
     * <p> The final results of decoding will be the same whether or
     * not intermediate updates are performed.  Thus if only the final
     * image is desired it may be perferable not to register any
     * <code>IIOReadUpdateListener</code>s.  In general, progressive
     * updating is most effective when fetching images over a network
     * connection that is very slow compared to local CPU processing;
     * over a fast connection, progressive updates may actually slow
     * down the presentation of the image.
     *
     * @param listener an IIOReadUpdateListener to be registered.
     *
     * @see #removeIIOReadUpdateListener
     */
    public void
        addIIOReadUpdateListener(IIOReadUpdateListener listener) {
        if (listener == null) {
            return;
        }
        updateListeners = addToList(updateListeners, listener);
    }

    /**
     * Removes an <code>IIOReadUpdateListener</code> from the list of
     * registered update listeners.  If the listener was not
     * previously registered, or if <code>listener</code> is
     * <code>null</code>, no exception will be thrown and no action
     * will be taken.
     *
     * @param listener an IIOReadUpdateListener to be unregistered.
     *
     * @see #addIIOReadUpdateListener
     */
    public void removeIIOReadUpdateListener(IIOReadUpdateListener listener) {
        if (listener == null || updateListeners == null) {
            return;
        }
        updateListeners = removeFromList(updateListeners, listener);
    }

    /**
     * Removes all currently registered
     * <code>IIOReadUpdateListener</code> objects.
     *
     * <p> The default implementation sets the
     * <code>updateListeners</code> instance variable to
     * <code>null</code>.
     */
    public void removeAllIIOReadUpdateListeners() {
        updateListeners = null;
    }

    /**
     * Broadcasts the start of an sequence of image reads to all
     * registered <code>IIOReadProgressListener</code>s by calling
     * their <code>sequenceStarted</code> method.  Subclasses may use
     * this method as a convenience.
     *
     * @param minIndex the lowest index being read.
     */
    protected void processSequenceStarted(int minIndex) {
        if (progressListeners == null) {
            return;
        }
        int numListeners = progressListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadProgressListener listener =
                (IIOReadProgressListener)progressListeners.get(i);
            listener.sequenceStarted(this, minIndex);
        }
    }

    /**
     * Broadcasts the completion of an sequence of image reads to all
     * registered <code>IIOReadProgressListener</code>s by calling
     * their <code>sequenceComplete</code> method.  Subclasses may use
     * this method as a convenience.
     */
    protected void processSequenceComplete() {
        if (progressListeners == null) {
            return;
        }
        int numListeners = progressListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadProgressListener listener =
                (IIOReadProgressListener)progressListeners.get(i);
            listener.sequenceComplete(this);
        }
    }

    /**
     * Broadcasts the start of an image read to all registered
     * <code>IIOReadProgressListener</code>s by calling their
     * <code>imageStarted</code> method.  Subclasses may use this
     * method as a convenience.
     *
     * @param imageIndex the index of the image about to be read.
     */
    protected void processImageStarted(int imageIndex) {
        if (progressListeners == null) {
            return;
        }
        int numListeners = progressListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadProgressListener listener =
                (IIOReadProgressListener)progressListeners.get(i);
            listener.imageStarted(this, imageIndex);
        }
    }

    /**
     * Broadcasts the current percentage of image completion to all
     * registered <code>IIOReadProgressListener</code>s by calling
     * their <code>imageProgress</code> method.  Subclasses may use
     * this method as a convenience.
     *
     * @param percentageDone the current percentage of completion,
     * as a <code>float</code>.
     */
    protected void processImageProgress(float percentageDone) {
        if (progressListeners == null) {
            return;
        }
        int numListeners = progressListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadProgressListener listener =
                (IIOReadProgressListener)progressListeners.get(i);
            listener.imageProgress(this, percentageDone);
        }
    }

    /**
     * Broadcasts the completion of an image read to all registered
     * <code>IIOReadProgressListener</code>s by calling their
     * <code>imageComplete</code> method.  Subclasses may use this
     * method as a convenience.
     */
    protected void processImageComplete() {
        if (progressListeners == null) {
            return;
        }
        int numListeners = progressListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadProgressListener listener =
                (IIOReadProgressListener)progressListeners.get(i);
            listener.imageComplete(this);
        }
    }

    /**
     * Broadcasts the start of a thumbnail read to all registered
     * <code>IIOReadProgressListener</code>s by calling their
     * <code>thumbnailStarted</code> method.  Subclasses may use this
     * method as a convenience.
     *
     * @param imageIndex the index of the image associated with the
     * thumbnail.
     * @param thumbnailIndex the index of the thumbnail.
     */
    protected void processThumbnailStarted(int imageIndex,
                                           int thumbnailIndex) {
        if (progressListeners == null) {
            return;
        }
        int numListeners = progressListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadProgressListener listener =
                (IIOReadProgressListener)progressListeners.get(i);
            listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
        }
    }

    /**
     * Broadcasts the current percentage of thumbnail completion to
     * all registered <code>IIOReadProgressListener</code>s by calling
     * their <code>thumbnailProgress</code> method.  Subclasses may
     * use this method as a convenience.
     *
     * @param percentageDone the current percentage of completion,
     * as a <code>float</code>.
     */
    protected void processThumbnailProgress(float percentageDone) {
        if (progressListeners == null) {
            return;
        }
        int numListeners = progressListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadProgressListener listener =
                (IIOReadProgressListener)progressListeners.get(i);
            listener.thumbnailProgress(this, percentageDone);
        }
    }

    /**
     * Broadcasts the completion of a thumbnail read to all registered
     * <code>IIOReadProgressListener</code>s by calling their
     * <code>thumbnailComplete</code> method.  Subclasses may use this
     * method as a convenience.
     */
    protected void processThumbnailComplete() {
        if (progressListeners == null) {
            return;
        }
        int numListeners = progressListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadProgressListener listener =
                (IIOReadProgressListener)progressListeners.get(i);
            listener.thumbnailComplete(this);
        }
    }

    /**
     * Broadcasts that the read has been aborted to all registered
     * <code>IIOReadProgressListener</code>s by calling their
     * <code>readAborted</code> method.  Subclasses may use this
     * method as a convenience.
     */
    protected void processReadAborted() {
        if (progressListeners == null) {
            return;
        }
        int numListeners = progressListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadProgressListener listener =
                (IIOReadProgressListener)progressListeners.get(i);
            listener.readAborted(this);
        }
    }

    /**
     * Broadcasts the beginning of a progressive pass to all
     * registered <code>IIOReadUpdateListener</code>s by calling their
     * <code>passStarted</code> method.  Subclasses may use this
     * method as a convenience.
     *
     * @param theImage the <code>BufferedImage</code> being updated.
     * @param pass the index of the current pass, starting with 0.
     * @param minPass the index of the first pass that will be decoded.
     * @param maxPass the index of the last pass that will be decoded.
     * @param minX the X coordinate of the upper-left pixel included
     * in the pass.
     * @param minY the X coordinate of the upper-left pixel included
     * in the pass.
     * @param periodX the horizontal separation between pixels.
     * @param periodY the vertical separation between pixels.
     * @param bands an array of <code>int</code>s indicating the
     * set of affected bands of the destination.
     */
    protected void processPassStarted(BufferedImage theImage,
                                      int pass,
                                      int minPass, int maxPass,
                                      int minX, int minY,
                                      int periodX, int periodY,
                                      int[] bands) {
        if (updateListeners == null) {
            return;
        }
        int numListeners = updateListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadUpdateListener listener =
                (IIOReadUpdateListener)updateListeners.get(i);
            listener.passStarted(this, theImage, pass,
                                 minPass,
                                 maxPass,
                                 minX, minY,
                                 periodX, periodY,
                                 bands);
        }
    }

    /**
     * Broadcasts the update of a set of samples to all registered
     * <code>IIOReadUpdateListener</code>s by calling their
     * <code>imageUpdate</code> method.  Subclasses may use this
     * method as a convenience.
     *
     * @param theImage the <code>BufferedImage</code> being updated.
     * @param minX the X coordinate of the upper-left pixel included
     * in the pass.
     * @param minY the X coordinate of the upper-left pixel included
     * in the pass.
     * @param width the total width of the area being updated, including
     * pixels being skipped if <code>periodX &gt; 1</code>.
     * @param height the total height of the area being updated,
     * including pixels being skipped if <code>periodY &gt; 1</code>.
     * @param periodX the horizontal separation between pixels.
     * @param periodY the vertical separation between pixels.
     * @param bands an array of <code>int</code>s indicating the
     * set of affected bands of the destination.
     */
    protected void processImageUpdate(BufferedImage theImage,
                                      int minX, int minY,
                                      int width, int height,
                                      int periodX, int periodY,
                                      int[] bands) {
        if (updateListeners == null) {
            return;
        }
        int numListeners = updateListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadUpdateListener listener =
                (IIOReadUpdateListener)updateListeners.get(i);
            listener.imageUpdate(this,
                                 theImage,
                                 minX, minY,
                                 width, height,
                                 periodX, periodY,
                                 bands);
        }
    }

    /**
     * Broadcasts the end of a progressive pass to all
     * registered <code>IIOReadUpdateListener</code>s by calling their
     * <code>passComplete</code> method.  Subclasses may use this
     * method as a convenience.
     *
     * @param theImage the <code>BufferedImage</code> being updated.
     */
    protected void processPassComplete(BufferedImage theImage) {
        if (updateListeners == null) {
            return;
        }
        int numListeners = updateListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadUpdateListener listener =
                (IIOReadUpdateListener)updateListeners.get(i);
            listener.passComplete(this, theImage);
        }
    }

    /**
     * Broadcasts the beginning of a thumbnail progressive pass to all
     * registered <code>IIOReadUpdateListener</code>s by calling their
     * <code>thumbnailPassStarted</code> method.  Subclasses may use this
     * method as a convenience.
     *
     * @param theThumbnail the <code>BufferedImage</code> thumbnail
     * being updated.
     * @param pass the index of the current pass, starting with 0.
     * @param minPass the index of the first pass that will be decoded.
     * @param maxPass the index of the last pass that will be decoded.
     * @param minX the X coordinate of the upper-left pixel included
     * in the pass.
     * @param minY the X coordinate of the upper-left pixel included
     * in the pass.
     * @param periodX the horizontal separation between pixels.
     * @param periodY the vertical separation between pixels.
     * @param bands an array of <code>int</code>s indicating the
     * set of affected bands of the destination.
     */
    protected void processThumbnailPassStarted(BufferedImage theThumbnail,
                                               int pass,
                                               int minPass, int maxPass,
                                               int minX, int minY,
                                               int periodX, int periodY,
                                               int[] bands) {
        if (updateListeners == null) {
            return;
        }
        int numListeners = updateListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadUpdateListener listener =
                (IIOReadUpdateListener)updateListeners.get(i);
            listener.thumbnailPassStarted(this, theThumbnail, pass,
                                          minPass,
                                          maxPass,
                                          minX, minY,
                                          periodX, periodY,
                                          bands);
        }
    }

    /**
     * Broadcasts the update of a set of samples in a thumbnail image
     * to all registered <code>IIOReadUpdateListener</code>s by
     * calling their <code>thumbnailUpdate</code> method.  Subclasses may
     * use this method as a convenience.
     *
     * @param theThumbnail the <code>BufferedImage</code> thumbnail
     * being updated.
     * @param minX the X coordinate of the upper-left pixel included
     * in the pass.
     * @param minY the X coordinate of the upper-left pixel included
     * in the pass.
     * @param width the total width of the area being updated, including
     * pixels being skipped if <code>periodX &gt; 1</code>.
     * @param height the total height of the area being updated,
     * including pixels being skipped if <code>periodY &gt; 1</code>.
     * @param periodX the horizontal separation between pixels.
     * @param periodY the vertical separation between pixels.
     * @param bands an array of <code>int</code>s indicating the
     * set of affected bands of the destination.
     */
    protected void processThumbnailUpdate(BufferedImage theThumbnail,
                                          int minX, int minY,
                                          int width, int height,
                                          int periodX, int periodY,
                                          int[] bands) {
        if (updateListeners == null) {
            return;
        }
        int numListeners = updateListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadUpdateListener listener =
                (IIOReadUpdateListener)updateListeners.get(i);
            listener.thumbnailUpdate(this,
                                     theThumbnail,
                                     minX, minY,
                                     width, height,
                                     periodX, periodY,
                                     bands);
        }
    }

    /**
     * Broadcasts the end of a thumbnail progressive pass to all
     * registered <code>IIOReadUpdateListener</code>s by calling their
     * <code>thumbnailPassComplete</code> method.  Subclasses may use this
     * method as a convenience.
     *
     * @param theThumbnail the <code>BufferedImage</code> thumbnail
     * being updated.
     */
    protected void processThumbnailPassComplete(BufferedImage theThumbnail) {
        if (updateListeners == null) {
            return;
        }
        int numListeners = updateListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadUpdateListener listener =
                (IIOReadUpdateListener)updateListeners.get(i);
            listener.thumbnailPassComplete(this, theThumbnail);
        }
    }

    /**
     * Broadcasts a warning message to all registered
     * <code>IIOReadWarningListener</code>s by calling their
     * <code>warningOccurred</code> method.  Subclasses may use this
     * method as a convenience.
     *
     * @param warning the warning message to send.
     *
     * @exception IllegalArgumentException if <code>warning</code>
     * is <code>null</code>.
     */
    protected void processWarningOccurred(String warning) {
        if (warningListeners == null) {
            return;
        }
        if (warning == null) {
            throw new IllegalArgumentException("warning == null!");
        }
        int numListeners = warningListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadWarningListener listener =
                (IIOReadWarningListener)warningListeners.get(i);

            listener.warningOccurred(this, warning);
        }
    }

    /**
     * Broadcasts a localized warning message to all registered
     * <code>IIOReadWarningListener</code>s by calling their
     * <code>warningOccurred</code> method with a string taken
     * from a <code>ResourceBundle</code>.  Subclasses may use this
     * method as a convenience.
     *
     * @param baseName the base name of a set of
     * <code>ResourceBundle</code>s containing localized warning
     * messages.
     * @param keyword the keyword used to index the warning message
     * within the set of <code>ResourceBundle</code>s.
     *
     * @exception IllegalArgumentException if <code>baseName</code>
     * is <code>null</code>.
     * @exception IllegalArgumentException if <code>keyword</code>
     * is <code>null</code>.
     * @exception IllegalArgumentException if no appropriate
     * <code>ResourceBundle</code> may be located.
     * @exception IllegalArgumentException if the named resource is
     * not found in the located <code>ResourceBundle</code>.
     * @exception IllegalArgumentException if the object retrieved
     * from the <code>ResourceBundle</code> is not a
     * <code>String</code>.
     */
    protected void processWarningOccurred(String baseName,
                                          String keyword) {
        if (warningListeners == null) {
            return;
        }
        if (baseName == null) {
            throw new IllegalArgumentException("baseName == null!");
        }
        if (keyword == null) {
            throw new IllegalArgumentException("keyword == null!");
        }
        int numListeners = warningListeners.size();
        for (int i = 0; i < numListeners; i++) {
            IIOReadWarningListener listener =
                (IIOReadWarningListener)warningListeners.get(i);
            Locale locale = (Locale)warningLocales.get(i);
            if (locale == null) {
                locale = Locale.getDefault();
            }

            /**
             * If an applet supplies an implementation of ImageReader and
             * resource bundles, then the resource bundle will need to be
             * accessed via the applet class loader. So first try the context
             * class loader to locate the resource bundle.
             * If that throws MissingResourceException, then try the
             * system class loader.
             */
            ClassLoader loader = (ClassLoader)
                java.security.AccessController.doPrivileged(
                   new java.security.PrivilegedAction() {
                      public Object run() {
                        return Thread.currentThread().getContextClassLoader();
                      }
                });

            ResourceBundle bundle = null;
            try {
                bundle = ResourceBundle.getBundle(baseName, locale, loader);
            } catch (MissingResourceException mre) {
                try {
                    bundle = ResourceBundle.getBundle(baseName, locale);
                } catch (MissingResourceException mre1) {
                    throw new IllegalArgumentException("Bundle not found!");
                }
            }

            String warning = null;
            try {
                warning = bundle.getString(keyword);
            } catch (ClassCastException cce) {
                throw new IllegalArgumentException("Resource is not a String!");
            } catch (MissingResourceException mre) {
                throw new IllegalArgumentException("Resource is missing!");
            }

            listener.warningOccurred(this, warning);
        }
    }

    // State management

    /**
     * Restores the <code>ImageReader</code> to its initial state.
     *
     * <p> The default implementation calls <code>setInput(null,
     * false)</code>, <code>setLocale(null)</code>,
     * <code>removeAllIIOReadUpdateListeners()</code>,
     * <code>removeAllIIOReadWarningListeners()</code>,
     * <code>removeAllIIOReadProgressListeners()</code>, and
     * <code>clearAbortRequest</code>.
     */
    public void reset() {
        setInput(null, false, false);
        setLocale(null);
        removeAllIIOReadUpdateListeners();
        removeAllIIOReadProgressListeners();
        removeAllIIOReadWarningListeners();
        clearAbortRequest();
    }

    /**
     * Allows any resources held by this object to be released.  The
     * result of calling any other method (other than
     * <code>finalize</code>) subsequent to a call to this method
     * is undefined.
     *
     * <p>It is important for applications to call this method when they
     * know they will no longer be using this <code>ImageReader</code>.
     * Otherwise, the reader may continue to hold on to resources
     * indefinitely.
     *
     * <p>The default implementation of this method in the superclass does
     * nothing.  Subclass implementations should ensure that all resources,
     * especially native resources, are released.
     */
    public void dispose() {
    }

    // Utility methods

    /**
     * A utility method that may be used by readers to compute the
     * region of the source image that should be read, taking into
     * account any source region and subsampling offset settings in
     * the supplied <code>ImageReadParam</code>.  The actual
     * subsampling factors, destination size, and destination offset
     * are <em>not</em> taken into consideration, thus further
     * clipping must take place.  The {@link #computeRegions
     * <code>computeRegions</code>} method performs all necessary
     * clipping.
     *
     * @param param the <code>ImageReadParam</code> being used, or
     * <code>null</code>.
     * @param srcWidth the width of the source image.
     * @param srcHeight the height of the source image.
     *
     * @return the source region as a <code>Rectangle</code>.
     */
    protected static Rectangle getSourceRegion(ImageReadParam param,
                                               int srcWidth,
                                               int srcHeight) {
        Rectangle sourceRegion = new Rectangle(0, 0, srcWidth, srcHeight);
        if (param != null) {
            Rectangle region = param.getSourceRegion();
            if (region != null) {
                sourceRegion = sourceRegion.intersection(region);
            }

            int subsampleXOffset = param.getSubsamplingXOffset();
            int subsampleYOffset = param.getSubsamplingYOffset();
            sourceRegion.x += subsampleXOffset;
            sourceRegion.y += subsampleYOffset;
            sourceRegion.width -= subsampleXOffset;
            sourceRegion.height -= subsampleYOffset;
        }

        return sourceRegion;
    }

    /**
     * Computes the source region of interest and the destination
     * region of interest, taking the width and height of the source
     * image, an optional destination image, and an optional
     * <code>ImageReadParam</code> into account.  The source region
     * begins with the entire source image.  Then that is clipped to
     * the source region specified in the <code>ImageReadParam</code>,
     * if one is specified.
     *
     * <p> If either of the destination offsets are negative, the
     * source region is clipped so that its top left will coincide
     * with the top left of the destination image, taking subsampling
     * into account.  Then the result is clipped to the destination
     * image on the right and bottom, if one is specified, taking
     * subsampling and destination offsets into account.
     *
     * <p> Similarly, the destination region begins with the source
     * image, is translated to the destination offset given in the
     * <code>ImageReadParam</code> if there is one, and finally is
     * clipped to the destination image, if there is one.
     *
     * <p> If either the source or destination regions end up having a
     * width or height of 0, an <code>IllegalArgumentException</code>
     * is thrown.
     *
     * <p> The {@link #getSourceRegion <code>getSourceRegion</code>}
     * method may be used if only source clipping is desired.
     *
     * @param param an <code>ImageReadParam</code>, or <code>null</code>.
     * @param srcWidth the width of the source image.
     * @param srcHeight the height of the source image.
     * @param image a <code>BufferedImage</code> that will be the
     * destination image, or <code>null</code>.
     * @param srcRegion a <code>Rectangle</code> that will be filled with
     * the source region of interest.
     * @param destRegion a <code>Rectangle</code> that will be filled with
     * the destination region of interest.
     * @exception IllegalArgumentException if <code>srcRegion</code>
     * is <code>null</code>.
     * @exception IllegalArgumentException if <code>dstRegion</code>
     * is <code>null</code>.
     * @exception IllegalArgumentException if the resulting source or
     * destination region is empty.
     */
    protected static void computeRegions(ImageReadParam param,
                                         int srcWidth,
                                         int srcHeight,
                                         BufferedImage image,
                                         Rectangle srcRegion,
                                         Rectangle destRegion) {
        if (srcRegion == null) {
            throw new IllegalArgumentException("srcRegion == null!");
        }
        if (destRegion == null) {
            throw new IllegalArgumentException("destRegion == null!");
        }

        // Start with the entire source image
        srcRegion.setBounds(0, 0, srcWidth, srcHeight);

        // Destination also starts with source image, as that is the
        // maximum extent if there is no subsampling
        destRegion.setBounds(0, 0, srcWidth, srcHeight);

        // Clip that to the param region, if there is one
        int periodX = 1;
        int periodY = 1;
        int gridX = 0;
        int gridY = 0;
        if (param != null) {
            Rectangle paramSrcRegion = param.getSourceRegion();
            if (paramSrcRegion != null) {
                srcRegion.setBounds(srcRegion.intersection(paramSrcRegion));
            }
            periodX = param.getSourceXSubsampling();
            periodY = param.getSourceYSubsampling();
            gridX = param.getSubsamplingXOffset();
            gridY = param.getSubsamplingYOffset();
            srcRegion.translate(gridX, gridY);
            srcRegion.width -= gridX;
            srcRegion.height -= gridY;
            destRegion.setLocation(param.getDestinationOffset());
        }

        // Now clip any negative destination offsets, i.e. clip
        // to the top and left of the destination image
        if (destRegion.x < 0) {
            int delta = -destRegion.x*periodX;
            srcRegion.x += delta;
            srcRegion.width -= delta;
            destRegion.x = 0;
        }
        if (destRegion.y < 0) {
            int delta = -destRegion.y*periodY;
            srcRegion.y += delta;
            srcRegion.height -= delta;
            destRegion.y = 0;
        }

        // Now clip the destination Region to the subsampled width and height
        int subsampledWidth = (srcRegion.width + periodX - 1)/periodX;
        int subsampledHeight = (srcRegion.height + periodY - 1)/periodY;
        destRegion.width = subsampledWidth;
        destRegion.height = subsampledHeight;

        // Now clip that to right and bottom of the destination image,
        // if there is one, taking subsampling into account
        if (image != null) {
            Rectangle destImageRect = new Rectangle(0, 0,
                                                    image.getWidth(),
                                                    image.getHeight());
            destRegion.setBounds(destRegion.intersection(destImageRect));
            if (destRegion.isEmpty()) {
                throw new IllegalArgumentException
                    ("Empty destination region!");
            }

            int deltaX = destRegion.x + subsampledWidth - image.getWidth();
            if (deltaX > 0) {
                srcRegion.width -= deltaX*periodX;
            }
            int deltaY =  destRegion.y + subsampledHeight - image.getHeight();
            if (deltaY > 0) {
                srcRegion.height -= deltaY*periodY;
            }
        }
        if (srcRegion.isEmpty() || destRegion.isEmpty()) {
            throw new IllegalArgumentException("Empty region!");
        }
    }

    /**
     * A utility method that may be used by readers to test the
     * validity of the source and destination band settings of an
     * <code>ImageReadParam</code>.  This method may be called as soon
     * as the reader knows both the number of bands of the source
     * image as it exists in the input stream, and the number of bands
     * of the destination image that being written.
     *
     * <p> The method retrieves the source and destination band
     * setting arrays from param using the <code>getSourceBands</code>
     * and <code>getDestinationBands</code>methods (or considers them
     * to be <code>null</code> if <code>param</code> is
     * <code>null</code>).  If the source band setting array is
     * <code>null</code>, it is considered to be equal to the array
     * <code>{ 0, 1, ..., numSrcBands - 1 }</code>, and similarly for
     * the destination band setting array.
     *
     * <p> The method then tests that both arrays are equal in length,
     * and that neither array contains a value larger than the largest
     * available band index.
     *
     * <p> Any failure results in an
     * <code>IllegalArgumentException</code> being thrown; success
     * results in the method returning silently.
     *
     * @param param the <code>ImageReadParam</code> being used to read
     * the image.
     * @param numSrcBands the number of bands of the image as it exists
     * int the input source.
     * @param numDstBands the number of bands in the destination image
     * being written.
     *
     * @exception IllegalArgumentException if <code>param</code>
     * contains an invalid specification of a source and/or
     * destination band subset.
     */
    protected static void checkReadParamBandSettings(ImageReadParam param,
                                                     int numSrcBands,
                                                     int numDstBands) {
        // A null param is equivalent to srcBands == dstBands == null.
        int[] srcBands = null;
        int[] dstBands = null;
        if (param != null) {
            srcBands = param.getSourceBands();
            dstBands = param.getDestinationBands();
        }

        int paramSrcBandLength =
            (srcBands == null) ? numSrcBands : srcBands.length;
        int paramDstBandLength =
            (dstBands == null) ? numDstBands : dstBands.length;

        if (paramSrcBandLength != paramDstBandLength) {
            throw new IllegalArgumentException("ImageReadParam num source & dest bands differ!");
        }

        if (srcBands != null) {
            for (int i = 0; i < srcBands.length; i++) {
                if (srcBands[i] >= numSrcBands) {
                    throw new IllegalArgumentException("ImageReadParam source bands contains a value >= the number of source bands!");
                }
            }
        }

        if (dstBands != null) {
            for (int i = 0; i < dstBands.length; i++) {
                if (dstBands[i] >= numDstBands) {
                    throw new IllegalArgumentException("ImageReadParam dest bands contains a value >= the number of dest bands!");
                }
            }
        }
    }

    /**
     * Returns the <code>BufferedImage</code> to which decoded pixel
     * data should be written.  The image is determined by inspecting
     * the supplied <code>ImageReadParam</code> if it is
     * non-<code>null</code>; if its <code>getDestination</code>
     * method returns a non-<code>null</code> value, that image is
     * simply returned.  Otherwise,
     * <code>param.getDestinationType</code> method is called to
     * determine if a particular image type has been specified.  If
     * so, the returned <code>ImageTypeSpecifier</code> is used after
     * checking that it is equal to one of those included in
     * <code>imageTypes</code>.
     *
     * <p> If <code>param</code> is <code>null</code> or the above
     * steps have not yielded an image or an
     * <code>ImageTypeSpecifier</code>, the first value obtained from
     * the <code>imageTypes</code> parameter is used.  Typically, the
     * caller will set <code>imageTypes</code> to the value of
     * <code>getImageTypes(imageIndex)</code>.
     *
     * <p> Next, the dimensions of the image are determined by a call
     * to <code>computeRegions</code>.  The actual width and height of
     * the image being decoded are passed in as the <code>width</code>
     * and <code>height</code> parameters.
     *
     * @param param an <code>ImageReadParam</code> to be used to get
     * the destination image or image type, or <code>null</code>.
     * @param imageTypes an <code>Iterator</code> of
     * <code>ImageTypeSpecifier</code>s indicating the legal image
     * types, with the default first.
     * @param width the true width of the image or tile begin decoded.
     * @param height the true width of the image or tile being decoded.
     *
     * @return the <code>BufferedImage</code> to which decoded pixel
     * data should be written.
     *
     * @exception IIOException if the <code>ImageTypeSpecifier</code>
     * specified by <code>param</code> does not match any of the legal
     * ones from <code>imageTypes</code>.
     * @exception IllegalArgumentException if <code>imageTypes</code>
     * is <code>null</code> or empty, or if an object not of type
     * <code>ImageTypeSpecifier</code> is retrieved from it.
     * @exception IllegalArgumentException if the resulting image would
     * have a width or height less than 1.
     * @exception IllegalArgumentException if the product of
     * <code>width</code> and <code>height</code> is greater than
     * <code>Integer.MAX_VALUE</code>.
     */
    protected static BufferedImage
        getDestination(ImageReadParam param,
                       Iterator<ImageTypeSpecifier> imageTypes,
                       int width, int height)
        throws IIOException {
        if (imageTypes == null || !imageTypes.hasNext()) {
            throw new IllegalArgumentException("imageTypes null or empty!");
        }
        if ((long)width*height > Integer.MAX_VALUE) {
            throw new IllegalArgumentException
                ("width*height > Integer.MAX_VALUE!");
        }

        BufferedImage dest = null;
        ImageTypeSpecifier imageType = null;

        // If param is non-null, use it
        if (param != null) {
            // Try to get the image itself
            dest = param.getDestination();
            if (dest != null) {
                return dest;
            }

            // No image, get the image type
            imageType = param.getDestinationType();
        }

        // No info from param, use fallback image type
        if (imageType == null) {
            Object o = imageTypes.next();
            if (!(o instanceof ImageTypeSpecifier)) {
                throw new IllegalArgumentException
                    ("Non-ImageTypeSpecifier retrieved from imageTypes!");
            }
            imageType = (ImageTypeSpecifier)o;
        } else {
            boolean foundIt = false;
            while (imageTypes.hasNext()) {
                ImageTypeSpecifier type =
                    (ImageTypeSpecifier)imageTypes.next();
                if (type.equals(imageType)) {
                    foundIt = true;
                    break;
                }
            }

            if (!foundIt) {
                throw new IIOException
                    ("Destination type from ImageReadParam does not match!");
            }
        }

        Rectangle srcRegion = new Rectangle(0,0,0,0);
        Rectangle destRegion = new Rectangle(0,0,0,0);
        computeRegions(param,
                       width,
                       height,
                       null,
                       srcRegion,
                       destRegion);

        int destWidth = destRegion.x + destRegion.width;
        int destHeight = destRegion.y + destRegion.height;
        // Create a new image based on the type specifier
        return imageType.createBufferedImage(destWidth, destHeight);
    }
}
