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

package javax.imageio;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.awt.image.Raster;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import javax.imageio.event.IIOWriteWarningListener;
import javax.imageio.event.IIOWriteProgressListener;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.spi.ImageWriterSpi;

/**
 * An abstract superclass for encoding and writing images.  This class
 * must be subclassed by classes that write out images in the context
 * of the Java Image I/O framework.
 *
 * <p> <code>ImageWriter</code> objects are normally instantiated by
 * the service provider class for the specific format.  Service
 * provider classes are registered with the <code>IIORegistry</code>,
 * which uses them for format recognition and presentation of
 * available format readers and writers.
 *
 * <p>
 *
 * @see ImageReader
 * @see ImageWriteParam
 * @see javax.imageio.spi.IIORegistry
 * @see javax.imageio.spi.ImageWriterSpi
 *
 */
public abstract class ImageWriter implements ImageTranscoder {

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

    /**
     * The <code>ImageOutputStream</code> or other <code>Object</code>
     * set by <code>setOutput</code> and retrieved by
     * <code>getOutput</code>.  By default it is initialized to
     * <code>null</code>.
     */
    protected Object output = null;

    /**
     * An array of <code>Locale</code>s that may be used to localize
     * warning messages and compression setting values, or
     * <code>null</code> if localization is not supported.  By default
     * it is initialized to <code>null</code>.
     */
    protected Locale[] availableLocales = null;

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

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

    /**
     * A <code>List</code> of <code>Locale</code>s, one for each
     * element of <code>warningListeners</code>, initialized by default
     * <code>null</code>, which is synonymous with an empty
     * <code>List</code>.
     */
    protected List<Locale> warningLocales = null;

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

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

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

    /**
     * Returns the <code>ImageWriterSpi</code> object that created
     * this <code>ImageWriter</code>, or <code>null</code> if this
     * object was not created through the <code>IIORegistry</code>.
     *
     * <p> The default implementation returns the value of the
     * <code>originatingProvider</code> instance variable.
     *
     * @return an <code>ImageWriterSpi</code>, or <code>null</code>.
     *
     * @see ImageWriterSpi
     */
    public ImageWriterSpi getOriginatingProvider() {
        return originatingProvider;
    }

    /**
     * Sets the destination to the given
     * <code>ImageOutputStream</code> or other <code>Object</code>.
     * The destination is assumed to be ready to accept data, and will
     * not be closed at the end of each write. This allows distributed
     * imaging applications to transmit a series of images over a
     * single network connection.  If <code>output</code> is
     * <code>null</code>, any currently set output will be removed.
     *
     * <p> If <code>output</code> is an
     * <code>ImageOutputStream</code>, calls to the
     * <code>write</code>, <code>writeToSequence</code>, and
     * <code>prepareWriteEmpty</code>/<code>endWriteEmpty</code>
     * methods will preserve the existing contents of the stream.
     * Other write methods, such as <code>writeInsert</code>,
     * <code>replaceStreamMetadata</code>,
     * <code>replaceImageMetadata</code>, <code>replacePixels</code>,
     * <code>prepareInsertEmpty</code>/<code>endInsertEmpty</code>,
     * and <code>endWriteSequence</code>, require the full contents
     * of the stream to be readable and writable, and may alter any
     * portion of the stream.
     *
     * <p> Use of a general <code>Object</code> other than an
     * <code>ImageOutputStream</code> is intended for writers that
     * interact directly with an output device or imaging protocol.
     * The set of legal classes is advertised by the writer's service
     * provider's <code>getOutputTypes</code> method; most writers
     * will return a single-element array containing only
     * <code>ImageOutputStream.class</code> to indicate that they
     * accept only an <code>ImageOutputStream</code>.
     *
     * <p> The default implementation sets the <code>output</code>
     * instance variable to the value of <code>output</code> after
     * checking <code>output</code> against the set of classes
     * advertised by the originating provider, if there is one.
     *
     * @param output the <code>ImageOutputStream</code> or other
     * <code>Object</code> to use for future writing.
     *
     * @exception IllegalArgumentException if <code>output</code> is
     * not an instance of one of the classes returned by the
     * originating service provider's <code>getOutputTypes</code>
     * method.
     *
     * @see #getOutput
     */
    public void setOutput(Object output) {
        if (output != null) {
            ImageWriterSpi provider = getOriginatingProvider();
            if (provider != null) {
                Class[] classes = provider.getOutputTypes();
                boolean found = false;
                for (int i = 0; i < classes.length; i++) {
                    if (classes[i].isInstance(output)) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    throw new IllegalArgumentException("Illegal output type!");
                }
            }
        }

        this.output = output;
    }

    /**
     * Returns the <code>ImageOutputStream</code> or other
     * <code>Object</code> set by the most recent call to the
     * <code>setOutput</code> method.  If no destination has been
     * set, <code>null</code> is returned.
     *
     * <p> The default implementation returns the value of the
     * <code>output</code> instance variable.
     *
     * @return the <code>Object</code> that was specified using
     * <code>setOutput</code>, or <code>null</code>.
     *
     * @see #setOutput
     */
    public Object getOutput() {
        return output;
    }

    // Localization

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

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

    /**
     * Returns the currently set <code>Locale</code>, or
     * <code>null</code> if none has been set.
     *
     * <p> The default implementation returns the value of the
     * <code>locale</code> instance variable.
     *
     * @return the current <code>Locale</code>, or <code>null</code>.
     *
     * @see #setLocale
     */
    public Locale getLocale() {
        return locale;
    }

    // Write params

    /**
     * Returns a new <code>ImageWriteParam</code> object of the
     * appropriate type for this file format containing default
     * values, that is, those values that would be used
     * if no <code>ImageWriteParam</code> object were specified.  This
     * is useful as a starting point for tweaking just a few parameters
     * and otherwise leaving the default settings alone.
     *
     * <p> The default implementation constructs and returns a new
     * <code>ImageWriteParam</code> object that does not allow tiling,
     * progressive encoding, or compression, and that will be
     * localized for the current <code>Locale</code> (<i>i.e.</i>,
     * what you would get by calling <code>new
     * ImageWriteParam(getLocale())</code>.
     *
     * <p> Individual plug-ins may return an instance of
     * <code>ImageWriteParam</code> with additional optional features
     * enabled, or they may return an instance of a plug-in specific
     * subclass of <code>ImageWriteParam</code>.
     *
     * @return a new <code>ImageWriteParam</code> object containing
     * default values.
     */
    public ImageWriteParam getDefaultWriteParam() {
        return new ImageWriteParam(getLocale());
    }

    // Metadata

    /**
     * Returns an <code>IIOMetadata</code> object containing default
     * values for encoding a stream of images.  The contents of the
     * object may be manipulated using either the XML tree structure
     * returned by the <code>IIOMetadata.getAsTree</code> method, an
     * <code>IIOMetadataController</code> object, or via plug-in
     * specific interfaces, and the resulting data supplied to one of
     * the <code>write</code> methods that take a stream metadata
     * parameter.
     *
     * <p> An optional <code>ImageWriteParam</code> may be supplied
     * for cases where it may affect the structure of the stream
     * metadata.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * <p> Writers that do not make use of stream metadata
     * (<i>e.g.</i>, writers for single-image formats) should return
     * <code>null</code>.
     *
     * @param param an <code>ImageWriteParam</code> that will be used to
     * encode the image, or <code>null</code>.
     *
     * @return an <code>IIOMetadata</code> object.
     */
    public abstract IIOMetadata
        getDefaultStreamMetadata(ImageWriteParam param);

    /**
     * Returns an <code>IIOMetadata</code> object containing default
     * values for encoding an image of the given type.  The contents
     * of the object may be manipulated using either the XML tree
     * structure returned by the <code>IIOMetadata.getAsTree</code>
     * method, an <code>IIOMetadataController</code> object, or via
     * plug-in specific interfaces, and the resulting data supplied to
     * one of the <code>write</code> methods that take a stream
     * metadata parameter.
     *
     * <p> An optional <code>ImageWriteParam</code> may be supplied
     * for cases where it may affect the structure of the image
     * metadata.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * @param imageType an <code>ImageTypeSpecifier</code> indicating the
     * format of the image to be written later.
     * @param param an <code>ImageWriteParam</code> that will be used to
     * encode the image, or <code>null</code>.
     *
     * @return an <code>IIOMetadata</code> object.
     */
    public abstract IIOMetadata
        getDefaultImageMetadata(ImageTypeSpecifier imageType,
                                ImageWriteParam param);

    // comment inherited
    public abstract IIOMetadata convertStreamMetadata(IIOMetadata inData,
                                                      ImageWriteParam param);

    // comment inherited
    public abstract IIOMetadata
        convertImageMetadata(IIOMetadata inData,
                             ImageTypeSpecifier imageType,
                             ImageWriteParam param);

    // Thumbnails

    /**
     * Returns the number of thumbnails supported by the format being
     * written, given the image type and any additional write
     * parameters and metadata objects that will be used during
     * encoding.  A return value of <code>-1</code> indicates that
     * insufficient information is available.
     *
     * <p> An <code>ImageWriteParam</code> may optionally be supplied
     * for cases where it may affect thumbnail handling.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * <p> The default implementation returns 0.
     *
     * @param imageType an <code>ImageTypeSpecifier</code> indicating
     * the type of image to be written, or <code>null</code>.
     * @param param the <code>ImageWriteParam</code> that will be used for
     * writing, or <code>null</code>.
     * @param streamMetadata an <code>IIOMetadata</code> object that will
     * be used for writing, or <code>null</code>.
     * @param imageMetadata an <code>IIOMetadata</code> object that will
     * be used for writing, or <code>null</code>.
     *
     * @return the number of thumbnails that may be written given the
     * supplied parameters, or <code>-1</code> if insufficient
     * information is available.
     */
    public int getNumThumbnailsSupported(ImageTypeSpecifier imageType,
                                         ImageWriteParam param,
                                         IIOMetadata streamMetadata,
                                         IIOMetadata imageMetadata) {
        return 0;
    }

    /**
     * Returns an array of <code>Dimension</code>s indicating the
     * legal size ranges for thumbnail images as they will be encoded
     * in the output file or stream.  This information is merely
     * advisory; the writer will resize any supplied thumbnails as
     * necessary.
     *
     * <p> The information is returned as a set of pairs; the first
     * element of a pair contains an (inclusive) minimum width and
     * height, and the second element contains an (inclusive) maximum
     * width and height.  Together, each pair defines a valid range of
     * sizes.  To specify a fixed size, the same width and height will
     * appear for both elements.  A return value of <code>null</code>
     * indicates that the size is arbitrary or unknown.
     *
     * <p> An <code>ImageWriteParam</code> may optionally be supplied
     * for cases where it may affect thumbnail handling.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * <p> The default implementation returns <code>null</code>.
     *
     * @param imageType an <code>ImageTypeSpecifier</code> indicating the
     * type of image to be written, or <code>null</code>.
     * @param param the <code>ImageWriteParam</code> that will be used for
     * writing, or <code>null</code>.
     * @param streamMetadata an <code>IIOMetadata</code> object that will
     * be used for writing, or <code>null</code>.
     * @param imageMetadata an <code>IIOMetadata</code> object that will
     * be used for writing, or <code>null</code>.
     *
     * @return an array of <code>Dimension</code>s with an even length
     * of at least two, or <code>null</code>.
     */
    public Dimension[] getPreferredThumbnailSizes(ImageTypeSpecifier imageType,
                                                  ImageWriteParam param,
                                                  IIOMetadata streamMetadata,
                                                  IIOMetadata imageMetadata) {
        return null;
    }

    /**
     * Returns <code>true</code> if the methods that take an
     * <code>IIOImage</code> parameter are capable of dealing with a
     * <code>Raster</code> (as opposed to <code>RenderedImage</code>)
     * source image.  If this method returns <code>false</code>, then
     * those methods will throw an
     * <code>UnsupportedOperationException</code> if supplied with an
     * <code>IIOImage</code> containing a <code>Raster</code>.
     *
     * <p> The default implementation returns <code>false</code>.
     *
     * @return <code>true</code> if <code>Raster</code> sources are
     * supported.
     */
    public boolean canWriteRasters() {
        return false;
    }

    /**
     * Appends a complete image stream containing a single image and
     * associated stream and image metadata and thumbnails to the
     * output.  Any necessary header information is included.  If the
     * output is an <code>ImageOutputStream</code>, its existing
     * contents prior to the current seek position are not affected,
     * and need not be readable or writable.
     *
     * <p> The output must have been set beforehand using the
     * <code>setOutput</code> method.
     *
     * <p> Stream metadata may optionally be supplied; if it is
     * <code>null</code>, default stream metadata will be used.
     *
     * <p> If <code>canWriteRasters</code> returns <code>true</code>,
     * the <code>IIOImage</code> may contain a <code>Raster</code>
     * source.  Otherwise, it must contain a
     * <code>RenderedImage</code> source.
     *
     * <p> The supplied thumbnails will be resized if needed, and any
     * thumbnails in excess of the supported number will be ignored.
     * If the format requires additional thumbnails that are not
     * provided, the writer should generate them internally.
     *
     * <p>  An <code>ImageWriteParam</code> may
     * optionally be supplied to control the writing process.  If
     * <code>param</code> is <code>null</code>, a default write param
     * will be used.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * @param streamMetadata an <code>IIOMetadata</code> object representing
     * stream metadata, or <code>null</code> to use default values.
     * @param image an <code>IIOImage</code> object containing an
     * image, thumbnails, and metadata to be written.
     * @param param an <code>ImageWriteParam</code>, or
     * <code>null</code> to use a default
     * <code>ImageWriteParam</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if <code>image</code>
     * contains a <code>Raster</code> and <code>canWriteRasters</code>
     * returns <code>false</code>.
     * @exception IllegalArgumentException if <code>image</code> is
     * <code>null</code>.
     * @exception IOException if an error occurs during writing.
     */
    public abstract void write(IIOMetadata streamMetadata,
                               IIOImage image,
                               ImageWriteParam param) throws IOException;

    /**
     * Appends a complete image stream containing a single image with
     * default metadata and thumbnails to the output.  This method is
     * a shorthand for <code>write(null, image, null)</code>.
     *
     * @param image an <code>IIOImage</code> object containing an
     * image, thumbnails, and metadata to be written.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception IllegalArgumentException if <code>image</code> is
     * <code>null</code>.
     * @exception UnsupportedOperationException if <code>image</code>
     * contains a <code>Raster</code> and <code>canWriteRasters</code>
     * returns <code>false</code>.
     * @exception IOException if an error occurs during writing.
     */
    public void write(IIOImage image) throws IOException {
        write(null, image, null);
    }

    /**
     * Appends a complete image stream consisting of a single image
     * with default metadata and thumbnails to the output.  This
     * method is a shorthand for <code>write(null, new IIOImage(image,
     * null, null), null)</code>.
     *
     * @param image a <code>RenderedImage</code> to be written.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception IllegalArgumentException if <code>image</code> is
     * <code>null</code>.
     * @exception IOException if an error occurs during writing.
     */
    public void write(RenderedImage image) throws IOException {
        write(null, new IIOImage(image, null, null), null);
    }

    // Check that the output has been set, then throw an
    // UnsupportedOperationException.
    private void unsupported() {
        if (getOutput() == null) {
            throw new IllegalStateException("getOutput() == null!");
        }
        throw new UnsupportedOperationException("Unsupported write variant!");
    }

    // Sequence writes

    /**
     * Returns <code>true</code> if the writer is able to append an
     * image to an image stream that already contains header
     * information and possibly prior images.
     *
     * <p> If <code>canWriteSequence</code> returns <code>false</code>,
     * <code>writeToSequence</code> and <code>endWriteSequence</code>
     * will throw an <code>UnsupportedOperationException</code>.
     *
     * <p> The default implementation returns <code>false</code>.
     *
     * @return <code>true</code> if images may be appended sequentially.
     */
    public boolean canWriteSequence() {
        return false;
    }

    /**
     * Prepares a stream to accept a series of subsequent
     * <code>writeToSequence</code> calls, using the provided stream
     * metadata object.  The metadata will be written to the stream if
     * it should precede the image data.  If the argument is <code>null</code>,
     * default stream metadata is used.
     *
     * <p> If the output is an <code>ImageOutputStream</code>, the existing
     * contents of the output prior to the current seek position are
     * flushed, and need not be readable or writable.  If the format
     * requires that <code>endWriteSequence</code> be able to rewind to
     * patch up the header information, such as for a sequence of images
     * in a single TIFF file, then the metadata written by this method
     * must remain in a writable portion of the stream.  Other formats
     * may flush the stream after this method and after each image.
     *
     * <p> If <code>canWriteSequence</code> returns <code>false</code>,
     * this method will throw an
     * <code>UnsupportedOperationException</code>.
     *
     * <p> The output must have been set beforehand using either
     * the <code>setOutput</code> method.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param streamMetadata A stream metadata object, or <code>null</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canWriteSequence</code> returns <code>false</code>.
     * @exception IOException if an error occurs writing the stream
     * metadata.
     */
    public void prepareWriteSequence(IIOMetadata streamMetadata)
        throws IOException {
        unsupported();
    }

    /**
     * Appends a single image and possibly associated metadata and
     * thumbnails, to the output.  If the output is an
     * <code>ImageOutputStream</code>, the existing contents of the
     * output prior to the current seek position may be flushed, and
     * need not be readable or writable, unless the plug-in needs to
     * be able to patch up the header information when
     * <code>endWriteSequence</code> is called (<i>e.g.</i> TIFF).
     *
     * <p> If <code>canWriteSequence</code> returns <code>false</code>,
     * this method will throw an
     * <code>UnsupportedOperationException</code>.
     *
     * <p> The output must have been set beforehand using
     * the <code>setOutput</code> method.
     *
     * <p> <code>prepareWriteSequence</code> must have been called
     * beforehand, or an <code>IllegalStateException</code> is thrown.
     *
     * <p> If <code>canWriteRasters</code> returns <code>true</code>,
     * the <code>IIOImage</code> may contain a <code>Raster</code>
     * source.  Otherwise, it must contain a
     * <code>RenderedImage</code> source.
     *
     * <p> The supplied thumbnails will be resized if needed, and any
     * thumbnails in excess of the supported number will be ignored.
     * If the format requires additional thumbnails that are not
     * provided, the writer will generate them internally.
     *
     * <p> An <code>ImageWriteParam</code> may optionally be supplied
     * to control the writing process.  If <code>param</code> is
     * <code>null</code>, a default write param will be used.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param image an <code>IIOImage</code> object containing an
     * image, thumbnails, and metadata to be written.
     * @param param an <code>ImageWriteParam</code>, or
     * <code>null</code> to use a default
     * <code>ImageWriteParam</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set, or <code>prepareWriteSequence</code> has not been called.
     * @exception UnsupportedOperationException if
     * <code>canWriteSequence</code> returns <code>false</code>.
     * @exception IllegalArgumentException if <code>image</code> is
     * <code>null</code>.
     * @exception UnsupportedOperationException if <code>image</code>
     * contains a <code>Raster</code> and <code>canWriteRasters</code>
     * returns <code>false</code>.
     * @exception IOException if an error occurs during writing.
     */
    public void writeToSequence(IIOImage image, ImageWriteParam param)
        throws IOException {
        unsupported();
    }

    /**
     * Completes the writing of a sequence of images begun with
     * <code>prepareWriteSequence</code>.  Any stream metadata that
     * should come at the end of the sequence of images is written out,
     * and any header information at the beginning of the sequence is
     * patched up if necessary.  If the output is an
     * <code>ImageOutputStream</code>, data through the stream metadata
     * at the end of the sequence are flushed and need not be readable
     * or writable.
     *
     * <p> If <code>canWriteSequence</code> returns <code>false</code>,
     * this method will throw an
     * <code>UnsupportedOperationException</code>.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set, or <code>prepareWriteSequence</code> has not been called.
     * @exception UnsupportedOperationException if
     * <code>canWriteSequence</code> returns <code>false</code>.
     * @exception IOException if an error occurs during writing.
     */
    public void endWriteSequence() throws IOException {
        unsupported();
    }

    // Metadata replacement

    /**
     * Returns <code>true</code> if it is possible to replace the
     * stream metadata already present in the output.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise returns <code>false</code>.
     *
     * @return <code>true</code> if replacement of stream metadata is
     * allowed.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception IOException if an I/O error occurs during the query.
     */
    public boolean canReplaceStreamMetadata() throws IOException {
        if (getOutput() == null) {
            throw new IllegalStateException("getOutput() == null!");
        }
        return false;
    }

    /**
     * Replaces the stream metadata in the output with new
     * information.  If the output is an
     * <code>ImageOutputStream</code>, the prior contents of the
     * stream are examined and possibly edited to make room for the
     * new data.  All of the prior contents of the output must be
     * available for reading and writing.
     *
     * <p> If <code>canReplaceStreamMetadata</code> returns
     * <code>false</code>, an
     * <code>UnsupportedOperationException</code> will be thrown.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param streamMetadata an <code>IIOMetadata</code> object representing
     * stream metadata, or <code>null</code> to use default values.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if the
     * <code>canReplaceStreamMetadata</code> returns
     * <code>false</code>.  modes do not include
     * @exception IOException if an error occurs during writing.
     */
    public void replaceStreamMetadata(IIOMetadata streamMetadata)
        throws IOException {
        unsupported();
    }

    /**
     * Returns <code>true</code> if it is possible to replace the
     * image metadata associated with an existing image with index
     * <code>imageIndex</code>.  If this method returns
     * <code>false</code>, a call to
     * <code>replaceImageMetadata(imageIndex)</code> will throw an
     * <code>UnsupportedOperationException</code>.
     *
     * <p> A writer that does not support any image metadata
     * replacement may return <code>false</code> without performing
     * bounds checking on the index.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise returns <code>false</code>
     * without checking the value of <code>imageIndex</code>.
     *
     * @param imageIndex the index of the image whose metadata is to
     * be replaced.
     *
     * @return <code>true</code> if the image metadata of the given
     * image can be replaced.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception IndexOutOfBoundsException if the writer supports
     * image metadata replacement in general, but
     * <code>imageIndex</code> is less than 0 or greater than the
     * largest available index.
     * @exception IOException if an I/O error occurs during the query.
     */
    public boolean canReplaceImageMetadata(int imageIndex)
        throws IOException {
        if (getOutput() == null) {
            throw new IllegalStateException("getOutput() == null!");
        }
        return false;
    }

    /**
     * Replaces the image metadata associated with an existing image.
     *
     * <p> If <code>canReplaceImageMetadata(imageIndex)</code> returns
     * <code>false</code>, an
     * <code>UnsupportedOperationException</code> will be thrown.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param imageIndex the index of the image whose metadata is to
     * be replaced.
     * @param imageMetadata an <code>IIOMetadata</code> object
     * representing image metadata, or <code>null</code>.
     *
     * @exception IllegalStateException if the output has not been
     * set.
     * @exception UnsupportedOperationException if
     * <code>canReplaceImageMetadata</code> returns
     * <code>false</code>.
     * @exception IndexOutOfBoundsException if <code>imageIndex</code>
     * is less than 0 or greater than the largest available index.
     * @exception IOException if an error occurs during writing.
     */
    public void replaceImageMetadata(int imageIndex,
                                     IIOMetadata imageMetadata)
        throws IOException {
        unsupported();
    }

    // Image insertion

    /**
     * Returns <code>true</code> if the writer supports the insertion
     * of a new image at the given index.  Existing images with
     * indices greater than or equal to the insertion index will have
     * their indices increased by 1.  A value for
     * <code>imageIndex</code> of <code>-1</code> may be used to
     * signify an index one larger than the current largest index.
     *
     * <p> A writer that does not support any image insertion may
     * return <code>false</code> without performing bounds checking on
     * the index.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise returns <code>false</code>
     * without checking the value of <code>imageIndex</code>.
     *
     * @param imageIndex the index at which the image is to be
     * inserted.
     *
     * @return <code>true</code> if an image may be inserted at the
     * given index.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception IndexOutOfBoundsException if the writer supports
     * image insertion in general, but <code>imageIndex</code> is less
     * than -1 or greater than the largest available index.
     * @exception IOException if an I/O error occurs during the query.
     */
    public boolean canInsertImage(int imageIndex) throws IOException {
        if (getOutput() == null) {
            throw new IllegalStateException("getOutput() == null!");
        }
        return false;
    }

    /**
     * Inserts a new image into an existing image stream.  Existing
     * images with an index greater than <code>imageIndex</code> are
     * preserved, and their indices are each increased by 1.  A value
     * for <code>imageIndex</code> of -1 may be used to signify an
     * index one larger than the previous largest index; that is, it
     * will cause the image to be logically appended to the end of the
     * sequence.  If the output is an <code>ImageOutputStream</code>,
     * the entirety of the stream must be both readable and writeable.
     *
     * <p> If <code>canInsertImage(imageIndex)</code> returns
     * <code>false</code>, an
     * <code>UnsupportedOperationException</code> will be thrown.
     *
     * <p> An <code>ImageWriteParam</code> may optionally be supplied
     * to control the writing process.  If <code>param</code> is
     * <code>null</code>, a default write param will be used.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param imageIndex the index at which to write the image.
     * @param image an <code>IIOImage</code> object containing an
     * image, thumbnails, and metadata to be written.
     * @param param an <code>ImageWriteParam</code>, or
     * <code>null</code> to use a default
     * <code>ImageWriteParam</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canInsertImage(imageIndex)</code> returns <code>false</code>.
     * @exception IllegalArgumentException if <code>image</code> is
     * <code>null</code>.
     * @exception IndexOutOfBoundsException if <code>imageIndex</code>
     * is less than -1 or greater than the largest available index.
     * @exception UnsupportedOperationException if <code>image</code>
     * contains a <code>Raster</code> and <code>canWriteRasters</code>
     * returns <code>false</code>.
     * @exception IOException if an error occurs during writing.
     */
    public void writeInsert(int imageIndex,
                            IIOImage image,
                            ImageWriteParam param) throws IOException {
        unsupported();
    }

    // Image removal

    /**
     * Returns <code>true</code> if the writer supports the removal
     * of an existing image at the given index.  Existing images with
     * indices greater than the insertion index will have
     * their indices decreased by 1.
     *
     * <p> A writer that does not support any image removal may
     * return <code>false</code> without performing bounds checking on
     * the index.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise returns <code>false</code>
     * without checking the value of <code>imageIndex</code>.
     *
     * @param imageIndex the index of the image to be removed.
     *
     * @return <code>true</code> if it is possible to remove the given
     * image.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception IndexOutOfBoundsException if the writer supports
     * image removal in general, but <code>imageIndex</code> is less
     * than 0 or greater than the largest available index.
     * @exception IOException if an I/O error occurs during the
     * query.
     */
    public boolean canRemoveImage(int imageIndex) throws IOException {
        if (getOutput() == null) {
            throw new IllegalStateException("getOutput() == null!");
        }
        return false;
    }

    /**
     * Removes an image from the stream.
     *
     * <p> If <code>canRemoveImage(imageIndex)</code> returns false,
     * an <code>UnsupportedOperationException</code>will be thrown.
     *
     * <p> The removal may or may not cause a reduction in the actual
     * file size.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param imageIndex the index of the image to be removed.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canRemoveImage(imageIndex)</code> returns <code>false</code>.
     * @exception IndexOutOfBoundsException if <code>imageIndex</code>
     * is less than 0 or greater than the largest available index.
     * @exception IOException if an I/O error occurs during the
     * removal.
     */
    public void removeImage(int imageIndex) throws IOException {
        unsupported();
    }

    // Empty images

    /**
     * Returns <code>true</code> if the writer supports the writing of
     * a complete image stream consisting of a single image with
     * undefined pixel values and associated metadata and thumbnails
     * to the output.  The pixel values may be defined by future
     * calls to the <code>replacePixels</code> methods.  If the output
     * is an <code>ImageOutputStream</code>, its existing contents
     * prior to the current seek position are not affected, and need
     * not be readable or writable.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise returns <code>false</code>.
     *
     * @return <code>true</code> if the writing of complete image
     * stream with contents to be defined later is supported.
     *
     * @exception IllegalStateException if the output has not been
     * set.
     * @exception IOException if an I/O error occurs during the
     * query.
     */
    public boolean canWriteEmpty() throws IOException {
        if (getOutput() == null) {
            throw new IllegalStateException("getOutput() == null!");
        }
        return false;
    }

    /**
     * Begins the writing of a complete image stream, consisting of a
     * single image with undefined pixel values and associated
     * metadata and thumbnails, to the output.  The pixel values will
     * be defined by future calls to the <code>replacePixels</code>
     * methods.  If the output is an <code>ImageOutputStream</code>,
     * its existing contents prior to the current seek position are
     * not affected, and need not be readable or writable.
     *
     * <p> The writing is not complete until a call to
     * <code>endWriteEmpty</code> occurs.  Calls to
     * <code>prepareReplacePixels</code>, <code>replacePixels</code>,
     * and <code>endReplacePixels</code> may occur between calls to
     * <code>prepareWriteEmpty</code> and <code>endWriteEmpty</code>.
     * However, calls to <code>prepareWriteEmpty</code> cannot be
     * nested, and calls to <code>prepareWriteEmpty</code> and
     * <code>prepareInsertEmpty</code> may not be interspersed.
     *
     * <p> If <code>canWriteEmpty</code> returns <code>false</code>,
     * an <code>UnsupportedOperationException</code> will be thrown.
     *
     * <p> An <code>ImageWriteParam</code> may optionally be supplied
     * to control the writing process.  If <code>param</code> is
     * <code>null</code>, a default write param will be used.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param streamMetadata an <code>IIOMetadata</code> object representing
     * stream metadata, or <code>null</code> to use default values.
     * @param imageType an <code>ImageTypeSpecifier</code> describing
     * the layout of the image.
     * @param width the width of the image.
     * @param height the height of the image.
     * @param imageMetadata an <code>IIOMetadata</code> object
     * representing image metadata, or <code>null</code>.
     * @param thumbnails a <code>List</code> of
     * <code>BufferedImage</code> thumbnails for this image, or
     * <code>null</code>.
     * @param param an <code>ImageWriteParam</code>, or
     * <code>null</code> to use a default
     * <code>ImageWriteParam</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canWriteEmpty</code> returns <code>false</code>.
     * @exception IllegalStateException if a previous call to
     * <code>prepareWriteEmpty</code> has been made without a
     * corresponding call to <code>endWriteEmpty</code>.
     * @exception IllegalStateException if a previous call to
     * <code>prepareInsertEmpty</code> has been made without a
     * corresponding call to <code>endInsertEmpty</code>.
     * @exception IllegalArgumentException if <code>imageType</code>
     * is <code>null</code> or <code>thumbnails</code> contains
     * <code>null</code> references or objects other than
     * <code>BufferedImage</code>s.
     * @exception IllegalArgumentException if width or height are less
     * than 1.
     * @exception IOException if an I/O error occurs during writing.
     */
    public void prepareWriteEmpty(IIOMetadata streamMetadata,
                                  ImageTypeSpecifier imageType,
                                  int width, int height,
                                  IIOMetadata imageMetadata,
                                  List<? extends BufferedImage> thumbnails,
                                  ImageWriteParam param) throws IOException {
        unsupported();
    }

    /**
     * Completes the writing of a new image that was begun with a
     * prior call to <code>prepareWriteEmpty</code>.
     *
     * <p> If <code>canWriteEmpty()</code> returns <code>false</code>,
     * an <code>UnsupportedOperationException</code> will be thrown.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canWriteEmpty(imageIndex)</code> returns
     * <code>false</code>.
     * @exception IllegalStateException if a previous call to
     * <code>prepareWriteEmpty</code> without a corresponding call to
     * <code>endWriteEmpty</code> has not been made.
     * @exception IllegalStateException if a previous call to
     * <code>prepareInsertEmpty</code> without a corresponding call to
     * <code>endInsertEmpty</code> has been made.
     * @exception IllegalStateException if a call to
     * <code>prepareReiplacePixels</code> has been made without a
     * matching call to <code>endReplacePixels</code>.
     * @exception IOException if an I/O error occurs during writing.
     */
    public void endWriteEmpty() throws IOException {
        if (getOutput() == null) {
            throw new IllegalStateException("getOutput() == null!");
        }
        throw new IllegalStateException("No call to prepareWriteEmpty!");
    }

    /**
     * Returns <code>true</code> if the writer supports the insertion
     * of a new, empty image at the given index.  The pixel values of
     * the image are undefined, and may be specified in pieces using
     * the <code>replacePixels</code> methods.  Existing images with
     * indices greater than or equal to the insertion index will have
     * their indices increased by 1.  A value for
     * <code>imageIndex</code> of <code>-1</code> may be used to
     * signify an index one larger than the current largest index.
     *
     * <p> A writer that does not support insertion of empty images
     * may return <code>false</code> without performing bounds
     * checking on the index.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise returns <code>false</code>
     * without checking the value of <code>imageIndex</code>.
     *
     * @param imageIndex the index at which the image is to be
     * inserted.
     *
     * @return <code>true</code> if an empty image may be inserted at
     * the given index.
     *
     * @exception IllegalStateException if the output has not been
     * set.
     * @exception IndexOutOfBoundsException if the writer supports
     * empty image insertion in general, but <code>imageIndex</code>
     * is less than -1 or greater than the largest available index.
     * @exception IOException if an I/O error occurs during the
     * query.
     */
    public boolean canInsertEmpty(int imageIndex) throws IOException {
        if (getOutput() == null) {
            throw new IllegalStateException("getOutput() == null!");
        }
        return false;
    }

    /**
     * Begins the insertion of a new image with undefined pixel values
     * into an existing image stream.  Existing images with an index
     * greater than <code>imageIndex</code> are preserved, and their
     * indices are each increased by 1.  A value for
     * <code>imageIndex</code> of -1 may be used to signify an index
     * one larger than the previous largest index; that is, it will
     * cause the image to be logically appended to the end of the
     * sequence.  If the output is an <code>ImageOutputStream</code>,
     * the entirety of the stream must be both readable and writeable.
     *
     * <p> The image contents may be
     * supplied later using the <code>replacePixels</code> method.
     * The insertion is not complete until a call to
     * <code>endInsertEmpty</code> occurs.  Calls to
     * <code>prepareReplacePixels</code>, <code>replacePixels</code>,
     * and <code>endReplacePixels</code> may occur between calls to
     * <code>prepareInsertEmpty</code> and
     * <code>endInsertEmpty</code>.  However, calls to
     * <code>prepareInsertEmpty</code> cannot be nested, and calls to
     * <code>prepareWriteEmpty</code> and
     * <code>prepareInsertEmpty</code> may not be interspersed.
     *
     * <p> If <code>canInsertEmpty(imageIndex)</code> returns
     * <code>false</code>, an
     * <code>UnsupportedOperationException</code> will be thrown.
     *
     * <p> An <code>ImageWriteParam</code> may optionally be supplied
     * to control the writing process.  If <code>param</code> is
     * <code>null</code>, a default write param will be used.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param imageIndex the index at which to write the image.
     * @param imageType an <code>ImageTypeSpecifier</code> describing
     * the layout of the image.
     * @param width the width of the image.
     * @param height the height of the image.
     * @param imageMetadata an <code>IIOMetadata</code> object
     * representing image metadata, or <code>null</code>.
     * @param thumbnails a <code>List</code> of
     * <code>BufferedImage</code> thumbnails for this image, or
     * <code>null</code>.
     * @param param an <code>ImageWriteParam</code>, or
     * <code>null</code> to use a default
     * <code>ImageWriteParam</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canInsertEmpty(imageIndex)</code> returns
     * <code>false</code>.
     * @exception IndexOutOfBoundsException if <code>imageIndex</code>
     * is less than -1 or greater than the largest available index.
     * @exception IllegalStateException if a previous call to
     * <code>prepareInsertEmpty</code> has been made without a
     * corresponding call to <code>endInsertEmpty</code>.
     * @exception IllegalStateException if a previous call to
     * <code>prepareWriteEmpty</code> has been made without a
     * corresponding call to <code>endWriteEmpty</code>.
     * @exception IllegalArgumentException if <code>imageType</code>
     * is <code>null</code> or <code>thumbnails</code> contains
     * <code>null</code> references or objects other than
     * <code>BufferedImage</code>s.
     * @exception IllegalArgumentException if width or height are less
     * than 1.
     * @exception IOException if an I/O error occurs during writing.
     */
    public void prepareInsertEmpty(int imageIndex,
                                   ImageTypeSpecifier imageType,
                                   int width, int height,
                                   IIOMetadata imageMetadata,
                                   List<? extends BufferedImage> thumbnails,
                                   ImageWriteParam param) throws IOException {
        unsupported();
    }

    /**
     * Completes the insertion of a new image that was begun with a
     * prior call to <code>prepareInsertEmpty</code>.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canInsertEmpty(imageIndex)</code> returns
     * <code>false</code>.
     * @exception IllegalStateException if a previous call to
     * <code>prepareInsertEmpty</code> without a corresponding call to
     * <code>endInsertEmpty</code> has not been made.
     * @exception IllegalStateException if a previous call to
     * <code>prepareWriteEmpty</code> without a corresponding call to
     * <code>endWriteEmpty</code> has been made.
     * @exception IllegalStateException if a call to
     * <code>prepareReplacePixels</code> has been made without a
     * matching call to <code>endReplacePixels</code>.
     * @exception IOException if an I/O error occurs during writing.
     */
    public void endInsertEmpty() throws IOException {
        unsupported();
    }

    // Pixel replacement

    /**
     * Returns <code>true</code> if the writer allows pixels of the
     * given image to be replaced using the <code>replacePixels</code>
     * methods.
     *
     * <p> A writer that does not support any pixel replacement may
     * return <code>false</code> without performing bounds checking on
     * the index.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise returns <code>false</code>
     * without checking the value of <code>imageIndex</code>.
     *
     * @param imageIndex the index of the image whose pixels are to be
     * replaced.
     *
     * @return <code>true</code> if the pixels of the given
     * image can be replaced.
     *
     * @exception IllegalStateException if the output has not been
     * set.
     * @exception IndexOutOfBoundsException if the writer supports
     * pixel replacement in general, but <code>imageIndex</code> is
     * less than 0 or greater than the largest available index.
     * @exception IOException if an I/O error occurs during the query.
     */
    public boolean canReplacePixels(int imageIndex) throws IOException {
        if (getOutput() == null) {
            throw new IllegalStateException("getOutput() == null!");
        }
        return false;
    }

    /**
     * Prepares the writer to handle a series of calls to the
     * <code>replacePixels</code> methods.  The affected pixel area
     * will be clipped against the supplied
     *
     * <p> If <code>canReplacePixels</code> returns
     * <code>false</code>, and
     * <code>UnsupportedOperationException</code> will be thrown.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param imageIndex the index of the image whose pixels are to be
     * replaced.
     * @param region a <code>Rectangle</code> that will be used to clip
     * future pixel regions.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canReplacePixels(imageIndex)</code> returns
     * <code>false</code>.
     * @exception IndexOutOfBoundsException if <code>imageIndex</code>
     * is less than 0 or greater than the largest available index.
     * @exception IllegalStateException if there is a previous call to
     * <code>prepareReplacePixels</code> without a matching call to
     * <code>endReplacePixels</code> (<i>i.e.</i>, nesting is not
     * allowed).
     * @exception IllegalArgumentException if <code>region</code> is
     * <code>null</code> or has a width or height less than 1.
     * @exception IOException if an I/O error occurs during the
     * preparation.
     */
    public void prepareReplacePixels(int imageIndex,
                                     Rectangle region)  throws IOException {
        unsupported();
    }

    /**
     * Replaces a portion of an image already present in the output
     * with a portion of the given image.  The image data must match,
     * or be convertible to, the image layout of the existing image.
     *
     * <p> The destination region is specified in the
     * <code>param</code> argument, and will be clipped to the image
     * boundaries and the region supplied to
     * <code>prepareReplacePixels</code>.  At least one pixel of the
     * source must not be clipped, or an exception is thrown.
     *
     * <p> An <code>ImageWriteParam</code> may optionally be supplied
     * to control the writing process.  If <code>param</code> is
     * <code>null</code>, a default write param will be used.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * <p> This method may only be called after a call to
     * <code>prepareReplacePixels</code>, or else an
     * <code>IllegalStateException</code> will be thrown.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param image a <code>RenderedImage</code> containing source
     * pixels.
     * @param param an <code>ImageWriteParam</code>, or
     * <code>null</code> to use a default
     * <code>ImageWriteParam</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canReplacePixels(imageIndex)</code> returns
     * <code>false</code>.
     * @exception IllegalStateException if there is no previous call to
     * <code>prepareReplacePixels</code> without a matching call to
     * <code>endReplacePixels</code>.
     * @exception IllegalArgumentException if any of the following are true:
     * <ul>
     * <li> <code>image</code> is <code>null</code>.
     * <li> <code>param</code> is <code>null</code>.
     * <li> the intersected region does not contain at least one pixel.
     * <li> the layout of <code>image</code> does not match, or this
     * writer cannot convert it to, the existing image layout.
     * </ul>
     * @exception IOException if an I/O error occurs during writing.
     */
    public void replacePixels(RenderedImage image, ImageWriteParam param)
        throws IOException {
        unsupported();
    }

    /**
     * Replaces a portion of an image already present in the output
     * with a portion of the given <code>Raster</code>.  The image
     * data must match, or be convertible to, the image layout of the
     * existing image.
     *
     * <p> An <code>ImageWriteParam</code> may optionally be supplied
     * to control the writing process.  If <code>param</code> is
     * <code>null</code>, a default write param will be used.
     *
     * <p> The destination region is specified in the
     * <code>param</code> argument, and will be clipped to the image
     * boundaries and the region supplied to
     * <code>prepareReplacePixels</code>.  At least one pixel of the
     * source must not be clipped, or an exception is thrown.
     *
     * <p> If the supplied <code>ImageWriteParam</code> contains
     * optional setting values not supported by this writer (<i>e.g.</i>
     * progressive encoding or any format-specific settings), they
     * will be ignored.
     *
     * <p> This method may only be called after a call to
     * <code>prepareReplacePixels</code>, or else an
     * <code>IllegalStateException</code> will be thrown.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @param raster a <code>Raster</code> containing source
     * pixels.
     * @param param an <code>ImageWriteParam</code>, or
     * <code>null</code> to use a default
     * <code>ImageWriteParam</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canReplacePixels(imageIndex)</code> returns
     * <code>false</code>.
     * @exception IllegalStateException if there is no previous call to
     * <code>prepareReplacePixels</code> without a matching call to
     * <code>endReplacePixels</code>.
     * @exception UnsupportedOperationException if
     * <code>canWriteRasters</code> returns <code>false</code>.
     * @exception IllegalArgumentException if any of the following are true:
     * <ul>
     * <li> <code>raster</code> is <code>null</code>.
     * <li> <code>param</code> is <code>null</code>.
     * <li> the intersected region does not contain at least one pixel.
     * <li> the layout of <code>raster</code> does not match, or this
     * writer cannot convert it to, the existing image layout.
     * </ul>
     * @exception IOException if an I/O error occurs during writing.
     */
    public void replacePixels(Raster raster, ImageWriteParam param)
        throws IOException {
        unsupported();
    }

    /**
     * Terminates a sequence of calls to <code>replacePixels</code>.
     *
     * <p> If <code>canReplacePixels</code> returns
     * <code>false</code>, and
     * <code>UnsupportedOperationException</code> will be thrown.
     *
     * <p> The default implementation throws an
     * <code>IllegalStateException</code> if the output is
     * <code>null</code>, and otherwise throws an
     * <code>UnsupportedOperationException</code>.
     *
     * @exception IllegalStateException if the output has not
     * been set.
     * @exception UnsupportedOperationException if
     * <code>canReplacePixels(imageIndex)</code> returns
     * <code>false</code>.
     * @exception IllegalStateException if there is no previous call
     * to <code>prepareReplacePixels</code> without a matching call to
     * <code>endReplacePixels</code>.
     * @exception IOException if an I/O error occurs during writing.
     */
    public void endReplacePixels() throws IOException {
        unsupported();
    }

    // Abort

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

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

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

    // Listeners

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            listener.warningOccurred(this, imageIndex, warning);
        }
    }

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

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

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

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

            listener.warningOccurred(this, imageIndex, warning);
        }
    }

    // State management

    /**
     * Restores the <code>ImageWriter</code> to its initial state.
     *
     * <p> The default implementation calls
     * <code>setOutput(null)</code>, <code>setLocale(null)</code>,
     * <code>removeAllIIOWriteWarningListeners()</code>,
     * <code>removeAllIIOWriteProgressListeners()</code>, and
     * <code>clearAbortRequest</code>.
     */
    public void reset() {
        setOutput(null);
        setLocale(null);
        removeAllIIOWriteWarningListeners();
        removeAllIIOWriteProgressListeners();
        clearAbortRequest();
    }

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