/* ImageReader.java -- Decodes raster images.
   Copyright (C) 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


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.ResourceBundle;
import java.util.MissingResourceException;
import java.util.Set;

import javax.imageio.event.IIOReadProgressListener;
import javax.imageio.event.IIOReadUpdateListener;
import javax.imageio.event.IIOReadWarningListener;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;

/**
 * A class for decoding images within the ImageIO framework.
 *
 * An ImageReader for a given format is instantiated by an
 * ImageReaderSpi for that format.  ImageReaderSpis are registered
 * with the IIORegistry.
 *
 * The ImageReader API supports reading animated images that may have
 * multiple frames; to support such images many methods take an index
 * parameter.
 *
 * Images may also be read in multiple passes, where each successive
 * pass increases the level of detail in the destination image.
 */
public abstract class ImageReader
{
  private boolean aborted;

  /**
   * All locales available for localization of warning messages, or
   * null if localization is not supported.
   */
  protected Locale[] availableLocales = null;

  /**
   * true if the input source does not require metadata to be read,
   * false otherwise.
   */
  protected boolean ignoreMetadata = false;

  /**
   * An ImageInputStream from which image data is read.
   */
  protected Object input = null;

  /**
   * The current locale used to localize warning messages, or null if
   * no locale has been set.
   */
  protected Locale locale = null;

  /**
   * The minimum index at which data can be read.  Constantly 0 if
   * seekForwardOnly is false, always increasing if seekForwardOnly is
   * true.
   */
  protected int minIndex = 0;

  /**
   * The image reader SPI that instantiated this reader.
   */
  protected ImageReaderSpi originatingProvider = null;

  /**
   * A list of installed progress listeners.  Initially null, meaning
   * no installed listeners.
   */
  protected List<IIOReadProgressListener> progressListeners = null;

  /**
   * true if this reader should only read data further ahead in the
   * stream than its current location.  false if it can read backwards
   * in the stream.  If this is true then caching can be avoided.
   */
  protected boolean seekForwardOnly = false;

  /**
   * A list of installed update listeners.  Initially null, meaning no
   * installed listeners.
   */
  protected List<IIOReadUpdateListener> updateListeners = null;

  /**
   * A list of installed warning listeners.  Initially null, meaning
   * no installed listeners.
   */
  protected List<IIOReadWarningListener> warningListeners = null;

  /**
   * A list of warning locales corresponding with the list of
   * installed warning listeners.  Initially null, meaning no locales.
   */
  protected List<Locale> warningLocales = null;

  /**
   * Construct an image reader.
   *
   * @param originatingProvider the provider that is constructing this
   * image reader, or null
   */
  protected ImageReader(ImageReaderSpi originatingProvider)
  {
    this.originatingProvider = originatingProvider;
  }

  /**
   * Request that reading be aborted.  The unread contents of the
   * image will be undefined.
   *
   * Readers should clear the abort flag before starting a read
   * operation, then poll it periodically during the read operation.
   */
  public void abort()
  {
    aborted = true;
  }

  /**
   * Check if the abort flag is set.
   *
   * @return true if the current read operation should be aborted,
   * false otherwise
   */
  protected boolean abortRequested()
  {
    return aborted;
  }

  /**
   * Install a read progress listener.  This method will return
   * immediately if listener is null.
   *
   * @param listener a read progress listener or null
   */
  public void addIIOReadProgressListener(IIOReadProgressListener listener)
  {
    if (listener == null)
      return;
    if (progressListeners == null)
      progressListeners = new ArrayList ();
    progressListeners.add(listener);
  }

  /**
   * Install a read update listener.  This method will return
   * immediately if listener is null.
   *
   * @param listener a read update listener
   */
  public void addIIOReadUpdateListener(IIOReadUpdateListener listener)
  {
    if (listener == null)
      return;
    if (updateListeners == null)
      updateListeners = new ArrayList ();
    updateListeners.add(listener);
  }

  /**
   * Install a read warning listener.  This method will return
   * immediately if listener is null.  Warning messages sent to this
   * listener will be localized using the current locale.  If the
   * current locale is null then this reader will select a sensible
   * default.
   *
   * @param listener a read warning listener
   */
  public void addIIOReadWarningListener(IIOReadWarningListener listener)
  {
    if (listener == null)
      return;
    if (warningListeners == null)
      warningListeners = new ArrayList ();
    warningListeners.add(listener);
  }

  /**
   * Check if this reader can handle raster data.  Determines whether
   * or not readRaster and readTileRaster throw
   * UnsupportedOperationException.
   *
   * @return true if this reader supports raster data, false if not
   */
  public boolean canReadRaster()
  {
    return false;
  }

  /**
   * Clear the abort flag.
   */
  protected void clearAbortRequest()
  {
    aborted = false;
  }

  /**
   * Releases any resources allocated to this object.  Subsequent
   * calls to methods on this object will produce undefined results.
   *
   * The default implementation does nothing; subclasses should use
   * this method ensure that native resources are released.
   */
  public void dispose()
  {
    // The default implementation does nothing.
  }

  /**
   * Returns the aspect ratio of this image, the ration of its width
   * to its height.  The aspect ratio is useful when resizing an image
   * while keeping its proportions constant.
   *
   * @param imageIndex the frame index
   *
   * @return the image's aspect ratio
   *
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public float getAspectRatio(int imageIndex)
    throws IOException
  {
    if (input == null)
      throw new IllegalStateException("input is null");

    return (float) (getWidth(imageIndex) / getHeight(imageIndex));
  }

  /**
   * Retrieve the available locales.  Return null if no locales are
   * available or a clone of availableLocales.
   *
   * @return an array of locales or null
   */
  public Locale[] getAvailableLocales()
  {
    if (availableLocales == null)
      return null;
    
    return (Locale[]) availableLocales.clone();
  }

  /**
   * Retrieve the default read parameters for this reader's image
   * format.
   *
   * The default implementation returns new ImageReadParam().
   *
   * @return image reading parameters
   */
  public ImageReadParam getDefaultReadParam()
  {
    return new ImageReadParam();
  }

  /**
   * Retrieve the format of the input source.
   *
   * @return the input source format name
   *
   * @exception IOException if a read error occurs
   */
  public String getFormatName()
    throws IOException
  {
    return originatingProvider.getFormatNames()[0];
  }

  /**
   * Get the height of the input image in pixels.  If the input image
   * is resizable then a default height is returned.
   *
   * @param imageIndex the frame index
   *
   * @return the height of the input image
   *
   * @exception IllegalStateException if input has not been set
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public abstract int getHeight(int imageIndex)
    throws IOException;

  /**
   * Get the metadata associated with this image.  If the reader is
   * set to ignore metadata or does not support reading metadata, or
   * if no metadata is available then null is returned.
   *
   * @param imageIndex the frame index
   *
   * @return a metadata object, or null
   *
   * @exception IllegalStateException if input has not been set
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public abstract IIOMetadata getImageMetadata(int imageIndex)
    throws IOException;

  /**
   * Get an iterator over the collection of image types into which
   * this reader can decode image data.  This method is guaranteed to
   * return at least one valid image type specifier.
   *
   * The elements of the iterator should be ordered; the first element
   * should be the most appropriate image type for this decoder,
   * followed by the second-most appropriate, and so on.
   *
   * @param imageIndex the frame index
   *
   * @return an iterator over a collection of image type specifiers
   *
   * @exception IllegalStateException if input has not been set
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public abstract Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex)
    throws IOException;

  /**
   * Set the input source to the given object, specify whether this
   * reader should be allowed to read input from the data stream more
   * than once, and specify whether this reader should ignore metadata
   * in the input stream.  The input source must be set before many
   * methods can be called on this reader. (see all ImageReader
   * methods that throw IllegalStateException).  If input is null then
   * the current input source will be removed.
   *
   * Unless this reader has direct access with imaging hardware, input
   * should be an ImageInputStream.
   *
   * @param input the input source object
   * @param seekForwardOnly true if this reader should be allowed to
   * read input from the data stream more than once, false otherwise
   * @param ignoreMetadata true if this reader should ignore metadata
   * associated with the input source, false otherwise
   *
   * @exception IllegalArgumentException if input is not a valid input
   * source for this reader and is not an ImageInputStream
   */
  public void setInput(Object input,
                       boolean seekForwardOnly,
                       boolean ignoreMetadata)
  {
    Class[] okClasses = originatingProvider.getInputTypes();
    if (okClasses == null)
      {
        if (!(input instanceof ImageInputStream))
          throw new IllegalArgumentException();
      }
    else
      {
        boolean classOk = false;
        for (int i = 0; i < okClasses.length; ++i)
          if (okClasses[i].isInstance(input))
            classOk = true;
        if (!classOk)
          throw new IllegalArgumentException();
      }

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

  /**
   * Set the input source to the given object and specify whether this
   * reader should be allowed to read input from the data stream more
   * than once.  The input source must be set before many methods can
   * be called on this reader. (see all ImageReader methods that throw
   * IllegalStateException).  If input is null then the current input
   * source will be removed.
   *
   * @param in the input source object
   * @param seekForwardOnly true if this reader should be allowed to
   * read input from the data stream more than once, false otherwise
   *
   * @exception IllegalArgumentException if input is not a valid input
   * source for this reader and is not an ImageInputStream
   */
  public void setInput(Object in, boolean seekForwardOnly)
  {
    setInput(in, seekForwardOnly, false);
  }

  /**
   * Set the input source to the given object.  The input source must
   * be set before many methods can be called on this reader. (see all
   * ImageReader methods that throw IllegalStateException).  If input
   * is null then the current input source will be removed.
   *
   * @param input the input source object
   *
   * @exception IllegalArgumentException if input is not a valid input
   * source for this reader and is not an ImageInputStream
   */
  public void setInput(Object input)
  {
    setInput(input, false, false);
  }

  /**
   * Get this reader's image input source.  null is returned if the
   * image source has not been set.
   *
   * @return an image input source object, or null
   */
  public Object getInput()
  {
    return input;
  }

  /**
   * Get this reader's locale.  null is returned if the locale has not
   * been set.
   *
   * @return this reader's locale, or null
   */
  public Locale getLocale()
  {
    return locale;
  }

  /**
   * Return the number of images available from the image input
   * source, not including thumbnails.  This method will return 1
   * unless this reader is reading an animated image.
   *
   * Certain multi-image formats do not encode the total number of
   * images.  When reading images in those formats it may be necessary
   * to repeatedly call read, incrementing the image index at each
   * call, until an IndexOutOfBoundsException is thrown.
   *
   * The allowSearch parameter determines whether all images must be
   * available at all times.  When allowSearch is false, getNumImages
   * will return -1 if the total number of images is unknown.
   * Otherwise this method returns the number of images.
   *
   * @param allowSearch true if all images should be available at
   * once, false otherwise
   *
   * @return -1 if allowSearch is false and the total number of images
   * is currently unknown, or the number of images
   *
   * @exception IllegalStateException if input has not been set, or if
   * seekForwardOnly is true
   * @exception IOException if a read error occurs
   */
  public abstract int getNumImages(boolean allowSearch)
    throws IOException;

  /**
   * Get the number of thumbnails associated with an image.
   *
   * @param imageIndex the frame index
   *
   * @return the number of thumbnails associated with this image
   */
  public int getNumThumbnails(int imageIndex)
    throws IOException
  {
    return 0;
  }

  /**
   * Get the ImageReaderSpi that created this reader or null.
   *
   * @return an ImageReaderSpi, or null
   */
  public ImageReaderSpi getOriginatingProvider()
  {
    return originatingProvider;
  }

  /**
   * Get the metadata associated with the image being read.  If the
   * reader is set to ignore metadata or does not support reading
   * metadata, or if no metadata is available then null is returned.
   * This method returns metadata associated with the entirety of the
   * image data, whereas getImageMetadata(int) returns metadata
   * associated with a frame within a multi-image data stream.
   *
   * @return metadata associated with the image being read, or null
   *
   * @exception IOException if a read error occurs
   */
  public abstract IIOMetadata getStreamMetadata()
    throws IOException;

  /**
   * Get the height of a thumbnail image.
   *
   * @param imageIndex the frame index
   * @param thumbnailIndex the thumbnail index
   *
   * @return the height of the thumbnail image
   *
   * @exception UnsupportedOperationException if this reader does not
   * support thumbnails
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if either index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public int getThumbnailHeight(int imageIndex, int thumbnailIndex)
    throws IOException
  {
    return readThumbnail(imageIndex, thumbnailIndex).getHeight();
  }

  /**
   * Get the width of a thumbnail image.
   *
   * @param imageIndex the frame index
   * @param thumbnailIndex the thumbnail index
   *
   * @return the width of the thumbnail image
   *
   * @exception UnsupportedOperationException if this reader does not
   * support thumbnails
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if either index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public int getThumbnailWidth(int imageIndex, int thumbnailIndex)
    throws IOException
  {
    return readThumbnail(imageIndex, thumbnailIndex).getWidth();
  }

  /**
   * Get the X coordinate in pixels of the top-left corner of the
   * first tile in this image.
   *
   * @param imageIndex the frame index
   *
   * @return the X coordinate of this image's first tile
   *
   * @exception IllegalStateException if input is needed but the input
   * source is not set
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public int getTileGridXOffset(int imageIndex)
    throws IOException
  {
    return 0;
  }

  /**
   * Get the Y coordinate in pixels of the top-left corner of the
   * first tile in this image.
   *
   * @param imageIndex the frame index
   *
   * @return the Y coordinate of this image's first tile
   *
   * @exception IllegalStateException if input is needed but the input
   * source is not set
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public int getTileGridYOffset(int imageIndex)
    throws IOException
  {
    return 0;
  }

  /**
   * Get the height of an image tile.
   *
   * @param imageIndex the frame index
   *
   * @return the tile height for the given image
   *
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public int getTileHeight(int imageIndex)
    throws IOException
  {
    return getHeight(imageIndex);
  }

  /**
   * Get the width of an image tile.
   *
   * @param imageIndex the frame index
   *
   * @return the tile width for the given image
   *
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public int getTileWidth(int imageIndex)
    throws IOException
  {
    return getWidth(imageIndex);
  }

  /**
   * Get the width of the input image in pixels.  If the input image
   * is resizable then a default width is returned.
   *
   * @param imageIndex the image's index
   *
   * @return the width of the input image
   *
   * @exception IllegalStateException if input has not been set
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public abstract int getWidth(int imageIndex)
    throws IOException;

  /**
   * Check whether or not the given image has thumbnails associated
   * with it.
   *
   * @return true if the given image has thumbnails, false otherwise
   *
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public boolean hasThumbnails(int imageIndex)
    throws IOException
  {
    return getNumThumbnails(imageIndex) > 0;
  }

  /**
   * Check if this image reader ignores metadata.  This method simply
   * returns the value of ignoreMetadata.
   *
   * @return true if metadata is being ignored, false otherwise
   */
  public boolean isIgnoringMetadata()
  {
    return ignoreMetadata;
  }

  /**
   * Check if the given image is sub-divided into equal-sized
   * non-overlapping pixel rectangles.
   *
   * A reader may expose tiling in the underlying format, hide it, or
   * simulate tiling even if the underlying format is not tiled.
   *
   * @return true if the given image is tiled, false otherwise
   *
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public boolean isImageTiled(int imageIndex)
    throws IOException
  {
    return false;
  }

  /**
   * Check if all pixels in this image are readily accessible.  This
   * method should return false for compressed formats.  The return
   * value is a hint as to the efficiency of certain image reader
   * operations.
   *
   * @param imageIndex the frame index
   *
   * @return true if random pixel access is fast, false otherwise
   *
   * @exception IllegalStateException if input is null and it is
   * needed to determine the return value
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds but the frame data must be accessed to determine
   * the return value
   * @exception IOException if a read error occurs
   */
  public boolean isRandomAccessEasy(int imageIndex)
    throws IOException
  {
    return false;
  }

  /**
   * Check if this image reader may only seek forward within the input
   * stream.
   *
   * @return true if this reader may only seek forward, false
   * otherwise
   */
  public boolean isSeekForwardOnly()
  {
    return seekForwardOnly;
  }

  /**
   * Notifies all installed read progress listeners that image loading
   * has completed by calling their imageComplete methods.
   */
  protected void processImageComplete()
  {
    if (progressListeners != null)
      {
	Iterator it = progressListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadProgressListener listener =
	      (IIOReadProgressListener) it.next();
	    listener.imageComplete (this);
	  }
      }
  }

  /**
   * Notifies all installed read progress listeners that a certain
   * percentage of the image has been loaded, by calling their
   * imageProgress methods.
   *
   * @param percentageDone the percentage of image data that has been
   * loaded
   */
  protected void processImageProgress(float percentageDone)
  {
     if (progressListeners != null)
      {
	Iterator it = progressListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadProgressListener listener =
	      (IIOReadProgressListener) it.next();
	    listener.imageProgress(this, percentageDone);
	  }
      }
  }
  /**
   * Notifies all installed read progress listeners, by calling their
   * imageStarted methods, that image loading has started on the given
   * image.
   *
   * @param imageIndex the frame index of the image that has started
   * loading
   */
  protected void processImageStarted(int imageIndex)
  {
     if (progressListeners != null)
      {
	Iterator it = progressListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadProgressListener listener =
	      (IIOReadProgressListener) it.next();
	    listener.imageStarted(this, imageIndex);
	  }
      }
  }

  /**
   * Notifies all installed read update listeners, by calling their
   * imageUpdate methods, that the set of samples has changed.
   *
   * @param image the buffered image that is being updated
   * @param minX the X coordinate of the top-left pixel in this pass
   * @param minY the Y coordinate of the top-left pixel in this pass
   * @param width the total width of the rectangle covered by this
   * pass, including skipped pixels
   * @param height the total height of the rectangle covered by this
   * pass, including skipped pixels
   * @param periodX the horizontal sample interval
   * @param periodY the vertical sample interval
   * @param bands the affected bands in the destination
   */
  protected void processImageUpdate(BufferedImage image, int minX, int minY,
				    int width, int height, int periodX,
				    int periodY, int[] bands)
  {
    if (updateListeners != null)
      {
	Iterator it = updateListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
	    listener.imageUpdate(this, image, minX, minY, width, height,
				 periodX, periodY, bands);
	  }
      }
  }

  /**
   * Notifies all installed update progress listeners, by calling
   * their passComplete methods, that a progressive pass has
   * completed.
   *
   * @param image the image that has being updated
   */
  protected void processPassComplete(BufferedImage image)
  {
    if (updateListeners != null)
      {
	Iterator it = updateListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
	    listener.passComplete(this, image);
	  }
      }
  }

  /**
   * Notifies all installed read update listeners, by calling their
   * passStarted methods, that a new pass has begun.
   *
   * @param image the buffered image that is being updated
   * @param pass the current pass number
   * @param minPass the pass at which decoding will begin
   * @param maxPass the pass at which decoding will end
   * @param minX the X coordinate of the top-left pixel in this pass
   * @param minY the Y coordinate of the top-left pixel in this pass
   * @param width the total width of the rectangle covered by this
   * pass, including skipped pixels
   * @param height the total height of the rectangle covered by this
   * pass, including skipped pixels
   * @param periodX the horizontal sample interval
   * @param periodY the vertical sample interval
   * @param bands the affected bands in the destination
   */
  protected void processPassStarted(BufferedImage image, int pass, int minPass,
				    int maxPass, int minX, int minY,
				    int periodX, int periodY, int[] bands)
  {
    if (updateListeners != null)
      {
	Iterator it = updateListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
	    listener.passStarted(this, image, pass, minPass, maxPass, minX,
				 minY, periodX, periodY, bands);
	  }
      }
  }

  /**
   * Notifies all installed read progress listeners that image loading
   * has been aborted by calling their readAborted methods.
   */
  protected void processReadAborted()
  {
     if (progressListeners != null)
      {
	Iterator it = progressListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadProgressListener listener =
	      (IIOReadProgressListener) it.next();
	    listener.readAborted(this);
	  }
      }
  }
  /**
   * Notifies all installed read progress listeners, by calling their
   * sequenceComplete methods, that a sequence of images has completed
   * loading.
   */
  protected void processSequenceComplete()
  {
     if (progressListeners != null)
      {
	Iterator it = progressListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadProgressListener listener =
	      (IIOReadProgressListener) it.next();
	    listener.sequenceComplete(this);
	  }
      }
  }

  /**
   * Notifies all installed read progress listeners, by calling their
   * sequenceStarted methods, a sequence of images has started
   * loading.
   *
   * @param minIndex the index of the first image in the sequence
   */
  protected void processSequenceStarted(int minIndex)
  {

    if (progressListeners != null)
      {
	Iterator it = progressListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadProgressListener listener =
	      (IIOReadProgressListener) it.next();
	    listener.sequenceStarted(this, minIndex);
	  }
      }
  }

  /**
   * Notifies all installed read progress listeners, by calling their
   * thumbnailComplete methods, that a thumbnail has completed
   * loading.
   */
  protected void processThumbnailComplete()
  {
    if (progressListeners != null)
      {
	Iterator it = progressListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadProgressListener listener =
	      (IIOReadProgressListener) it.next();
	    listener.thumbnailComplete(this);
	  }
      }
  }

  /**
   * Notifies all installed update progress listeners, by calling
   * their thumbnailPassComplete methods, that a progressive pass has
   * completed on a thumbnail.
   *
   * @param thumbnail the thumbnail that has being updated
   */
  protected void processThumbnailPassComplete(BufferedImage thumbnail)
  {
    if (updateListeners != null)
      {
	Iterator it = updateListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
	    listener.thumbnailPassComplete(this, thumbnail);
	  }
      }
  }

  /**
   * Notifies all installed read update listeners, by calling their
   * thumbnailPassStarted methods, that a new pass has begun.
   *
   * @param thumbnail the thumbnail that is being updated
   * @param pass the current pass number
   * @param minPass the pass at which decoding will begin
   * @param maxPass the pass at which decoding will end
   * @param minX the X coordinate of the top-left pixel in this pass
   * @param minY the Y coordinate of the top-left pixel in this pass
   * @param width the total width of the rectangle covered by this
   * pass, including skipped pixels
   * @param height the total height of the rectangle covered by this
   * pass, including skipped pixels
   * @param periodX the horizontal sample interval
   * @param periodY the vertical sample interval
   * @param bands the affected bands in the destination
   */
  protected void processThumbnailPassStarted(BufferedImage thumbnail, int pass,
					     int minPass, int maxPass, int minX,
					     int minY, int periodX, int periodY,
					     int[] bands)
  {
    if (updateListeners != null)
      {
	Iterator it = updateListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
	    listener.thumbnailPassStarted(this, thumbnail, pass, minPass,
					  maxPass, minX, minY, periodX,
					  periodY, bands);
	  }
      }
  }

  /**
   * Notifies all installed read progress listeners that a certain
   * percentage of a thumbnail has been loaded, by calling their
   * thumbnailProgress methods.
   *
   * @param percentageDone the percentage of thumbnail data that has
   * been loaded
   */
  protected void processThumbnailProgress(float percentageDone)
  {
    if (progressListeners != null)
      {
	Iterator it = progressListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadProgressListener listener =
	      (IIOReadProgressListener) it.next();
	    listener.thumbnailProgress(this, percentageDone);
	  }
      }
  }

  /**
   * Notifies all installed read progress listeners, by calling their
   * imageStarted methods, that thumbnail loading has started on the
   * given thumbnail of the given image.
   *
   * @param imageIndex the frame index of the image one of who's
   * thumbnails has started loading
   * @param thumbnailIndex the index of the thumbnail that has started
   * loading
   */
  protected void processThumbnailStarted(int imageIndex, int thumbnailIndex)
  {
    if (progressListeners != null)
      {
	Iterator it = progressListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadProgressListener listener =
	      (IIOReadProgressListener) it.next();
	    listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
	  }
      }
  }

  /**
   * Notifies all installed read update listeners, by calling their
   * thumbnailUpdate methods, that the set of samples has changed.
   *
   * @param image the buffered image that is being updated
   * @param minX the X coordinate of the top-left pixel in this pass
   * @param minY the Y coordinate of the top-left pixel in this pass
   * @param width the total width of the rectangle covered by this
   * pass, including skipped pixels
   * @param height the total height of the rectangle covered by this
   * pass, including skipped pixels
   * @param periodX the horizontal sample interval
   * @param periodY the vertical sample interval
   * @param bands the affected bands in the destination
   */
  protected void processThumbnailUpdate(BufferedImage image, int minX, int minY,
					int width, int height, int periodX,
					int periodY, int[] bands)
  {
    if (updateListeners != null)
      {
	Iterator it = updateListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
	    listener.thumbnailUpdate(this, image, minX, minY, width, height,
				     periodX, periodY, bands);
	  }
      }
  }

  /**
   * Notifies all installed warning listeners, by calling their
   * warningOccurred methods, that a warning message has been raised.
   *
   * @param warning the warning message
   *
   * @exception IllegalArgumentException if warning is null
   */
  protected void processWarningOccurred(String warning)
  {
    if (warning == null)
      throw new IllegalArgumentException ("null argument");
    if (warningListeners != null)
      {
	Iterator it = warningListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadWarningListener listener =
	      (IIOReadWarningListener) it.next();
	    listener.warningOccurred(this, warning);
	  }
      }
  }

  /**
   * Notify all installed warning listeners, by calling their
   * warningOccurred methods, that a warning message has been raised.
   * The warning message is retrieved from a resource bundle, using
   * the given basename and keyword.
   *
   * @param baseName the basename of the resource from which to
   * retrieve the warning message
   * @param keyword the keyword used to retrieve the warning from the
   * resource bundle
   *
   * @exception IllegalArgumentException if either baseName or keyword
   * is null
   * @exception IllegalArgumentException if no resource bundle is
   * found using baseName
   * @exception IllegalArgumentException if the given keyword produces
   * no results from the resource bundle
   * @exception IllegalArgumentException if the retrieved object is
   * not a String
   */
  protected void processWarningOccurred(String baseName,
					String keyword)
  {
    if (baseName == null || keyword == null)
      throw new IllegalArgumentException ("null argument");

    ResourceBundle b = null;

    try
      {
	b = ResourceBundle.getBundle(baseName, getLocale());
      }
    catch (MissingResourceException e)
      {
	throw new IllegalArgumentException ("no resource bundle found");
      }

    Object str = null;

    try
      {
	str = b.getObject(keyword);
      }
    catch (MissingResourceException e)
      {
	throw new IllegalArgumentException ("no results found for keyword");
      }

    if (! (str instanceof String))
      throw new IllegalArgumentException ("retrieved object not a String");

    String warning = (String) str;

    if (warningListeners != null)
      {
	Iterator it = warningListeners.iterator();

	while (it.hasNext())
	  {
	    IIOReadWarningListener listener =
	      (IIOReadWarningListener) it.next();
	    listener.warningOccurred(this, warning);
	  }
      }
  }

  /**
   * Read the given frame into a buffered image using the given read
   * parameters.  Listeners will be notified of image loading progress
   * and warnings.
   *
   * @param imageIndex the index of the frame to read
   * @param param the image read parameters to use when reading
   *
   * @return a buffered image
   *
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public abstract BufferedImage read(int imageIndex, ImageReadParam param)
    throws IOException;

  /**
   * Check if this reader supports reading thumbnails.
   *
   * @return true if this reader supports reading thumbnails, false
   * otherwise
   */
  public boolean readerSupportsThumbnails()
  {
    return false;
  }

  /**
   * Read raw raster data.  The image type specifier in param is
   * ignored but all other parameters are used.  Offset parameters are
   * translated into the raster's coordinate space.  This method may
   * be implemented by image readers that want to provide direct
   * access to raw image data.
   *
   * @param imageIndex the frame index
   * @param param the image read parameters
   *
   * @return a raster containing the read image data
   *
   * @exception UnsupportedOperationException if this reader doesn't
   * support rasters
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public Raster readRaster(int imageIndex, ImageReadParam param)
    throws IOException
  {
    throw new UnsupportedOperationException();
  }

  /**
   * Read a thumbnail.
   *
   * @param imageIndex the frame index
   * @param thumbnailIndex the thumbnail index
   *
   * @return a buffered image of the thumbnail
   *
   * @exception UnsupportedOperationException if this reader doesn't
   * support thumbnails
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if either the frame index or
   * the thumbnail index is out-of-bounds
   * @exception IOException if a read error occurs
   * 
   */
  public BufferedImage readThumbnail(int imageIndex, int thumbnailIndex)
    throws IOException
  {
    throw new UnsupportedOperationException();
  }

  /**
   * Uninstall all read progress listeners.
   */
  public void removeAllIIOReadProgressListeners()
  {
    progressListeners = null;
  }

  /**
   * Uninstall all read update listeners.
   */
  public void removeAllIIOReadUpdateListeners()
  {
    updateListeners = null;
  }

  /**
   * Uninstall all read warning listeners.
   */
  public void removeAllIIOReadWarningListeners()
  {
    warningListeners = null;
  }

  /**
   * Uninstall the given read progress listener.
   *
   * @param listener the listener to remove
   */
  public void removeIIOReadProgressListener(IIOReadProgressListener listener) 
  {
    if (listener == null)
      return;
    if (progressListeners != null)
      {
	progressListeners.remove(listener);
      }
  }

  /**
   * Uninstall the given read update listener.
   *
   * @param listener the listener to remove
   */
  public void removeIIOReadUpdateListener(IIOReadUpdateListener listener) 
  {
    if (listener == null)
      return;

    if (updateListeners != null)
      {
	updateListeners.remove(listener);
      }
  }

  /**
   * Uninstall the given read warning listener.
   *
   * @param listener the listener to remove
   */
  public void removeIIOReadWarningListener(IIOReadWarningListener listener)
  {
    if (listener == null)
      return;
    if (warningListeners != null)
      {
	warningListeners.remove(listener);
      }
  }

  /**
   * Set the current locale or use the default locale.
   *
   * @param locale the locale to set, or null
   */
  public void setLocale(Locale locale)
  {
    if (locale != null)
      {
	// Check if its a valid locale.
	boolean found = false;

	if (availableLocales != null)
	  for (int i = availableLocales.length - 1; i >= 0; --i)
	    if (availableLocales[i].equals(locale))
	      found = true;

	if (! found)
	  throw new IllegalArgumentException("looale not available");
      }

    this.locale = locale;
  }

  /**
   * Check that the given read parameters have valid source and
   * destination band settings.  If the param.getSourceBands() returns
   * null, the array is assumed to include all band indices, 0 to
   * numSrcBands - 1; likewise if param.getDestinationBands() returns
   * null, it is assumed to be an array containing indices 0 to
   * numDstBands - 1.  A failure will cause this method to throw
   * IllegalArgumentException.
   *
   * @param param the image parameters to check
   * @param numSrcBands the number of input source bands
   * @param numDstBands the number of ouput destination bands
   *
   * @exception IllegalArgumentException if either the given source or
   * destination band indices are invalid
   */
  protected static void checkReadParamBandSettings(ImageReadParam param,
						   int numSrcBands,
						   int numDstBands)
  {
    int[] srcBands = param.getSourceBands();
    int[] dstBands = param.getDestinationBands();
    boolean lengthsDiffer = false;
    boolean srcOOB = false;
    boolean dstOOB = false;

    if (srcBands == null)
      {
        if (dstBands == null)
          {
            if (numSrcBands != numDstBands)
              lengthsDiffer = true;
          }
        else
          {
            if (numSrcBands != dstBands.length)
              lengthsDiffer = true;

            for (int i = 0; i < dstBands.length; i++)
              if (dstBands[i] > numSrcBands - 1)
                {
                  dstOOB = true;
                  break;
                }
          }
      }
    else
      {
        if (dstBands == null)
          {
            if (srcBands.length != numDstBands)
              lengthsDiffer = true;

            for (int i = 0; i < srcBands.length; i++)
              if (srcBands[i] > numDstBands - 1)
                {
                  srcOOB = true;
                  break;
                }
          }
        else
          {
            if (srcBands.length != dstBands.length)
              lengthsDiffer = true;

            for (int i = 0; i < srcBands.length; i++)
              if (srcBands[i] > numDstBands - 1)
                {
                  srcOOB = true;
                  break;
                }

            for (int i = 0; i < dstBands.length; i++)
              if (dstBands[i] > numSrcBands - 1)
                {
                  dstOOB = true;
                  break;
                }
          }
      }

    if (lengthsDiffer)
      throw new IllegalArgumentException ("array lengths differ");

    if (srcOOB)
      throw new IllegalArgumentException ("source band index"
                                          + " out-of-bounds");

    if (dstOOB)
      throw new IllegalArgumentException ("destination band index"
                                          + " out-of-bounds");
  }

  /**
   * Calcluate the source and destination regions that will be read
   * from and written to, given image parameters and/or a destination
   * buffered image.  The source region will be clipped if any of its
   * bounds are outside the destination region.  Clipping will account
   * for subsampling and destination offsets.  Likewise, the
   * destination region is clipped to the given destination image, if
   * it is not null, using the given image parameters, if they are not
   * null.  IllegalArgumentException is thrown if either region will
   * contain 0 pixels after clipping.
   *
   * @param param read parameters, or null
   * @param srcWidth the width of the source image
   * @param srcHeight the height of the source image
   * @param image the destination image, or null
   * @param srcRegion a rectangle whose values will be set to the
   * clipped source region
   * @param destRegion a rectangle whose values will be set to the
   * clipped destination region
   *
   * @exception IllegalArgumentException if either srcRegion or
   * destRegion is null
   * @exception IllegalArgumentException if either of the calculated
   * regions is empty
   */
  protected static void computeRegions (ImageReadParam param,
					int srcWidth,
					int srcHeight,
					BufferedImage image,
					Rectangle srcRegion,
					Rectangle destRegion)
  {
    if (srcRegion == null || destRegion == null)
      throw new IllegalArgumentException ("null region");

    if (srcWidth == 0 || srcHeight == 0)
      throw new IllegalArgumentException ("zero-sized region");

    srcRegion = getSourceRegion(param, srcWidth, srcHeight);
    if (image != null)
      destRegion = new Rectangle (0, 0, image.getWidth(), image.getHeight());
    else
      destRegion = new Rectangle (0, 0, srcWidth, srcHeight);

    if (param != null)
      {
        Point offset = param.getDestinationOffset();

        if (offset.x < 0)
          {
            srcRegion.x -= offset.x;
            srcRegion.width += offset.x;
          }
        if (offset.y < 0)
          {
            srcRegion.y -= offset.y;
            srcRegion.height += offset.y;
          }

        srcRegion.width = srcRegion.width > destRegion.width
          ? destRegion.width : srcRegion.width;
        srcRegion.height = srcRegion.height > destRegion.height
          ? destRegion.height : srcRegion.height;

        if (offset.x >= 0)
          {
            destRegion.x += offset.x;
            destRegion.width -= offset.x;
          }
        if (offset.y >= 0)
          {
            destRegion.y += offset.y;
            destRegion.height -= offset.y;
          }
      }

    if (srcRegion.isEmpty() || destRegion.isEmpty())
      throw new IllegalArgumentException ("zero-sized region");
  }

  /**
   * Return a suitable destination buffered image.  If
   * param.getDestination() is non-null, then it is returned,
   * otherwise a buffered image is created using
   * param.getDestinationType() if it is non-null and also in the
   * given imageTypes collection, or the first element of imageTypes
   * otherwise.
   *
   * @param param image read parameters from which a destination image
   * or image type is retrieved, or null
   * @param imageTypes a collection of legal image types
   * @param width the width of the source image
   * @param height the height of the source image
   *
   * @return a suitable destination buffered image
   *
   * @exception IIOException if param.getDestinationType() does not
   * return an image type in imageTypes
   * @exception IllegalArgumentException if imageTypes is null or
   * empty, or if a non-ImageTypeSpecifier object is retrieved from
   * imageTypes
   * @exception IllegalArgumentException if the resulting destination
   * region is empty
   * @exception IllegalArgumentException if the product of width and
   * height is greater than Integer.MAX_VALUE
   */
  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 (width < 0 || height < 0)
      throw new IllegalArgumentException ("negative dimension");

    // test for overflow
    if (width * height < Math.min (width, height))
      throw new IllegalArgumentException ("width * height > Integer.MAX_VALUE");

    BufferedImage dest = null;
    ImageTypeSpecifier destType = null;

    if (param != null)
      {
        dest = param.getDestination ();
        if (dest == null)
          {
            ImageTypeSpecifier type = param.getDestinationType();
            if (type != null)
              {
                Iterator it = imageTypes;

                while (it.hasNext())
                  {
                    Object o = it.next ();
                    if (! (o instanceof ImageTypeSpecifier))
                      throw new IllegalArgumentException ("non-ImageTypeSpecifier object");

                    ImageTypeSpecifier t = (ImageTypeSpecifier) o;
                    if (t.equals (type))
                      {
                        dest = t.createBufferedImage (width, height);
                        break;
                      }
                    if (destType == null)
                      throw new IIOException ("invalid destination type");

                  }
              }
          }
      }
    if (dest == null)
      {
        Rectangle srcRegion = new Rectangle ();
        Rectangle destRegion = new Rectangle ();

        computeRegions (param, width, height, null, srcRegion, destRegion);

        if (destRegion.isEmpty())
          throw new IllegalArgumentException ("destination region empty");

        if (destType == null)
          {
            Object o = imageTypes.next();
            if (! (o instanceof ImageTypeSpecifier))
              throw new IllegalArgumentException ("non-ImageTypeSpecifier"
                                                  + " object");

            dest = ((ImageTypeSpecifier) o).createBufferedImage
              (destRegion.width, destRegion.height);
          }
        else
          dest = destType.createBufferedImage
            (destRegion.width, destRegion.height);
      }
    return dest;
  }

  /**
   * Get the metadata associated with this image.  If the reader is
   * set to ignore metadata or does not support reading metadata, or
   * if no metadata is available then null is returned.
   *
   * This more specific version of getImageMetadata(int) can be used
   * to restrict metadata retrieval to specific formats and node
   * names, which can limit the amount of data that needs to be
   * processed.
   *
   * @param imageIndex the frame index
   * @param formatName the format of metadata requested
   * @param nodeNames a set of Strings specifiying node names to be
   * retrieved
   *
   * @return a metadata object, or null
   *
   * @exception IllegalStateException if input has not been set
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IllegalArgumentException if formatName is null
   * @exception IllegalArgumentException if nodeNames is null
   * @exception IOException if a read error occurs
   */
  public IIOMetadata getImageMetadata (int imageIndex,
                                       String formatName,
                                       Set<String> nodeNames)
    throws IOException
  {
    if (formatName == null || nodeNames == null)
      throw new IllegalArgumentException ("null argument");

    return getImageMetadata (imageIndex);
  }

  /**
   * Get the index at which the next image will be read.  If
   * seekForwardOnly is true then the returned value will increase
   * monotonically each time an image frame is read.  If
   * seekForwardOnly is false then the returned value will always be
   * 0.
   *
   * @return the current frame index
   */
  public int getMinIndex()
  {
    return minIndex;
  }

  /**
   * Get the image type specifier that most closely represents the
   * internal data representation used by this reader.  This value
   * should be included in the return value of getImageTypes.
   *
   * @param imageIndex the frame index
   *
   * @return an image type specifier
   *
   * @exception IllegalStateException if input has not been set
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public ImageTypeSpecifier getRawImageType (int imageIndex)
    throws IOException
  {
    return getImageTypes(imageIndex).next();
  }

  /**
   * Calculate a source region based on the given source image
   * dimensions and parameters.  Subsampling offsets and a source
   * region are taken from the given image read parameters and used to
   * clip the given image dimensions, returning a new rectangular
   * region as a result.
   *
   * @param param image parameters, or null
   * @param srcWidth the width of the source image
   * @param srcHeight the height of the source image
   *
   * @return a clipped rectangle
   */
  protected static Rectangle getSourceRegion (ImageReadParam param,
					      int srcWidth,
					      int srcHeight)
  {
    Rectangle clippedRegion = new Rectangle (0, 0, srcWidth, srcHeight);

    if (param != null)
      {
        Rectangle srcRegion = param.getSourceRegion();

        if (srcRegion != null)
          {
            clippedRegion.x = srcRegion.x > clippedRegion.x
              ? srcRegion.x : clippedRegion.x;
            clippedRegion.y = srcRegion.y > clippedRegion.y
              ? srcRegion.y : clippedRegion.y;
            clippedRegion.width = srcRegion.width > clippedRegion.width
              ? srcRegion.width : clippedRegion.width;
            clippedRegion.height = srcRegion.height > clippedRegion.height
              ? srcRegion.height : clippedRegion.height;
          }

        int xOffset = param.getSubsamplingXOffset();

        clippedRegion.x += xOffset;
        clippedRegion.width -= xOffset;

        int yOffset = param.getSubsamplingYOffset();

        clippedRegion.y += yOffset;
        clippedRegion.height -= yOffset;
      }
    return clippedRegion;
  }

  /**
   * Get the metadata associated with the image being read.  If the
   * reader is set to ignore metadata or does not support reading
   * metadata, or if no metadata is available then null is returned.
   * This method returns metadata associated with the entirety of the
   * image data, whereas getStreamMetadata() returns metadata
   * associated with a frame within a multi-image data stream.
   *
   * This more specific version of getStreamMetadata() can be used to
   * restrict metadata retrieval to specific formats and node names,
   * which can limit the amount of data that needs to be processed.
   *
   * @param formatName the format of metadata requested
   * @param nodeNames a set of Strings specifiying node names to be
   * retrieved
   *
   * @return metadata associated with the image being read, or null
   *
   * @exception IllegalArgumentException if formatName is null
   * @exception IllegalArgumentException if nodeNames is null
   * @exception IOException if a read error occurs
   */
  public IIOMetadata getStreamMetadata (String formatName,
                                        Set<String> nodeNames)
    throws IOException
  {
    if (formatName == null || nodeNames == null)
      throw new IllegalArgumentException ("null argument");

    return getStreamMetadata();
  }

  /**
   * Read the given frame all at once, using default image read
   * parameters, and return a buffered image.
   *
   * The returned image will be formatted according to the
   * currently-preferred image type specifier.
   *
   * Installed read progress listeners, update progress listeners and
   * warning listeners will be notified of read progress, changes in
   * sample sets and warnings respectively.
   *
   * @param imageIndex the index of the image frame to read
   *
   * @return a buffered image
   *
   * @exception IllegalStateException if input has not been set
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public BufferedImage read (int imageIndex)
    throws IOException
  {
    return read (imageIndex, null);
  }

  /**
   * Read the given frame all at once, using the given image read
   * parameters, and return an IIOImage.  The IIOImage will contain a
   * buffered image as returned by getDestination.
   *
   * Installed read progress listeners, update progress listeners and
   * warning listeners will be notified of read progress, changes in
   * sample sets and warnings respectively.
   *
   * The source and destination band settings are checked with a call
   * to checkReadParamBandSettings.
   *
   * @param imageIndex the index of the image frame to read
   * @param param the image read parameters
   *
   * @return an IIOImage
   *
   * @exception IllegalStateException if input has not been set
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IllegalArgumentException if param.getSourceBands() and
   * param.getDestinationBands() are incompatible
   * @exception IllegalArgumentException if either the source or
   * destination image regions are empty
   * @exception IOException if a read error occurs
   */
  public IIOImage readAll (int imageIndex,
			   ImageReadParam param)
    throws IOException
  {
    checkReadParamBandSettings (param,
                                param.getSourceBands().length,
                                param.getDestinationBands().length);

    List l = new ArrayList ();

    for (int i = 0; i < getNumThumbnails (imageIndex); i++)
      l.add (readThumbnail(imageIndex, i));

    return new IIOImage (getDestination(param, getImageTypes(imageIndex),
                                        getWidth(imageIndex),
                                        getHeight(imageIndex)),
                         l,
                         getImageMetadata (imageIndex));
  }

  /**
   * Read all image frames all at once, using the given image read
   * parameters iterator, and return an iterator over a collection of
   * IIOImages.  Each IIOImage in the collection will contain a
   * buffered image as returned by getDestination.
   *
   * Installed read progress listeners, update progress listeners and
   * warning listeners will be notified of read progress, changes in
   * sample sets and warnings respectively.
   *
   * Each set of source and destination band settings are checked with
   * a call to checkReadParamBandSettings.
   *
   * @param params iterator over the image read parameters
   *
   * @return an IIOImage
   *
   * @exception IllegalStateException if input has not been set
   * @exception IllegalArgumentException if a non-ImageReadParam is
   * found in params
   * @exception IllegalArgumentException if param.getSourceBands() and
   * param.getDestinationBands() are incompatible
   * @exception IllegalArgumentException if either the source or
   * destination image regions are empty
   * @exception IOException if a read error occurs
   */
  public Iterator<IIOImage> readAll (Iterator<? extends ImageReadParam> params)
    throws IOException
  {
    List l = new ArrayList ();
    int index = 0;

    while (params.hasNext())
      {
        if (params != null && ! (params instanceof ImageReadParam))
          throw new IllegalArgumentException ("non-ImageReadParam found");

        l.add (readAll(index++, (ImageReadParam) params.next ()));
      }

    return l.iterator();
  }

  /**
   * Read a rendered image.  This is a more general counterpart to
   * read (int, ImageReadParam).  All image data may not be read
   * before this method returns and so listeners will not necessarily
   * be notified.
   *
   * @param imageIndex the index of the image frame to read
   * @param param the image read parameters
   *
   * @return a rendered image
   *
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IllegalArgumentException if param.getSourceBands() and
   * param.getDestinationBands() are incompatible
   * @exception IllegalArgumentException if either the source or
   * destination image regions are empty
   * @exception IOException if a read error occurs
   */
  public RenderedImage readAsRenderedImage (int imageIndex,
					    ImageReadParam param)
    throws IOException
  {
    return read (imageIndex, param);
  }

  /**
   * Read the given tile into a buffered image.  If the tile
   * coordinates are out-of-bounds an exception is thrown.  If the
   * image is not tiled then the coordinates 0, 0 are expected and the
   * entire image will be read.
   *
   * @param imageIndex the frame index
   * @param tileX the horizontal tile coordinate
   * @param tileY the vertical tile coordinate
   *
   * @return the contents of the tile as a buffered image
   *
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IllegalArgumentException if the tile coordinates are
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public BufferedImage readTile (int imageIndex, int tileX, int tileY)
    throws IOException
  {
    if (tileX != 0 || tileY != 0)
      throw new IllegalArgumentException ("tileX not 0 or tileY not 0");

    return read (imageIndex);
  }

  /**
   * Read the given tile into a raster containing the raw image data.
   * If the tile coordinates are out-of-bounds an exception is thrown.
   * If the image is not tiled then the coordinates 0, 0 are expected
   * and the entire image will be read.
   *
   * @param imageIndex the frame index
   * @param tileX the horizontal tile coordinate
   * @param tileY the vertical tile coordinate
   *
   * @return the contents of the tile as a raster
   *
   * @exception UnsupportedOperationException if rasters are not
   * supported
   * @exception IllegalStateException if input is null
   * @exception IndexOutOfBoundsException if the frame index is
   * out-of-bounds
   * @exception IllegalArgumentException if the tile coordinates are
   * out-of-bounds
   * @exception IOException if a read error occurs
   */
  public Raster readTileRaster (int imageIndex, int tileX, int tileY)
    throws IOException
  {
    if (!canReadRaster())
      throw new UnsupportedOperationException ("cannot read rasters");

    if (tileX != 0 || tileY != 0)
      throw new IllegalArgumentException ("tileX not 0 or tileY not 0");

    return readRaster (imageIndex, null);
  }

  /**
   * Reset this reader's internal state.
   */
  public void reset ()
  {
    setInput (null, false);
    setLocale (null);
    removeAllIIOReadUpdateListeners ();
    removeAllIIOReadWarningListeners ();
    removeAllIIOReadProgressListeners ();
    clearAbortRequest ();
  }
}

