/* ImageWriter.java -- Encodes 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.Dimension;
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 javax.imageio.event.IIOWriteProgressListener;
import javax.imageio.event.IIOWriteWarningListener;
import javax.imageio.metadata.IIOMetadata;

import javax.imageio.spi.ImageWriterSpi;

/**
 * A class for encoding images within the ImageIO framework.
 *
 * An ImageWriter for a given format is instantiated by an
 * ImageWriterSpi for that format.  ImageWriterSpis are registered
 * with the IIORegistry.
 *
 * The ImageWriter API supports writing animated images that may have
 * multiple frames; to support such images many methods take an index
 * parameter.
 *
 * Images may also be written in multiple passes, where each
 * successive pass increases the level of detail in the destination
 * image.
 */
public abstract class ImageWriter
  implements ImageTranscoder
{
  private boolean aborted;
  
  /**
   * All locales available for localization of warning messages, or
   * null if localization is not supported.
   */
  protected Locale[] availableLocales = null;

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

  /**
   * The image writer SPI that instantiated this writer.
   */
  protected ImageWriterSpi originatingProvider = null;

  /**
   * An ImageInputStream to which image data is written.
   */
  protected Object output = null;

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

  /**
   * A list of installed warning listeners.  Initially null, meaning
   * no installed listeners.
   */
  protected List<IIOWriteWarningListener> 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 writer.
   *
   * @param originatingProvider the provider that is constructing this
   * image writer, or null
   */
  protected ImageWriter(ImageWriterSpi originatingProvider)
  {
    this.originatingProvider = originatingProvider;
  }

  /**
   * Throw an IllegalStateException if output is null.
   *
   * @exception IllegalStateException if output is null
   */
  private void checkOutputSet()
  {
    if (output == null)
      throw new IllegalStateException("no output set");
  }
  
  /**
   * Request that writing be aborted.  The unwritten portions of the
   * destination image will be undefined.
   *
   * Writers should clear the abort flag before starting a write
   * operation, then poll it periodically during the write operation.
   */
  public void abort()
  {
    aborted = true;
  }

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

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

  /**
   * Install a write 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 writer will select a sensible
   * default.
   *
   * @param listener a write warning listener
   */
  public void addIIOWriteWarningListener (IIOWriteWarningListener listener)
  {
    if (listener == null)
      return;
    if (warningListeners == null)
      warningListeners = new ArrayList ();
    warningListeners.add(listener);
  }

  /**
   * Check whether a new empty image can be inserted at the given
   * frame index.  Pixel values may be filled in later using the
   * replacePixels methods.  Indices greater than the insertion index
   * will be incremented.  If imageIndex is -1, the image will be
   * appended at the end of the current image list.
   *
   * @param imageIndex the frame index
   *
   * @return true if an empty image can be inserted at imageIndex,
   * false otherwise
   *
   * @exception IllegalStateException if output is null
   * @exception IndexOutOfBoundsException if imageIndex is less than
   * -1 or greater than the last index in the current image list
   * @exception IOException if a write error occurs
   */
  public boolean canInsertEmpty(int imageIndex)
    throws IOException
  {
    checkOutputSet();
    return false;
  }

  /**
   * Check whether an image can be inserted at the given frame index.
   * Indices greater than the insertion index will be incremented.  If
   * imageIndex is -1, the image will be appended at the end of the
   * current image list.
   *
   * @param imageIndex the frame index
   *
   * @return true if an image can be inserted at imageIndex, false
   * otherwise
   *
   * @exception IllegalStateException if output is null
   * @exception IndexOutOfBoundsException if imageIndex is less than
   * -1 or greater than the last index in the current image list
   * @exception IOException if a write error occurs
   */
  public boolean canInsertImage(int imageIndex)
    throws IOException
  {
    checkOutputSet();
    return false;
  }

  /**
   * Check whether an image can be removed from the given frame index.
   * Indices greater than the removal index will be decremented.
   *
   * @param imageIndex the frame index
   *
   * @return true if an image can be removed from imageIndex, false
   * otherwise
   *
   * @exception IllegalStateException if output is null
   * @exception IndexOutOfBoundsException if imageIndex is less than 0
   * or greater than the last index in the current image list
   * @exception IOException if a write error occurs
   */
  public boolean canRemoveImage(int imageIndex)
    throws IOException
  {
    checkOutputSet();
    return false;
  }

  /**
   * Check whether the metadata associated the image at the given
   * frame index can be replaced.
   *
   * @param imageIndex the frame index
   *
   * @return true if the metadata associated with the image at
   * imageIndex can be replaced, false otherwise
   *
   * @exception IllegalStateException if output is null
   * @exception IndexOutOfBoundsException if imageIndex is less than 0
   * or greater than the last index in the current image list
   * @exception IOException if a write error occurs
   */
  public boolean canReplaceImageMetadata(int imageIndex)
    throws IOException
  {
    checkOutputSet();
    return false;
  }

  /**
   * Check whether the pixels within the image at the given index can
   * be replaced.
   *
   * @param imageIndex the frame index
   *
   * @return true if the pixels in the image at imageIndex can be
   * replaced, false otherwise
   *
   * @exception IllegalStateException if output is null
   * @exception IndexOutOfBoundsException if imageIndex is less than 0
   * or greater than the last index in the current image list
   * @exception IOException if a write error occurs
   */
  public boolean canReplacePixels(int imageIndex)
    throws IOException
  {
    checkOutputSet();
    return false;
  }

  /**
   * Check whether the metadata associated the entire image stream can
   * be replaced.
   *
   * @return true if the stream metadata can be replaced, false
   * otherwise
   *
   * @exception IllegalStateException if output is null
   * @exception IOException if a write error occurs
   */
  public boolean canReplaceStreamMetadata()
    throws IOException
  {
    checkOutputSet();
    return false;
  }

  /**
   * Check whether an entire empty image, including empty metadata and
   * empty thumbnails, can be written to the output stream, leaving
   * pixel values to be filled in later using the replacePixels
   * methods.
   *
   * @return true if an entire empty image can be written before its
   * contents are filled in, false otherwise
   *
   * @exception IllegalStateException if output is null
   * @exception IOException if a write error occurs
   */
  public boolean canWriteEmpty()
    throws IOException
  {
    checkOutputSet();
    return false;
  }

  /**
   * Check if IIOImages containing raster data are supported.
   *
   * @return true if raster IIOImages are supported, false otherwise
   */
  public boolean canWriteRasters()
  {
    return false;
  }

  /**
   * Check if an image can be appended at the end of the current list
   * of images even if prior images have already been written.
   *
   * @return true if sequences of images can be written, false
   * otherwise
   */
  public boolean canWriteSequence()
  {
    return false;
  }

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

  /**
   * Convert IIOMetadata from an input reader format, returning an
   * IIOMetadata suitable for use by an image writer.
   *
   * The ImageTypeSpecifier specifies the destination image type.
   *
   * An optional ImageWriteParam argument is available in case the
   * image writing parameters affect the metadata conversion.
   *
   * @param inData the metadata coming from an image reader
   * @param imageType the output image type of the writer
   * @param param the image writing parameters or null
   *
   * @return the converted metadata that should be used by the image
   * writer, or null if this ImageTranscoder has no knowledge of the
   * input metadata
   *
   * @exception IllegalArgumentException if either inData or imageType
   * is null
   */
  public abstract IIOMetadata convertImageMetadata (IIOMetadata inData,
		                                    ImageTypeSpecifier imageType,
				                    ImageWriteParam param);

  /**
   * Convert IIOMetadata from an input stream format, returning an
   * IIOMetadata suitable for use by an image writer.
   *
   * An optional ImageWriteParam argument is available in case the
   * image writing parameters affect the metadata conversion.
   *
   * @param inData the metadata coming from an input image stream
   * @param param the image writing parameters or null
   *
   * @return the converted metadata that should be used by the image
   * writer, or null if this ImageTranscoder has no knowledge of the
   * input metadata
   *
   * @exception IllegalArgumentException if inData is null
   */
  public abstract IIOMetadata convertStreamMetadata (IIOMetadata inData,
					             ImageWriteParam param);

  /**
   * 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 is empty. Subclasses have to overwrite it.
  }
  
  /**
   * 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()
  {
    return availableLocales;
  }

  /**
   * Get a metadata object appropriate for encoding an image specified
   * by the given image type specifier and optional image write
   * parameters.
   *
   * @param imageType an image type specifier
   * @param param image writing parameters, or null
   *
   * @return a metadata object appropriate for encoding an image of
   * the given type with the given parameters
   */
  public abstract IIOMetadata getDefaultImageMetadata (ImageTypeSpecifier imageType, ImageWriteParam param);

  /**
   * Get a metadata object appropriate for encoding the default image
   * type handled by this writer, optionally considering image write
   * parameters.
   *
   * @param param image writing parameters, or null
   *
   * @return a metadata object appropriate for encoding an image of
   * the default type with the given parameters
   */
  public abstract IIOMetadata getDefaultStreamMetadata (ImageWriteParam param);

  /**
   * Retrieve the default write parameters for this writer's image
   * format.
   *
   * The default implementation returns new ImageWriteParam().
   *
   * @return image writing parameters
   */
  public ImageWriteParam getDefaultWriteParam()
  {
    return new ImageWriteParam(getLocale());
  }

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

  /**
   * Get the number of thumbnails supported by this image writer,
   * based on the given image type, image writing parameters, and
   * stream and image metadata.  The image writing parameters are
   * optional, in case they affect the number of thumbnails supported.
   *
   * @param imageType an image type specifier, or null
   * @param param image writing parameters, or null
   * @param streamMetadata the metadata associated with this stream,
   * or null
   * @param imageMetadata the metadata associated with this image, or
   * null
   *
   * @return the number of thumbnails that this writer supports
   * writing or -1 if the given information is insufficient
   */
  public int getNumThumbnailsSupported (ImageTypeSpecifier imageType,
                                        ImageWriteParam param,
		                        IIOMetadata streamMetadata,
                                        IIOMetadata imageMetadata)
  {
    return 0;
  }

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

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

  /**
   * Get the preferred sizes for thumbnails based on the given image
   * type, image writing parameters, and stream and image metadata.
   * The preferred sizes are returned in pairs of dimension values;
   * the first value in the array is a dimension object representing
   * the minimum thumbnail size, the second value is a dimension
   * object representing a maximum thumbnail size.  The writer can
   * select a size within the range given by each pair, or it can
   * ignore these size hints.
   *
   * @param imageType an image type specifier, or null
   * @param param image writing parameters, or null
   * @param streamMetadata the metadata associated with this stream,
   * or null
   * @param imageMetadata the metadata associated with this image, or
   * null
   *
   * @return an array of dimension pairs whose length is a multiple of
   * 2, or null if there is no preferred size (any size is allowed) or
   * if the size is unknown (insufficient information was provided)
   */
  public Dimension[] getPreferredThumbnailSizes (ImageTypeSpecifier imageType,
		                                 ImageWriteParam param,
						 IIOMetadata streamMetadata,
						 IIOMetadata imageMetadata)
  {
    return null;
  }

  /**
   * Notifies all installed write 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())
	  {
	    IIOWriteProgressListener listener =
	      (IIOWriteProgressListener) it.next();
	    listener.imageComplete(this);
	  }
      }
  }

  /**
   * Notifies all installed write 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())
	  {
	    IIOWriteProgressListener listener =
	      (IIOWriteProgressListener) it.next();
	    listener.imageProgress(this, percentageDone);
	  }
      }
  }

  /**
   * Notifies all installed write 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())
	  {
	    IIOWriteProgressListener listener =
	      (IIOWriteProgressListener) it.next();
	    listener.imageStarted(this, imageIndex);
	  }
      }
  }

  /**
   * Notifies all installed write 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())
	  {
	    IIOWriteProgressListener listener =
	      (IIOWriteProgressListener) it.next();
	    listener.thumbnailComplete(this);
	  }
      }
  }

  /**
   * Notifies all installed write 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())
	  {
	    IIOWriteProgressListener listener =
	      (IIOWriteProgressListener) it.next();
	    listener.thumbnailProgress(this, percentageDone);
	  }
      }
  }

  /**
   * Notifies all installed write 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())
	  {
	    IIOWriteProgressListener listener =
	      (IIOWriteProgressListener) it.next();
	    listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
	  }
      }
  }

  /**
   * Notifies all installed warning listeners, by calling their
   * warningOccurred methods, that a warning message has been raised.
   *
   * @param imageIndex the index of the image that was being written
   * when the warning was raised
   * @param warning the warning message
   *
   * @exception IllegalArgumentException if warning is null
   */
  protected void processWarningOccurred(int imageIndex, String warning)
  {
     if (warningListeners != null)
      {
	Iterator it = warningListeners.iterator();

	while (it.hasNext())
	  {
	    IIOWriteWarningListener listener =
	      (IIOWriteWarningListener) it.next();
	    listener.warningOccurred(this, imageIndex, 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 imageIndex the index of the image that was being written
   * when the warning was raised
   * @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(int imageIndex,
					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())
	  {
	    IIOWriteWarningListener listener =
	      (IIOWriteWarningListener) it.next();
	    listener.warningOccurred(this, imageIndex, warning);
	  }
      }
  }

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

	while (it.hasNext())
	  {
	    IIOWriteProgressListener listener =
	      (IIOWriteProgressListener) it.next();
	    listener.writeAborted(this);
	  }
      }
  }

  /**
   * Uninstall all write progress listeners.
   */
  public void removeAllIIOWriteProgressListeners()
  {
    if (progressListeners != null)
      {
	progressListeners.clear();
      }
  }

  /**
   * Uninstall all write warning listeners.
   */
  public void removeAllIIOWriteWarningListeners()
  {
    if (progressListeners != null)
      {
	progressListeners.clear();
      }
  }

  /**
   * Uninstall the given write progress listener.
   *
   * @param listener the listener to remove
   */
  public void removeIIOWriteProgressListener (IIOWriteProgressListener listener)
  {
    if (listener == null)
      return;
    if (progressListeners != null)
      {
	progressListeners.remove(listener);
      }
  }
  /**
   * Uninstall the given write warning listener.
   *
   * @param listener the listener to remove
   */
  public void removeIIOWriteWarningListener (IIOWriteWarningListener listener)
  {
    if (listener == null)
      return;
    if (warningListeners != null)
      {
	warningListeners.remove(listener);
      }
  }
  /**
   * Reset this writer's internal state.
   */
  public void reset()
  {
    setOutput(null);
    setLocale(null);
    removeAllIIOWriteWarningListeners();
    removeAllIIOWriteProgressListeners();
    clearAbortRequest();
  }
  
  /**
   * 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;
  }

  /**
   * Set the output destination of the given object.  The output
   * destination must be set before many methods can be called on this
   * writer. (see all ImageWriter methods that throw
   * IllegalStateException).  If input is null then the current input
   * source will be removed.
   *
   * @param input the output destination object
   *
   * @exception IllegalArgumentException if input is not a valid input
   * source for this writer and is not an ImageInputStream
   */
  public void setOutput(Object output)
  {
    if (output != null)
      {
	// Check if its a valid output object.
	boolean found = false;
	Class[] types = null;

	if (originatingProvider != null)
	  types = originatingProvider.getOutputTypes();
        
	if (types != null)
	  for (int i = types.length - 1; i >= 0; --i)
            if (types[i].isInstance(output))
              found = true;

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

    this.output = output;
  }

  /**
   * Write an image stream, including thumbnails and metadata to the
   * output stream.  The output must have been set prior to this
   * method being called.  Metadata associated with the stream may be
   * supplied, or it can be left null.  IIOImage may contain raster
   * data if this writer supports rasters, or it will contain a
   * rendered image.  Thumbnails are resized if need be.  Image
   * writing parameters may be specified to affect writing, or may be
   * left null.
   *
   * @param streamMetadata metadata associated with this stream, or
   * null
   * @param image an IIOImage containing image data, metadata and
   * thumbnails to be written
   * @param param image writing parameters, or null
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if image contains raster
   * data but this writer does not support rasters
   * @exception IllegalArgumentException if image is null
   * @exception IOException if a write error occurs
   */
  public abstract void write (IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param)
    throws IOException;

  /**
   * Complete inserting an empty image in the output stream.
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if inserting empty
   * images is not supported
   * @exception IllegalArgumentException if a call to
   * prepareInsertEmpty was not called previous to this method being
   * called (a sequence of prepareInsertEmpty calls must be terminated
   * by a call to endInsertEmpty)
   * @exception IllegalArgumentException if prepareWriteEmpty was
   * called before this method being called (without a terminating
   * call to endWriteEmpty)
   * @exception IllegalArgumentException if prepareReplacePixels was
   * called before this method being called (without a terminating
   * call to endReplacePixels)
   * @exception IOException if a write error occurs
   */
  public void endInsertEmpty ()
    throws IOException
  {
    if (!canInsertEmpty(0))
      throw new UnsupportedOperationException();
  }

  /**
   * Complete replacing pixels in an image in the output stream.
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if replacing pixels is
   * not supported by this writer
   * @exception IllegalArgumentException if prepareReplacePixels was
   * not called before this method being called
   * @exception IOException if a write error occurs
   */
  public void endReplacePixels ()
    throws IOException
  {
    if (!canReplacePixels(0))
      throw new UnsupportedOperationException();
  }

  /**
   * Complete writing an empty image to the image output stream.
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if writing empty images
   * is not supported
   * @exception IllegalArgumentException if a call to
   * prepareWriteEmpty was not called previous to this method being
   * called (a sequence of prepareWriteEmpty calls must be terminated
   * by a call to endWriteEmpty)
   * @exception IllegalArgumentException if prepareInsertEmpty was
   * called before this method being called (without a terminating
   * call to endInsertEmpty)
   * @exception IllegalArgumentException if prepareReplacePixels was
   * called before this method being called (without a terminating
   * call to endReplacePixels)
   * @exception IOException if a write error occurs
   */
  public void endWriteEmpty ()
    throws IOException
  {
    if (!canWriteEmpty())
      throw new UnsupportedOperationException();
  }

  /**
   * Complete writing a sequence of images to the output stream.  This
   * method may patch header data and write out footer data.
   *
   * @exception IllegalStateException if output is null
   * @exception IllegalStateException if prepareWriteSequence has not
   * been called
   * @exception UnsupportedOperationException if writing a sequence of
   * images is not supported
   * @exception IOException if a write error occurs
   */
  public void endWriteSequence ()
    throws IOException
  {
    checkOutputSet();
    if (!canWriteSequence())
      throw new UnsupportedOperationException();
  }

  /**
   * Start inserting an empty image in the image output stream.  All
   * indices after the specified index are incremented.  An index of
   * -1 implies that the empty image should be appended to the end of
   * the current image list.
   *
   * The insertion that this method call starts is not complete until
   * endInsertEmpty is called.  prepareInsertEmpty cannot be called
   * again until endInsertEmpty is called and calls to
   * prepareWriteEmpty and prepareInsertEmpty may not be intersperced.
   *
   * @param imageIndex the image index
   * @param imageType the image type specifier
   * @param width the image width
   * @param height the image height
   * @param imageMetadata the image metadata, or null
   * @param thumbnails a list of thumbnails, or null
   * @param param image write parameters, or null
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if inserting empty
   * images is not supported
   * @exception IndexOutOfBoundsException if imageIndex is less than
   * -1 or greater than the last index in the current image list
   * @exception IllegalStateException if a previous call to
   * prepareInsertEmpty was made (without a terminating call to
   * endInsertEmpty)
   * @exception IllegalStateException if a previous call to
   * prepareWriteEmpty was made (without a terminating call to
   * endWriteEmpty)
   * @exception IllegalArgumentException if imageType is null or
   * thumbnails contain non-BufferedImage objects
   * @exception IllegalArgumentException if either width or height is
   * less than 1
   * @exception IOException if a write error occurs
   */
  public void prepareInsertEmpty (int imageIndex, ImageTypeSpecifier imageType,
                                  int width, int height,
                                  IIOMetadata imageMetadata,
                                  List<? extends BufferedImage> thumbnails,
                                  ImageWriteParam param)
    throws IOException
  {
    if (!canInsertEmpty(imageIndex))
      throw new UnsupportedOperationException();
  }

  /**
   * Start the replacement of pixels within an image in the output
   * stream.  Output pixels will be clipped to lie within region.
   *
   * @param imageIndex the index of the image in which pixels are
   * being replaced
   * @param region the rectangle to which to limit pixel replacement
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if replacing pixels is
   * not supported
   * @exception IndexOutOfBoundsException if imageIndex is less than 0
   * or greater than the last index in the current image list
   * @exception IllegalStateException if a previous call to
   * prepareReplacePixels was made (without a terminating call to
   * endReplacePixels)
   * @exception IllegalArgumentException if either region.width or
   * region.height is less than 1, or if region is null
   * @exception IOException if a write error occurs
   */
  public void prepareReplacePixels (int imageIndex, Rectangle region)
    throws IOException
  {
    if (canReplacePixels(imageIndex))
      throw new UnsupportedOperationException();
  }

  /**
   * Start writing an empty image to the end of the image output
   * stream.
   *
   * The writing that this method call starts is not complete until
   * endWriteEmpty is called.  prepareWritetEmpty cannot be called
   * again until endWriteEmpty is called and calls to
   * prepareWriteEmpty and prepareInsertEmpty may not be intersperced.
   *
   * @param streamMetadata metadata associated with the stream, or null
   * @param imageType the image type specifier
   * @param width the image width
   * @param height the image height
   * @param imageMetadata the image metadata, or null
   * @param thumbnails a list of thumbnails, or null
   * @param param image write parameters, or null
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if writing empty images
   * is not supported
   * @exception IndexOutOfBoundsException if imageIndex is less than
   * -1 or greater than the last index in the current image list
   * @exception IllegalStateException if a previous call to
   * prepareInsertEmpty was made (without a terminating call to
   * endInsertEmpty)
   * @exception IllegalStateException if a previous call to
   * prepareWriteEmpty was made (without a terminating call to
   * endWriteEmpty)
   * @exception IllegalArgumentException if imageType is null or
   * thumbnails contain non-BufferedImage objects
   * @exception IllegalArgumentException if either width or height is
   * less than 1
   * @exception IOException if a write error occurs
   */
  public void prepareWriteEmpty (IIOMetadata streamMetadata,
                                 ImageTypeSpecifier imageType,
                                 int width, int height,
                                 IIOMetadata imageMetadata,
                                 List<? extends BufferedImage> thumbnails,
                                 ImageWriteParam param)
    throws IOException
  {
    if (!canWriteEmpty())
      throw new UnsupportedOperationException();
  }

  /**
   * Start the writing of a sequence of images.
   *
   * @param streamMetadata the stream metadata, or null
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if writing sequences of
   * images is not supported
   * @exception IOException if a write error occurs
   */
  public void prepareWriteSequence (IIOMetadata streamMetadata)
    throws IOException
  {
    checkOutputSet();
    if (!canWriteSequence())
      throw new UnsupportedOperationException();
  }

  /**
   * Remove the image at the specified index from the output stream.
   *
   * @param imageIndex the frame index from which to remove the image
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if removing this image
   * is not supported
   * @exception IndexOutOfBoundsException if imageIndex is less than 0
   * or greater than the last index in the current image list
   * @exception IOException if a write error occurs
   */
  public void removeImage (int imageIndex)
    throws IOException
  {
    if (!canRemoveImage(imageIndex))
      throw new UnsupportedOperationException();
  }

  /**
   * Replace the metadata associated with the image at the given
   * index.
   *
   * @param imageIndex the index of the image whose metadata should be
   * replaced
   * @param imageMetadata the metadata, or null
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if replacing this
   * image's metadata is not supported
   * @exception IndexOutOfBoundsException if imageIndex is less than 0
   * or greater than the last index in the current image list
   * @exception IOException if a write error occurs
   */
  public void replaceImageMetadata (int imageIndex, IIOMetadata imageMetadata)
    throws IOException
  {
    if (!canReplaceImageMetadata(imageIndex))
      throw new UnsupportedOperationException();
  }

  /**
   * Replace a region of an image in the output stream with a portion
   * of the given rendered image.  The image data must be of the same
   * type as that in the output stream.  The destination region is
   * given by the image writing parameters and the source region is
   * the one given to prepareReplacePixels.
   *
   * @param image the rendered image with which to overwrite the image
   * region in the stream
   * @param param the image writing parameters
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if replacing pixels is
   * not supported
   * @exception IllegalStateException if prepareReplacePixels was not
   * called before this method was called
   * @exception IllegalArgumentException if image is null or if param
   * is null or if the overlap of the source and destination regions
   * contains no pixels or if the image types differ and no conversion
   * is possible
   * @exception IOException if a write error occurs
   */
  public void replacePixels (RenderedImage image,
                             ImageWriteParam param)
    throws IOException
  {
    if (!canReplacePixels(0))
      throw new UnsupportedOperationException();
  }

  /**
   * Replace a region of an image in the output stream with a portion
   * of the given raster data.  The image data must be of the same
   * type as that in the output stream.  The destination region is
   * given by the image writing parameters and the source region is
   * the one given to prepareReplacePixels.
   *
   * @param raster the raster data with which to overwrite the image
   * region in the stream
   * @param param the image writing parameters
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if replacing pixels is
   * not supported
   * @exception IllegalStateException if prepareReplacePixels was not
   * called before this method was called
   * @exception UnsupportedOperationException if raster data is not
   * supported
   * @exception IllegalArgumentException if raster is null or if param
   * is null or if the overlap of the source and destination regions
   * contains no pixels or if the image types differ and no conversion
   * is possible
   * @exception IOException if a write error occurs
   */
  public void replacePixels (Raster raster, ImageWriteParam param)
    throws IOException
  {
    if (!canReplacePixels(0))
    throw new UnsupportedOperationException();
  }

  /**
   * Replace the metadata associated with this image stream.
   *
   * @param streamMetadata the stream metadata, or null
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if replacing the stream
   * metadata is not supported
   * @exception IOException if a write error occurs
   */
  public void replaceStreamMetadata (IIOMetadata streamMetadata)
    throws IOException
  {
    if (!canReplaceStreamMetadata())
      throw new UnsupportedOperationException();
  }

  /**
   * Write a rendered image to the output stream.
   *
   * @param image a rendered image containing image data to be written
   *
   * @exception IllegalStateException if output is null
   * @exception IllegalArgumentException if image is null
   * @exception IOException if a write error occurs
   */
  public void write (RenderedImage image)
    throws IOException
  {
    checkOutputSet();
    write (null, new IIOImage(image, null, null), null);
  }

  /**
   * Write a image data, metadata and thumbnails to the output stream.
   *
   * @param image image data, metadata and thumbnails to be written
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if image contains raster
   * data but this writer does not support rasters
   * @exception IllegalArgumentException if image is null
   * @exception IOException if a write error occurs
   */
  public void write (IIOImage image)
    throws IOException
  {
    checkOutputSet();
    write (null, image, null);
  }

  /**
   * Insert an image into the output stream.  Indices greater than the
   * specified index are incremented accordingly.  Specifying an index
   * of -1 causes the image to be appended at the end of the current
   * image list.
   *
   * @param imageIndex the frame index at which to insert the image
   * @param image the image data, metadata and thumbnails to be
   * inserted
   * @param the image write parameters, or null
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if image insertion is
   * not supported
   * @exception IllegalArgumentException if image is null
   * @exception IndexOutOfBoundsException if imageIndex is less than
   * -1 or greater than the last index in the current image list
   * @exception UnsupportedOperationException if image contains raster
   * data but this writer does not support rasters
   * @exception IOException if a write error occurs
   */
  public void writeInsert (int imageIndex, IIOImage image, ImageWriteParam param)
    throws IOException
  {
    if (!canInsertImage(imageIndex))
      throw new UnsupportedOperationException();
  }

  /**
   * Write a sequence of images, including thumbnails and metadata, to
   * the output stream.  The output must have been set prior to this
   * method being called.  Metadata associated with the stream may be
   * supplied, or it can be left null.  IIOImage may contain raster
   * data if this writer supports rasters, or it will contain a
   * rendered image.  Thumbnails are resized if need be.  Image
   * writing parameters may be specified to affect writing, or may be
   * left null.
   *
   * @param streamMetadata metadata associated with this stream, or
   * null
   * @param image an IIOImage containing image data, metadata and
   * thumbnails to be written
   * @param param image writing parameters, or null
   *
   * @exception IllegalStateException if output is null
   * @exception UnsupportedOperationException if writing sequences of
   * images is not supported
   * @exception IllegalArgumentException if image is null
   * @exception UnsupportedOperationException if image contains raster
   * data but this writer does not support rasters
   * @exception IOException if a write error occurs
   */
  public void writeToSequence (IIOImage image, ImageWriteParam param)
    throws IOException
  {
    if (!canWriteSequence())
      throw new UnsupportedOperationException();
  }
}
