/* | 
|
 * 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() { | 
|
}  | 
|
}  |