/* * Copyright (c) 1999, 2014, 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. * *

ImageWriter objects are normally instantiated by * the service provider class for the specific format. Service * provider classes are registered with the IIORegistry, * which uses them for format recognition and presentation of * available format readers and writers. * * @see ImageReader * @see ImageWriteParam * @see javax.imageio.spi.IIORegistry * @see javax.imageio.spi.ImageWriterSpi * */ public abstract class ImageWriter implements ImageTranscoder { /** * The ImageWriterSpi that instantiated this object, * or null if its identity is not known or none * exists. By default it is initialized to null. */ protected ImageWriterSpi originatingProvider = null; /** * The ImageOutputStream or other Object * set by setOutput and retrieved by * getOutput. By default it is initialized to * null. */ protected Object output = null; /** * An array of Locales that may be used to localize * warning messages and compression setting values, or * null if localization is not supported. By default * it is initialized to null. */ protected Locale[] availableLocales = null; /** * The current Locale to be used for localization, or * null if none has been set. By default it is * initialized to null. */ protected Locale locale = null; /** * A List of currently registered * IIOWriteWarningListeners, initialized by default to * null, which is synonymous with an empty * List. */ protected List warningListeners = null; /** * A List of Locales, one for each * element of warningListeners, initialized by default * null, which is synonymous with an empty * List. */ protected List warningLocales = null; /** * A List of currently registered * IIOWriteProgressListeners, initialized by default * null, which is synonymous with an empty * List. */ protected List progressListeners = null; /** * If true, the current write operation should be * aborted. */ private boolean abortFlag = false; /** * Constructs an ImageWriter and sets its * originatingProvider instance variable to the * supplied value. * *

Subclasses that make use of extensions should provide a * constructor with signature (ImageWriterSpi, * Object) in order to retrieve the extension object. If * the extension object is unsuitable, an * IllegalArgumentException should be thrown. * * @param originatingProvider the ImageWriterSpi that * is constructing this object, or null. */ protected ImageWriter(ImageWriterSpi originatingProvider) { this.originatingProvider = originatingProvider; } /** * Returns the ImageWriterSpi object that created * this ImageWriter, or null if this * object was not created through the IIORegistry. * *

The default implementation returns the value of the * originatingProvider instance variable. * * @return an ImageWriterSpi, or null. * * @see ImageWriterSpi */ public ImageWriterSpi getOriginatingProvider() { return originatingProvider; } /** * Sets the destination to the given * ImageOutputStream or other Object. * 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 output is * null, any currently set output will be removed. * *

If output is an * ImageOutputStream, calls to the * write, writeToSequence, and * prepareWriteEmpty/endWriteEmpty * methods will preserve the existing contents of the stream. * Other write methods, such as writeInsert, * replaceStreamMetadata, * replaceImageMetadata, replacePixels, * prepareInsertEmpty/endInsertEmpty, * and endWriteSequence, require the full contents * of the stream to be readable and writable, and may alter any * portion of the stream. * *

Use of a general Object other than an * ImageOutputStream 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 getOutputTypes method; most writers * will return a single-element array containing only * ImageOutputStream.class to indicate that they * accept only an ImageOutputStream. * *

The default implementation sets the output * instance variable to the value of output after * checking output against the set of classes * advertised by the originating provider, if there is one. * * @param output the ImageOutputStream or other * Object to use for future writing. * * @exception IllegalArgumentException if output is * not an instance of one of the classes returned by the * originating service provider's getOutputTypes * 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 ImageOutputStream or other * Object set by the most recent call to the * setOutput method. If no destination has been * set, null is returned. * *

The default implementation returns the value of the * output instance variable. * * @return the Object that was specified using * setOutput, or null. * * @see #setOutput */ public Object getOutput() { return output; } // Localization /** * Returns an array of Locales that may be used to * localize warning listeners and compression settings. A return * value of null indicates that localization is not * supported. * *

The default implementation returns a clone of the * availableLocales instance variable if it is * non-null, or else returns null. * * @return an array of Locales that may be used as * arguments to setLocale, or null. */ public Locale[] getAvailableLocales() { return (availableLocales == null) ? null : availableLocales.clone(); } /** * Sets the current Locale of this * ImageWriter to the given value. A value of * null removes any previous setting, and indicates * that the writer should localize as it sees fit. * *

The default implementation checks locale * against the values returned by * getAvailableLocales, and sets the * locale instance variable if it is found. If * locale is null, the instance variable * is set to null without any checking. * * @param locale the desired Locale, or * null. * * @exception IllegalArgumentException if locale is * non-null but is not one of the values returned by * getAvailableLocales. * * @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 Locale, or * null if none has been set. * *

The default implementation returns the value of the * locale instance variable. * * @return the current Locale, or null. * * @see #setLocale */ public Locale getLocale() { return locale; } // Write params /** * Returns a new ImageWriteParam object of the * appropriate type for this file format containing default * values, that is, those values that would be used * if no ImageWriteParam object were specified. This * is useful as a starting point for tweaking just a few parameters * and otherwise leaving the default settings alone. * *

The default implementation constructs and returns a new * ImageWriteParam object that does not allow tiling, * progressive encoding, or compression, and that will be * localized for the current Locale (i.e., * what you would get by calling new * ImageWriteParam(getLocale()). * *

Individual plug-ins may return an instance of * ImageWriteParam with additional optional features * enabled, or they may return an instance of a plug-in specific * subclass of ImageWriteParam. * * @return a new ImageWriteParam object containing * default values. */ public ImageWriteParam getDefaultWriteParam() { return new ImageWriteParam(getLocale()); } // Metadata /** * Returns an IIOMetadata 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 IIOMetadata.getAsTree method, an * IIOMetadataController object, or via plug-in * specific interfaces, and the resulting data supplied to one of * the write methods that take a stream metadata * parameter. * *

An optional ImageWriteParam may be supplied * for cases where it may affect the structure of the stream * metadata. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * *

Writers that do not make use of stream metadata * (e.g., writers for single-image formats) should return * null. * * @param param an ImageWriteParam that will be used to * encode the image, or null. * * @return an IIOMetadata object. */ public abstract IIOMetadata getDefaultStreamMetadata(ImageWriteParam param); /** * Returns an IIOMetadata 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 IIOMetadata.getAsTree * method, an IIOMetadataController object, or via * plug-in specific interfaces, and the resulting data supplied to * one of the write methods that take a stream * metadata parameter. * *

An optional ImageWriteParam may be supplied * for cases where it may affect the structure of the image * metadata. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * * @param imageType an ImageTypeSpecifier indicating the * format of the image to be written later. * @param param an ImageWriteParam that will be used to * encode the image, or null. * * @return an IIOMetadata 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 -1 indicates that * insufficient information is available. * *

An ImageWriteParam may optionally be supplied * for cases where it may affect thumbnail handling. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * *

The default implementation returns 0. * * @param imageType an ImageTypeSpecifier indicating * the type of image to be written, or null. * @param param the ImageWriteParam that will be used for * writing, or null. * @param streamMetadata an IIOMetadata object that will * be used for writing, or null. * @param imageMetadata an IIOMetadata object that will * be used for writing, or null. * * @return the number of thumbnails that may be written given the * supplied parameters, or -1 if insufficient * information is available. */ public int getNumThumbnailsSupported(ImageTypeSpecifier imageType, ImageWriteParam param, IIOMetadata streamMetadata, IIOMetadata imageMetadata) { return 0; } /** * Returns an array of Dimensions 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. * *

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 null * indicates that the size is arbitrary or unknown. * *

An ImageWriteParam may optionally be supplied * for cases where it may affect thumbnail handling. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * *

The default implementation returns null. * * @param imageType an ImageTypeSpecifier indicating the * type of image to be written, or null. * @param param the ImageWriteParam that will be used for * writing, or null. * @param streamMetadata an IIOMetadata object that will * be used for writing, or null. * @param imageMetadata an IIOMetadata object that will * be used for writing, or null. * * @return an array of Dimensions with an even length * of at least two, or null. */ public Dimension[] getPreferredThumbnailSizes(ImageTypeSpecifier imageType, ImageWriteParam param, IIOMetadata streamMetadata, IIOMetadata imageMetadata) { return null; } /** * Returns true if the methods that take an * IIOImage parameter are capable of dealing with a * Raster (as opposed to RenderedImage) * source image. If this method returns false, then * those methods will throw an * UnsupportedOperationException if supplied with an * IIOImage containing a Raster. * *

The default implementation returns false. * * @return true if Raster 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 ImageOutputStream, its existing * contents prior to the current seek position are not affected, * and need not be readable or writable. * *

The output must have been set beforehand using the * setOutput method. * *

Stream metadata may optionally be supplied; if it is * null, default stream metadata will be used. * *

If canWriteRasters returns true, * the IIOImage may contain a Raster * source. Otherwise, it must contain a * RenderedImage source. * *

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. * *

An ImageWriteParam may * optionally be supplied to control the writing process. If * param is null, a default write param * will be used. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * * @param streamMetadata an IIOMetadata object representing * stream metadata, or null to use default values. * @param image an IIOImage object containing an * image, thumbnails, and metadata to be written. * @param param an ImageWriteParam, or * null to use a default * ImageWriteParam. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if image * contains a Raster and canWriteRasters * returns false. * @exception IllegalArgumentException if image is * null. * @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 write(null, image, null). * * @param image an IIOImage object containing an * image, thumbnails, and metadata to be written. * * @exception IllegalStateException if the output has not * been set. * @exception IllegalArgumentException if image is * null. * @exception UnsupportedOperationException if image * contains a Raster and canWriteRasters * returns false. * @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 write(null, new IIOImage(image, * null, null), null). * * @param image a RenderedImage to be written. * * @exception IllegalStateException if the output has not * been set. * @exception IllegalArgumentException if image is * null. * @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 true if the writer is able to append an * image to an image stream that already contains header * information and possibly prior images. * *

If canWriteSequence returns false, * writeToSequence and endWriteSequence * will throw an UnsupportedOperationException. * *

The default implementation returns false. * * @return true if images may be appended sequentially. */ public boolean canWriteSequence() { return false; } /** * Prepares a stream to accept a series of subsequent * writeToSequence 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 null, * default stream metadata is used. * *

If the output is an ImageOutputStream, 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 endWriteSequence 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. * *

If canWriteSequence returns false, * this method will throw an * UnsupportedOperationException. * *

The output must have been set beforehand using either * the setOutput method. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param streamMetadata A stream metadata object, or null. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canWriteSequence returns false. * @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 * ImageOutputStream, 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 * endWriteSequence is called (e.g. TIFF). * *

If canWriteSequence returns false, * this method will throw an * UnsupportedOperationException. * *

The output must have been set beforehand using * the setOutput method. * *

prepareWriteSequence must have been called * beforehand, or an IllegalStateException is thrown. * *

If canWriteRasters returns true, * the IIOImage may contain a Raster * source. Otherwise, it must contain a * RenderedImage source. * *

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. * *

An ImageWriteParam may optionally be supplied * to control the writing process. If param is * null, a default write param will be used. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param image an IIOImage object containing an * image, thumbnails, and metadata to be written. * @param param an ImageWriteParam, or * null to use a default * ImageWriteParam. * * @exception IllegalStateException if the output has not * been set, or prepareWriteSequence has not been called. * @exception UnsupportedOperationException if * canWriteSequence returns false. * @exception IllegalArgumentException if image is * null. * @exception UnsupportedOperationException if image * contains a Raster and canWriteRasters * returns false. * @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 * prepareWriteSequence. 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 * ImageOutputStream, data through the stream metadata * at the end of the sequence are flushed and need not be readable * or writable. * *

If canWriteSequence returns false, * this method will throw an * UnsupportedOperationException. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @exception IllegalStateException if the output has not * been set, or prepareWriteSequence has not been called. * @exception UnsupportedOperationException if * canWriteSequence returns false. * @exception IOException if an error occurs during writing. */ public void endWriteSequence() throws IOException { unsupported(); } // Metadata replacement /** * Returns true if it is possible to replace the * stream metadata already present in the output. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise returns false. * * @return true 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 * ImageOutputStream, 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. * *

If canReplaceStreamMetadata returns * false, an * UnsupportedOperationException will be thrown. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param streamMetadata an IIOMetadata object representing * stream metadata, or null to use default values. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if the * canReplaceStreamMetadata returns * false. modes do not include * @exception IOException if an error occurs during writing. */ public void replaceStreamMetadata(IIOMetadata streamMetadata) throws IOException { unsupported(); } /** * Returns true if it is possible to replace the * image metadata associated with an existing image with index * imageIndex. If this method returns * false, a call to * replaceImageMetadata(imageIndex) will throw an * UnsupportedOperationException. * *

A writer that does not support any image metadata * replacement may return false without performing * bounds checking on the index. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise returns false * without checking the value of imageIndex. * * @param imageIndex the index of the image whose metadata is to * be replaced. * * @return true 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 * imageIndex 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. * *

If canReplaceImageMetadata(imageIndex) returns * false, an * UnsupportedOperationException will be thrown. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param imageIndex the index of the image whose metadata is to * be replaced. * @param imageMetadata an IIOMetadata object * representing image metadata, or null. * * @exception IllegalStateException if the output has not been * set. * @exception UnsupportedOperationException if * canReplaceImageMetadata returns * false. * @exception IndexOutOfBoundsException if imageIndex * 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 true 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 * imageIndex of -1 may be used to * signify an index one larger than the current largest index. * *

A writer that does not support any image insertion may * return false without performing bounds checking on * the index. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise returns false * without checking the value of imageIndex. * * @param imageIndex the index at which the image is to be * inserted. * * @return true 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 imageIndex 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 imageIndex are * preserved, and their indices are each increased by 1. A value * for imageIndex 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 ImageOutputStream, * the entirety of the stream must be both readable and writeable. * *

If canInsertImage(imageIndex) returns * false, an * UnsupportedOperationException will be thrown. * *

An ImageWriteParam may optionally be supplied * to control the writing process. If param is * null, a default write param will be used. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param imageIndex the index at which to write the image. * @param image an IIOImage object containing an * image, thumbnails, and metadata to be written. * @param param an ImageWriteParam, or * null to use a default * ImageWriteParam. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canInsertImage(imageIndex) returns false. * @exception IllegalArgumentException if image is * null. * @exception IndexOutOfBoundsException if imageIndex * is less than -1 or greater than the largest available index. * @exception UnsupportedOperationException if image * contains a Raster and canWriteRasters * returns false. * @exception IOException if an error occurs during writing. */ public void writeInsert(int imageIndex, IIOImage image, ImageWriteParam param) throws IOException { unsupported(); } // Image removal /** * Returns true 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. * *

A writer that does not support any image removal may * return false without performing bounds checking on * the index. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise returns false * without checking the value of imageIndex. * * @param imageIndex the index of the image to be removed. * * @return true 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 imageIndex 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. * *

If canRemoveImage(imageIndex) returns false, * an UnsupportedOperationExceptionwill be thrown. * *

The removal may or may not cause a reduction in the actual * file size. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param imageIndex the index of the image to be removed. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canRemoveImage(imageIndex) returns false. * @exception IndexOutOfBoundsException if imageIndex * 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 true 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 replacePixels methods. If the output * is an ImageOutputStream, its existing contents * prior to the current seek position are not affected, and need * not be readable or writable. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise returns false. * * @return true 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 replacePixels * methods. If the output is an ImageOutputStream, * its existing contents prior to the current seek position are * not affected, and need not be readable or writable. * *

The writing is not complete until a call to * endWriteEmpty occurs. Calls to * prepareReplacePixels, replacePixels, * and endReplacePixels may occur between calls to * prepareWriteEmpty and endWriteEmpty. * However, calls to prepareWriteEmpty cannot be * nested, and calls to prepareWriteEmpty and * prepareInsertEmpty may not be interspersed. * *

If canWriteEmpty returns false, * an UnsupportedOperationException will be thrown. * *

An ImageWriteParam may optionally be supplied * to control the writing process. If param is * null, a default write param will be used. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param streamMetadata an IIOMetadata object representing * stream metadata, or null to use default values. * @param imageType an ImageTypeSpecifier describing * the layout of the image. * @param width the width of the image. * @param height the height of the image. * @param imageMetadata an IIOMetadata object * representing image metadata, or null. * @param thumbnails a List of * BufferedImage thumbnails for this image, or * null. * @param param an ImageWriteParam, or * null to use a default * ImageWriteParam. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canWriteEmpty returns false. * @exception IllegalStateException if a previous call to * prepareWriteEmpty has been made without a * corresponding call to endWriteEmpty. * @exception IllegalStateException if a previous call to * prepareInsertEmpty has been made without a * corresponding call to endInsertEmpty. * @exception IllegalArgumentException if imageType * is null or thumbnails contains * null references or objects other than * BufferedImages. * @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 thumbnails, ImageWriteParam param) throws IOException { unsupported(); } /** * Completes the writing of a new image that was begun with a * prior call to prepareWriteEmpty. * *

If canWriteEmpty() returns false, * an UnsupportedOperationException will be thrown. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canWriteEmpty(imageIndex) returns * false. * @exception IllegalStateException if a previous call to * prepareWriteEmpty without a corresponding call to * endWriteEmpty has not been made. * @exception IllegalStateException if a previous call to * prepareInsertEmpty without a corresponding call to * endInsertEmpty has been made. * @exception IllegalStateException if a call to * prepareReiplacePixels has been made without a * matching call to endReplacePixels. * @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 true 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 replacePixels methods. Existing images with * indices greater than or equal to the insertion index will have * their indices increased by 1. A value for * imageIndex of -1 may be used to * signify an index one larger than the current largest index. * *

A writer that does not support insertion of empty images * may return false without performing bounds * checking on the index. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise returns false * without checking the value of imageIndex. * * @param imageIndex the index at which the image is to be * inserted. * * @return true 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 imageIndex * 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 imageIndex are preserved, and their * indices are each increased by 1. A value for * imageIndex 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 ImageOutputStream, * the entirety of the stream must be both readable and writeable. * *

The image contents may be * supplied later using the replacePixels method. * The insertion is not complete until a call to * endInsertEmpty occurs. Calls to * prepareReplacePixels, replacePixels, * and endReplacePixels may occur between calls to * prepareInsertEmpty and * endInsertEmpty. However, calls to * prepareInsertEmpty cannot be nested, and calls to * prepareWriteEmpty and * prepareInsertEmpty may not be interspersed. * *

If canInsertEmpty(imageIndex) returns * false, an * UnsupportedOperationException will be thrown. * *

An ImageWriteParam may optionally be supplied * to control the writing process. If param is * null, a default write param will be used. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param imageIndex the index at which to write the image. * @param imageType an ImageTypeSpecifier describing * the layout of the image. * @param width the width of the image. * @param height the height of the image. * @param imageMetadata an IIOMetadata object * representing image metadata, or null. * @param thumbnails a List of * BufferedImage thumbnails for this image, or * null. * @param param an ImageWriteParam, or * null to use a default * ImageWriteParam. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canInsertEmpty(imageIndex) returns * false. * @exception IndexOutOfBoundsException if imageIndex * is less than -1 or greater than the largest available index. * @exception IllegalStateException if a previous call to * prepareInsertEmpty has been made without a * corresponding call to endInsertEmpty. * @exception IllegalStateException if a previous call to * prepareWriteEmpty has been made without a * corresponding call to endWriteEmpty. * @exception IllegalArgumentException if imageType * is null or thumbnails contains * null references or objects other than * BufferedImages. * @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 thumbnails, ImageWriteParam param) throws IOException { unsupported(); } /** * Completes the insertion of a new image that was begun with a * prior call to prepareInsertEmpty. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canInsertEmpty(imageIndex) returns * false. * @exception IllegalStateException if a previous call to * prepareInsertEmpty without a corresponding call to * endInsertEmpty has not been made. * @exception IllegalStateException if a previous call to * prepareWriteEmpty without a corresponding call to * endWriteEmpty has been made. * @exception IllegalStateException if a call to * prepareReplacePixels has been made without a * matching call to endReplacePixels. * @exception IOException if an I/O error occurs during writing. */ public void endInsertEmpty() throws IOException { unsupported(); } // Pixel replacement /** * Returns true if the writer allows pixels of the * given image to be replaced using the replacePixels * methods. * *

A writer that does not support any pixel replacement may * return false without performing bounds checking on * the index. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise returns false * without checking the value of imageIndex. * * @param imageIndex the index of the image whose pixels are to be * replaced. * * @return true 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 imageIndex 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 * replacePixels methods. The affected pixel area * will be clipped against the supplied * *

If canReplacePixels returns * false, and * UnsupportedOperationException will be thrown. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param imageIndex the index of the image whose pixels are to be * replaced. * @param region a Rectangle that will be used to clip * future pixel regions. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canReplacePixels(imageIndex) returns * false. * @exception IndexOutOfBoundsException if imageIndex * is less than 0 or greater than the largest available index. * @exception IllegalStateException if there is a previous call to * prepareReplacePixels without a matching call to * endReplacePixels (i.e., nesting is not * allowed). * @exception IllegalArgumentException if region is * null 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. * *

The destination region is specified in the * param argument, and will be clipped to the image * boundaries and the region supplied to * prepareReplacePixels. At least one pixel of the * source must not be clipped, or an exception is thrown. * *

An ImageWriteParam may optionally be supplied * to control the writing process. If param is * null, a default write param will be used. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * *

This method may only be called after a call to * prepareReplacePixels, or else an * IllegalStateException will be thrown. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param image a RenderedImage containing source * pixels. * @param param an ImageWriteParam, or * null to use a default * ImageWriteParam. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canReplacePixels(imageIndex) returns * false. * @exception IllegalStateException if there is no previous call to * prepareReplacePixels without a matching call to * endReplacePixels. * @exception IllegalArgumentException if any of the following are true: *

* @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 Raster. The image * data must match, or be convertible to, the image layout of the * existing image. * *

An ImageWriteParam may optionally be supplied * to control the writing process. If param is * null, a default write param will be used. * *

The destination region is specified in the * param argument, and will be clipped to the image * boundaries and the region supplied to * prepareReplacePixels. At least one pixel of the * source must not be clipped, or an exception is thrown. * *

If the supplied ImageWriteParam contains * optional setting values not supported by this writer (e.g. * progressive encoding or any format-specific settings), they * will be ignored. * *

This method may only be called after a call to * prepareReplacePixels, or else an * IllegalStateException will be thrown. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @param raster a Raster containing source * pixels. * @param param an ImageWriteParam, or * null to use a default * ImageWriteParam. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canReplacePixels(imageIndex) returns * false. * @exception IllegalStateException if there is no previous call to * prepareReplacePixels without a matching call to * endReplacePixels. * @exception UnsupportedOperationException if * canWriteRasters returns false. * @exception IllegalArgumentException if any of the following are true: *

* @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 replacePixels. * *

If canReplacePixels returns * false, and * UnsupportedOperationException will be thrown. * *

The default implementation throws an * IllegalStateException if the output is * null, and otherwise throws an * UnsupportedOperationException. * * @exception IllegalStateException if the output has not * been set. * @exception UnsupportedOperationException if * canReplacePixels(imageIndex) returns * false. * @exception IllegalStateException if there is no previous call * to prepareReplacePixels without a matching call to * endReplacePixels. * @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. * *

Writers should call clearAbortRequest at the * beginning of each write operation, and poll the value of * abortRequested regularly during the write. */ public synchronized void abort() { this.abortFlag = true; } /** * Returns true if a request to abort the current * write operation has been made since the writer was instantiated or * clearAbortRequest was called. * * @return true 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, abortRequested will return * false. * * @see #abort * @see #abortRequested */ protected synchronized void clearAbortRequest() { this.abortFlag = false; } // Listeners /** * Adds an IIOWriteWarningListener to the list of * registered warning listeners. If listener is * null, 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 * Locale. If no Locale has been set, * warning messages may be localized as the writer sees fit. * * @param listener an IIOWriteWarningListener 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 IIOWriteWarningListener from the list * of registered warning listeners. If the listener was not * previously registered, or if listener is * null, no exception will be thrown and no action * will be taken. * * @param listener an IIOWriteWarningListener 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 * IIOWriteWarningListener objects. * *

The default implementation sets the * warningListeners and warningLocales * instance variables to null. */ public void removeAllIIOWriteWarningListeners() { this.warningListeners = null; this.warningLocales = null; } /** * Adds an IIOWriteProgressListener to the list of * registered progress listeners. If listener is * null, no exception will be thrown and no action * will be taken. * * @param listener an IIOWriteProgressListener to be * registered. * * @see #removeIIOWriteProgressListener */ public void addIIOWriteProgressListener(IIOWriteProgressListener listener) { if (listener == null) { return; } progressListeners = ImageReader.addToList(progressListeners, listener); } /** * Removes an IIOWriteProgressListener from the list * of registered progress listeners. If the listener was not * previously registered, or if listener is * null, no exception will be thrown and no action * will be taken. * * @param listener an IIOWriteProgressListener 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 * IIOWriteProgressListener objects. * *

The default implementation sets the * progressListeners instance variable to * null. */ public void removeAllIIOWriteProgressListeners() { this.progressListeners = null; } /** * Broadcasts the start of an image write to all registered * IIOWriteProgressListeners by calling their * imageStarted 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 = progressListeners.get(i); listener.imageStarted(this, imageIndex); } } /** * Broadcasts the current percentage of image completion to all * registered IIOWriteProgressListeners by calling * their imageProgress method. Subclasses may use * this method as a convenience. * * @param percentageDone the current percentage of completion, * as a float. */ protected void processImageProgress(float percentageDone) { if (progressListeners == null) { return; } int numListeners = progressListeners.size(); for (int i = 0; i < numListeners; i++) { IIOWriteProgressListener listener = progressListeners.get(i); listener.imageProgress(this, percentageDone); } } /** * Broadcasts the completion of an image write to all registered * IIOWriteProgressListeners by calling their * imageComplete 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 = progressListeners.get(i); listener.imageComplete(this); } } /** * Broadcasts the start of a thumbnail write to all registered * IIOWriteProgressListeners by calling their * thumbnailStarted 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 = progressListeners.get(i); listener.thumbnailStarted(this, imageIndex, thumbnailIndex); } } /** * Broadcasts the current percentage of thumbnail completion to * all registered IIOWriteProgressListeners by calling * their thumbnailProgress method. Subclasses may * use this method as a convenience. * * @param percentageDone the current percentage of completion, * as a float. */ protected void processThumbnailProgress(float percentageDone) { if (progressListeners == null) { return; } int numListeners = progressListeners.size(); for (int i = 0; i < numListeners; i++) { IIOWriteProgressListener listener = progressListeners.get(i); listener.thumbnailProgress(this, percentageDone); } } /** * Broadcasts the completion of a thumbnail write to all registered * IIOWriteProgressListeners by calling their * thumbnailComplete 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 = progressListeners.get(i); listener.thumbnailComplete(this); } } /** * Broadcasts that the write has been aborted to all registered * IIOWriteProgressListeners by calling their * writeAborted 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 = progressListeners.get(i); listener.writeAborted(this); } } /** * Broadcasts a warning message to all registered * IIOWriteWarningListeners by calling their * warningOccurred 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 warning * is null. */ 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 = warningListeners.get(i); listener.warningOccurred(this, imageIndex, warning); } } /** * Broadcasts a localized warning message to all registered * IIOWriteWarningListeners by calling their * warningOccurred method with a string taken * from a ResourceBundle. 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 * ResourceBundles containing localized warning * messages. * @param keyword the keyword used to index the warning message * within the set of ResourceBundles. * * @exception IllegalArgumentException if baseName * is null. * @exception IllegalArgumentException if keyword * is null. * @exception IllegalArgumentException if no appropriate * ResourceBundle may be located. * @exception IllegalArgumentException if the named resource is * not found in the located ResourceBundle. * @exception IllegalArgumentException if the object retrieved * from the ResourceBundle is not a * String. */ 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 = warningListeners.get(i); 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 = java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public ClassLoader 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 ImageWriter to its initial state. * *

The default implementation calls * setOutput(null), setLocale(null), * removeAllIIOWriteWarningListeners(), * removeAllIIOWriteProgressListeners(), and * clearAbortRequest. */ 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 * finalize) subsequent to a call to this method * is undefined. * *

It is important for applications to call this method when they * know they will no longer be using this ImageWriter. * Otherwise, the writer may continue to hold on to resources * indefinitely. * *

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