0001 /*
0002 * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package javax.imageio;
0027
0028 import java.awt.Dimension;
0029 import java.awt.Rectangle;
0030 import java.awt.image.BufferedImage;
0031 import java.awt.image.RenderedImage;
0032 import java.awt.image.Raster;
0033 import java.io.IOException;
0034 import java.util.ArrayList;
0035 import java.util.List;
0036 import java.util.Locale;
0037 import java.util.MissingResourceException;
0038 import java.util.ResourceBundle;
0039 import javax.imageio.event.IIOWriteWarningListener;
0040 import javax.imageio.event.IIOWriteProgressListener;
0041 import javax.imageio.metadata.IIOMetadata;
0042 import javax.imageio.stream.ImageOutputStream;
0043 import javax.imageio.spi.ImageWriterSpi;
0044
0045 /**
0046 * An abstract superclass for encoding and writing images. This class
0047 * must be subclassed by classes that write out images in the context
0048 * of the Java Image I/O framework.
0049 *
0050 * <p> <code>ImageWriter</code> objects are normally instantiated by
0051 * the service provider class for the specific format. Service
0052 * provider classes are registered with the <code>IIORegistry</code>,
0053 * which uses them for format recognition and presentation of
0054 * available format readers and writers.
0055 *
0056 * <p>
0057 *
0058 * @see ImageReader
0059 * @see ImageWriteParam
0060 * @see javax.imageio.spi.IIORegistry
0061 * @see javax.imageio.spi.ImageWriterSpi
0062 *
0063 * @version 0.5
0064 */
0065 public abstract class ImageWriter implements ImageTranscoder {
0066
0067 /**
0068 * The <code>ImageWriterSpi</code> that instantiated this object,
0069 * or <code>null</code> if its identity is not known or none
0070 * exists. By default it is initialized to <code>null</code>.
0071 */
0072 protected ImageWriterSpi originatingProvider = null;
0073
0074 /**
0075 * The <code>ImageOutputStream</code> or other <code>Object</code>
0076 * set by <code>setOutput</code> and retrieved by
0077 * <code>getOutput</code>. By default it is initialized to
0078 * <code>null</code>.
0079 */
0080 protected Object output = null;
0081
0082 /**
0083 * An array of <code>Locale</code>s that may be used to localize
0084 * warning messages and compression setting values, or
0085 * <code>null</code> if localization is not supported. By default
0086 * it is initialized to <code>null</code>.
0087 */
0088 protected Locale[] availableLocales = null;
0089
0090 /**
0091 * The current <code>Locale</code> to be used for localization, or
0092 * <code>null</code> if none has been set. By default it is
0093 * initialized to <code>null</code>.
0094 */
0095 protected Locale locale = null;
0096
0097 /**
0098 * A <code>List</code> of currently registered
0099 * <code>IIOWriteWarningListener</code>s, initialized by default to
0100 * <code>null</code>, which is synonymous with an empty
0101 * <code>List</code>.
0102 */
0103 protected List<IIOWriteWarningListener> warningListeners = null;
0104
0105 /**
0106 * A <code>List</code> of <code>Locale</code>s, one for each
0107 * element of <code>warningListeners</code>, initialized by default
0108 * <code>null</code>, which is synonymous with an empty
0109 * <code>List</code>.
0110 */
0111 protected List<Locale> warningLocales = null;
0112
0113 /**
0114 * A <code>List</code> of currently registered
0115 * <code>IIOWriteProgressListener</code>s, initialized by default
0116 * <code>null</code>, which is synonymous with an empty
0117 * <code>List</code>.
0118 */
0119 protected List<IIOWriteProgressListener> progressListeners = null;
0120
0121 /**
0122 * If <code>true</code>, the current write operation should be
0123 * aborted.
0124 */
0125 private boolean abortFlag = false;
0126
0127 /**
0128 * Constructs an <code>ImageWriter</code> and sets its
0129 * <code>originatingProvider</code> instance variable to the
0130 * supplied value.
0131 *
0132 * <p> Subclasses that make use of extensions should provide a
0133 * constructor with signature <code>(ImageWriterSpi,
0134 * Object)</code> in order to retrieve the extension object. If
0135 * the extension object is unsuitable, an
0136 * <code>IllegalArgumentException</code> should be thrown.
0137 *
0138 * @param originatingProvider the <code>ImageWriterSpi</code> that
0139 * is constructing this object, or <code>null</code>.
0140 */
0141 protected ImageWriter(ImageWriterSpi originatingProvider) {
0142 this .originatingProvider = originatingProvider;
0143 }
0144
0145 /**
0146 * Returns the <code>ImageWriterSpi</code> object that created
0147 * this <code>ImageWriter</code>, or <code>null</code> if this
0148 * object was not created through the <code>IIORegistry</code>.
0149 *
0150 * <p> The default implementation returns the value of the
0151 * <code>originatingProvider</code> instance variable.
0152 *
0153 * @return an <code>ImageWriterSpi</code>, or <code>null</code>.
0154 *
0155 * @see ImageWriterSpi
0156 */
0157 public ImageWriterSpi getOriginatingProvider() {
0158 return originatingProvider;
0159 }
0160
0161 /**
0162 * Sets the destination to the given
0163 * <code>ImageOutputStream</code> or other <code>Object</code>.
0164 * The destination is assumed to be ready to accept data, and will
0165 * not be closed at the end of each write. This allows distributed
0166 * imaging applications to transmit a series of images over a
0167 * single network connection. If <code>output</code> is
0168 * <code>null</code>, any currently set output will be removed.
0169 *
0170 * <p> If <code>output</code> is an
0171 * <code>ImageOutputStream</code>, calls to the
0172 * <code>write</code>, <code>writeToSequence</code>, and
0173 * <code>prepareWriteEmpty</code>/<code>endWriteEmpty</code>
0174 * methods will preserve the existing contents of the stream.
0175 * Other write methods, such as <code>writeInsert</code>,
0176 * <code>replaceStreamMetadata</code>,
0177 * <code>replaceImageMetadata</code>, <code>replacePixels</code>,
0178 * <code>prepareInsertEmpty</code>/<code>endInsertEmpty</code>,
0179 * and <code>endWriteSequence</code>, require the full contents
0180 * of the stream to be readable and writable, and may alter any
0181 * portion of the stream.
0182 *
0183 * <p> Use of a general <code>Object</code> other than an
0184 * <code>ImageOutputStream</code> is intended for writers that
0185 * interact directly with an output device or imaging protocol.
0186 * The set of legal classes is advertised by the writer's service
0187 * provider's <code>getOutputTypes</code> method; most writers
0188 * will return a single-element array containing only
0189 * <code>ImageOutputStream.class</code> to indicate that they
0190 * accept only an <code>ImageOutputStream</code>.
0191 *
0192 * <p> The default implementation sets the <code>output</code>
0193 * instance variable to the value of <code>output</code> after
0194 * checking <code>output</code> against the set of classes
0195 * advertised by the originating provider, if there is one.
0196 *
0197 * @param output the <code>ImageOutputStream</code> or other
0198 * <code>Object</code> to use for future writing.
0199 *
0200 * @exception IllegalArgumentException if <code>output</code> is
0201 * not an instance of one of the classes returned by the
0202 * originating service provider's <code>getOutputTypes</code>
0203 * method.
0204 *
0205 * @see #getOutput
0206 */
0207 public void setOutput(Object output) {
0208 if (output != null) {
0209 ImageWriterSpi provider = getOriginatingProvider();
0210 if (provider != null) {
0211 Class[] classes = provider.getOutputTypes();
0212 boolean found = false;
0213 for (int i = 0; i < classes.length; i++) {
0214 if (classes[i].isInstance(output)) {
0215 found = true;
0216 break;
0217 }
0218 }
0219 if (!found) {
0220 throw new IllegalArgumentException(
0221 "Illegal output type!");
0222 }
0223 }
0224 }
0225
0226 this .output = output;
0227 }
0228
0229 /**
0230 * Returns the <code>ImageOutputStream</code> or other
0231 * <code>Object</code> set by the most recent call to the
0232 * <code>setOutput</code> method. If no destination has been
0233 * set, <code>null</code> is returned.
0234 *
0235 * <p> The default implementation returns the value of the
0236 * <code>output</code> instance variable.
0237 *
0238 * @return the <code>Object</code> that was specified using
0239 * <code>setOutput</code>, or <code>null</code>.
0240 *
0241 * @see #setOutput
0242 */
0243 public Object getOutput() {
0244 return output;
0245 }
0246
0247 // Localization
0248
0249 /**
0250 * Returns an array of <code>Locale</code>s that may be used to
0251 * localize warning listeners and compression settings. A return
0252 * value of <code>null</code> indicates that localization is not
0253 * supported.
0254 *
0255 * <p> The default implementation returns a clone of the
0256 * <code>availableLocales</code> instance variable if it is
0257 * non-<code>null</code>, or else returns <code>null</code>.
0258 *
0259 * @return an array of <code>Locale</code>s that may be used as
0260 * arguments to <code>setLocale</code>, or <code>null</code>.
0261 */
0262 public Locale[] getAvailableLocales() {
0263 return (availableLocales == null) ? null
0264 : (Locale[]) availableLocales.clone();
0265 }
0266
0267 /**
0268 * Sets the current <code>Locale</code> of this
0269 * <code>ImageWriter</code> to the given value. A value of
0270 * <code>null</code> removes any previous setting, and indicates
0271 * that the writer should localize as it sees fit.
0272 *
0273 * <p> The default implementation checks <code>locale</code>
0274 * against the values returned by
0275 * <code>getAvailableLocales</code>, and sets the
0276 * <code>locale</code> instance variable if it is found. If
0277 * <code>locale</code> is <code>null</code>, the instance variable
0278 * is set to <code>null</code> without any checking.
0279 *
0280 * @param locale the desired <code>Locale</code>, or
0281 * <code>null</code>.
0282 *
0283 * @exception IllegalArgumentException if <code>locale</code> is
0284 * non-<code>null</code> but is not one of the values returned by
0285 * <code>getAvailableLocales</code>.
0286 *
0287 * @see #getLocale
0288 */
0289 public void setLocale(Locale locale) {
0290 if (locale != null) {
0291 Locale[] locales = getAvailableLocales();
0292 boolean found = false;
0293 if (locales != null) {
0294 for (int i = 0; i < locales.length; i++) {
0295 if (locale.equals(locales[i])) {
0296 found = true;
0297 break;
0298 }
0299 }
0300 }
0301 if (!found) {
0302 throw new IllegalArgumentException("Invalid locale!");
0303 }
0304 }
0305 this .locale = locale;
0306 }
0307
0308 /**
0309 * Returns the currently set <code>Locale</code>, or
0310 * <code>null</code> if none has been set.
0311 *
0312 * <p> The default implementation returns the value of the
0313 * <code>locale</code> instance variable.
0314 *
0315 * @return the current <code>Locale</code>, or <code>null</code>.
0316 *
0317 * @see #setLocale
0318 */
0319 public Locale getLocale() {
0320 return locale;
0321 }
0322
0323 // Write params
0324
0325 /**
0326 * Returns a new <code>ImageWriteParam</code> object of the
0327 * appropriate type for this file format containing default
0328 * values, that is, those values that would be used
0329 * if no <code>ImageWriteParam</code> object were specified. This
0330 * is useful as a starting point for tweaking just a few parameters
0331 * and otherwise leaving the default settings alone.
0332 *
0333 * <p> The default implementation constructs and returns a new
0334 * <code>ImageWriteParam</code> object that does not allow tiling,
0335 * progressive encoding, or compression, and that will be
0336 * localized for the current <code>Locale</code> (<i>i.e.</i>,
0337 * what you would get by calling <code>new
0338 * ImageWriteParam(getLocale())</code>.
0339 *
0340 * <p> Individual plug-ins may return an instance of
0341 * <code>ImageWriteParam</code> with additional optional features
0342 * enabled, or they may return an instance of a plug-in specific
0343 * subclass of <code>ImageWriteParam</code>.
0344 *
0345 * @return a new <code>ImageWriteParam</code> object containing
0346 * default values.
0347 */
0348 public ImageWriteParam getDefaultWriteParam() {
0349 return new ImageWriteParam(getLocale());
0350 }
0351
0352 // Metadata
0353
0354 /**
0355 * Returns an <code>IIOMetadata</code> object containing default
0356 * values for encoding a stream of images. The contents of the
0357 * object may be manipulated using either the XML tree structure
0358 * returned by the <code>IIOMetadata.getAsTree</code> method, an
0359 * <code>IIOMetadataController</code> object, or via plug-in
0360 * specific interfaces, and the resulting data supplied to one of
0361 * the <code>write</code> methods that take a stream metadata
0362 * parameter.
0363 *
0364 * <p> An optional <code>ImageWriteParam</code> may be supplied
0365 * for cases where it may affect the structure of the stream
0366 * metadata.
0367 *
0368 * <p> If the supplied <code>ImageWriteParam</code> contains
0369 * optional setting values not supported by this writer (<i>e.g.</i>
0370 * progressive encoding or any format-specific settings), they
0371 * will be ignored.
0372 *
0373 * <p> Writers that do not make use of stream metadata
0374 * (<i>e.g.</i>, writers for single-image formats) should return
0375 * <code>null</code>.
0376 *
0377 * @param param an <code>ImageWriteParam</code> that will be used to
0378 * encode the image, or <code>null</code>.
0379 *
0380 * @return an <code>IIOMetadata</code> object.
0381 */
0382 public abstract IIOMetadata getDefaultStreamMetadata(
0383 ImageWriteParam param);
0384
0385 /**
0386 * Returns an <code>IIOMetadata</code> object containing default
0387 * values for encoding an image of the given type. The contents
0388 * of the object may be manipulated using either the XML tree
0389 * structure returned by the <code>IIOMetadata.getAsTree</code>
0390 * method, an <code>IIOMetadataController</code> object, or via
0391 * plug-in specific interfaces, and the resulting data supplied to
0392 * one of the <code>write</code> methods that take a stream
0393 * metadata parameter.
0394 *
0395 * <p> An optional <code>ImageWriteParam</code> may be supplied
0396 * for cases where it may affect the structure of the image
0397 * metadata.
0398 *
0399 * <p> If the supplied <code>ImageWriteParam</code> contains
0400 * optional setting values not supported by this writer (<i>e.g.</i>
0401 * progressive encoding or any format-specific settings), they
0402 * will be ignored.
0403 *
0404 * @param imageType an <code>ImageTypeSpecifier</code> indicating the
0405 * format of the image to be written later.
0406 * @param param an <code>ImageWriteParam</code> that will be used to
0407 * encode the image, or <code>null</code>.
0408 *
0409 * @return an <code>IIOMetadata</code> object.
0410 */
0411 public abstract IIOMetadata getDefaultImageMetadata(
0412 ImageTypeSpecifier imageType, ImageWriteParam param);
0413
0414 // comment inherited
0415 public abstract IIOMetadata convertStreamMetadata(
0416 IIOMetadata inData, ImageWriteParam param);
0417
0418 // comment inherited
0419 public abstract IIOMetadata convertImageMetadata(
0420 IIOMetadata inData, ImageTypeSpecifier imageType,
0421 ImageWriteParam param);
0422
0423 // Thumbnails
0424
0425 /**
0426 * Returns the number of thumbnails suported by the format being
0427 * written, given the image type and any additional write
0428 * parameters and metadata objects that will be used during
0429 * encoding. A return value of <code>-1</code> indicates that
0430 * insufficient information is available.
0431 *
0432 * <p> An <code>ImageWriteParam</code> may optionally be supplied
0433 * for cases where it may affect thumbnail handling.
0434 *
0435 * <p> If the supplied <code>ImageWriteParam</code> contains
0436 * optional setting values not supported by this writer (<i>e.g.</i>
0437 * progressive encoding or any format-specific settings), they
0438 * will be ignored.
0439 *
0440 * <p> The default implementation returns 0.
0441 *
0442 * @param imageType an <code>ImageTypeSpecifier</code> indicating
0443 * the type of image to be written, or <code>null</code>.
0444 * @param param the <code>ImageWriteParam</code> that will be used for
0445 * writing, or <code>null</code>.
0446 * @param streamMetadata an <code>IIOMetadata</code> object that will
0447 * be used for writing, or <code>null</code>.
0448 * @param imageMetadata an <code>IIOMetadata</code> object that will
0449 * be used for writing, or <code>null</code>.
0450 *
0451 * @return the number of thumbnails that may be written given the
0452 * supplied parameters, or <code>-1</code> if insufficient
0453 * information is available.
0454 */
0455 public int getNumThumbnailsSupported(ImageTypeSpecifier imageType,
0456 ImageWriteParam param, IIOMetadata streamMetadata,
0457 IIOMetadata imageMetadata) {
0458 return 0;
0459 }
0460
0461 /**
0462 * Returns an array of <code>Dimension</code>s indicating the
0463 * legal size ranges for thumbnail images as they will be encoded
0464 * in the output file or stream. This information is merely
0465 * advisory; the writer will resize any supplied thumbnails as
0466 * necessary.
0467 *
0468 * <p> The information is returned as a set of pairs; the first
0469 * element of a pair contains an (inclusive) minimum width and
0470 * height, and the second element contains an (inclusive) maximum
0471 * width and height. Together, each pair defines a valid range of
0472 * sizes. To specify a fixed size, the same width and height will
0473 * appear for both elements. A return value of <code>null</code>
0474 * indicates that the size is arbitrary or unknown.
0475 *
0476 * <p> An <code>ImageWriteParam</code> may optionally be supplied
0477 * for cases where it may affect thumbnail handling.
0478 *
0479 * <p> If the supplied <code>ImageWriteParam</code> contains
0480 * optional setting values not supported by this writer (<i>e.g.</i>
0481 * progressive encoding or any format-specific settings), they
0482 * will be ignored.
0483 *
0484 * <p> The default implementation returns <code>null</code>.
0485 *
0486 * @param imageType an <code>ImageTypeSpecifier</code> indicating the
0487 * type of image to be written, or <code>null</code>.
0488 * @param param the <code>ImageWriteParam</code> that will be used for
0489 * writing, or <code>null</code>.
0490 * @param streamMetadata an <code>IIOMetadata</code> object that will
0491 * be used for writing, or <code>null</code>.
0492 * @param imageMetadata an <code>IIOMetadata</code> object that will
0493 * be used for writing, or <code>null</code>.
0494 *
0495 * @return an array of <code>Dimension</code>s with an even length
0496 * of at least two, or <code>null</code>.
0497 */
0498 public Dimension[] getPreferredThumbnailSizes(
0499 ImageTypeSpecifier imageType, ImageWriteParam param,
0500 IIOMetadata streamMetadata, IIOMetadata imageMetadata) {
0501 return null;
0502 }
0503
0504 /**
0505 * Returns <code>true</code> if the methods that take an
0506 * <code>IIOImage</code> parameter are capable of dealing with a
0507 * <code>Raster</code> (as opposed to <code>RenderedImage</code>)
0508 * source image. If this method returns <code>false</code>, then
0509 * those methods will throw an
0510 * <code>UnsupportedOperationException</code> if supplied with an
0511 * <code>IIOImage</code> containing a <code>Raster</code>.
0512 *
0513 * <p> The default implementation returns <code>false</code>.
0514 *
0515 * @return <code>true</code> if <code>Raster</code> sources are
0516 * supported.
0517 */
0518 public boolean canWriteRasters() {
0519 return false;
0520 }
0521
0522 /**
0523 * Appends a complete image stream containing a single image and
0524 * associated stream and image metadata and thumbnails to the
0525 * output. Any necessary header information is included. If the
0526 * output is an <code>ImageOutputStream</code>, its existing
0527 * contents prior to the current seek position are not affected,
0528 * and need not be readable or writable.
0529 *
0530 * <p> The output must have been set beforehand using the
0531 * <code>setOutput</code> method.
0532 *
0533 * <p> Stream metadata may optionally be supplied; if it is
0534 * <code>null</code>, default stream metadata will be used.
0535 *
0536 * <p> If <code>canWriteRasters</code> returns <code>true</code>,
0537 * the <code>IIOImage</code> may contain a <code>Raster</code>
0538 * source. Otherwise, it must contain a
0539 * <code>RenderedImage</code> source.
0540 *
0541 * <p> The supplied thumbnails will be resized if needed, and any
0542 * thumbnails in excess of the supported number will be ignored.
0543 * If the format requires additional thumbnails that are not
0544 * provided, the writer should generate them internally.
0545 *
0546 * <p> An <code>ImageWriteParam</code> may
0547 * optionally be supplied to control the writing process. If
0548 * <code>param</code> is <code>null</code>, a default write param
0549 * will be used.
0550 *
0551 * <p> If the supplied <code>ImageWriteParam</code> contains
0552 * optional setting values not supported by this writer (<i>e.g.</i>
0553 * progressive encoding or any format-specific settings), they
0554 * will be ignored.
0555 *
0556 * @param streamMetadata an <code>IIOMetadata</code> object representing
0557 * stream metadata, or <code>null</code> to use default values.
0558 * @param image an <code>IIOImage</code> object containing an
0559 * image, thumbnails, and metadata to be written.
0560 * @param param an <code>ImageWriteParam</code>, or
0561 * <code>null</code> to use a default
0562 * <code>ImageWriteParam</code>.
0563 *
0564 * @exception IllegalStateException if the output has not
0565 * been set.
0566 * @exception UnsupportedOperationException if <code>image</code>
0567 * contains a <code>Raster</code> and <code>canWriteRasters</code>
0568 * returns <code>false</code>.
0569 * @exception IllegalArgumentException if <code>image</code> is
0570 * <code>null</code>.
0571 * @exception IOException if an error occurs during writing.
0572 */
0573 public abstract void write(IIOMetadata streamMetadata,
0574 IIOImage image, ImageWriteParam param) throws IOException;
0575
0576 /**
0577 * Appends a complete image stream containing a single image with
0578 * default metadata and thumbnails to the output. This method is
0579 * a shorthand for <code>write(null, image, null)</code>.
0580 *
0581 * @param image an <code>IIOImage</code> object containing an
0582 * image, thumbnails, and metadata to be written.
0583 *
0584 * @exception IllegalStateException if the output has not
0585 * been set.
0586 * @exception IllegalArgumentException if <code>image</code> is
0587 * <code>null</code>.
0588 * @exception UnsupportedOperationException if <code>image</code>
0589 * contains a <code>Raster</code> and <code>canWriteRasters</code>
0590 * returns <code>false</code>.
0591 * @exception IOException if an error occurs during writing.
0592 */
0593 public void write(IIOImage image) throws IOException {
0594 write(null, image, null);
0595 }
0596
0597 /**
0598 * Appends a complete image stream consisting of a single image
0599 * with default metadata and thumbnails to the output. This
0600 * method is a shorthand for <code>write(null, new IIOImage(image,
0601 * null, null), null)</code>.
0602 *
0603 * @param image a <code>RenderedImage</code> to be written.
0604 *
0605 * @exception IllegalStateException if the output has not
0606 * been set.
0607 * @exception IllegalArgumentException if <code>image</code> is
0608 * <code>null</code>.
0609 * @exception IOException if an error occurs during writing.
0610 */
0611 public void write(RenderedImage image) throws IOException {
0612 write(null, new IIOImage(image, null, null), null);
0613 }
0614
0615 // Check that the output has been set, then throw an
0616 // UnsupportedOperationException.
0617 private void unsupported() {
0618 if (getOutput() == null) {
0619 throw new IllegalStateException("getOutput() == null!");
0620 }
0621 throw new UnsupportedOperationException(
0622 "Unsupported write variant!");
0623 }
0624
0625 // Sequence writes
0626
0627 /**
0628 * Returns <code>true</code> if the writer is able to append an
0629 * image to an image stream that already contains header
0630 * information and possibly prior images.
0631 *
0632 * <p> If <code>canWriteSequence</code> returns <code>false</code>,
0633 * <code>writeToSequence</code> and <code>endWriteSequence</code>
0634 * will throw an <code>UnsupportedOperationException</code>.
0635 *
0636 * <p> The default implementation returns <code>false</code>.
0637 *
0638 * @return <code>true</code> if images may be appended sequentially.
0639 */
0640 public boolean canWriteSequence() {
0641 return false;
0642 }
0643
0644 /**
0645 * Prepares a stream to accept a series of subsequent
0646 * <code>writeToSequence</code> calls, using the provided stream
0647 * metadata object. The metadata will be written to the stream if
0648 * it should precede the image data. If the argument is <code>null</code>,
0649 * default stream metadata is used.
0650 *
0651 * <p> If the output is an <code>ImageOutputStream</code>, the existing
0652 * contents of the output prior to the current seek position are
0653 * flushed, and need not be readable or writable. If the format
0654 * requires that <code>endWriteSequence</code> be able to rewind to
0655 * patch up the header information, such as for a sequence of images
0656 * in a single TIFF file, then the metadata written by this method
0657 * must remain in a writable portion of the stream. Other formats
0658 * may flush the stream after this method and after each image.
0659 *
0660 * <p> If <code>canWriteSequence</code> returns <code>false</code>,
0661 * this method will throw an
0662 * <code>UnsupportedOperationException</code>.
0663 *
0664 * <p> The output must have been set beforehand using either
0665 * the <code>setOutput</code> method.
0666 *
0667 * <p> The default implementation throws an
0668 * <code>IllegalStateException</code> if the output is
0669 * <code>null</code>, and otherwise throws an
0670 * <code>UnsupportedOperationException</code>.
0671 *
0672 * @param streamMetadata A stream metadata object, or <code>null</code>.
0673 *
0674 * @exception IllegalStateException if the output has not
0675 * been set.
0676 * @exception UnsupportedOperationException if
0677 * <code>canWriteSequence</code> returns <code>false</code>.
0678 * @exception IOException if an error occurs writing the stream
0679 * metadata.
0680 */
0681 public void prepareWriteSequence(IIOMetadata streamMetadata)
0682 throws IOException {
0683 unsupported();
0684 }
0685
0686 /**
0687 * Appends a single image and possibly associated metadata and
0688 * thumbnails, to the output. If the output is an
0689 * <code>ImageOutputStream</code>, the existing contents of the
0690 * output prior to the current seek position may be flushed, and
0691 * need not be readable or writable, unless the plug-in needs to
0692 * be able to patch up the header information when
0693 * <code>endWriteSequence</code> is called (<italic>e.g.</italic> TIFF).
0694 *
0695 * <p> If <code>canWriteSequence</code> returns <code>false</code>,
0696 * this method will throw an
0697 * <code>UnsupportedOperationException</code>.
0698 *
0699 * <p> The output must have been set beforehand using
0700 * the <code>setOutput</code> method.
0701 *
0702 * <p> <code>prepareWriteSequence</code> must have been called
0703 * beforehand, or an <code>IllegalStateException</code> is thrown.
0704 *
0705 * <p> If <code>canWriteRasters</code> returns <code>true</code>,
0706 * the <code>IIOImage</code> may contain a <code>Raster</code>
0707 * source. Otherwise, it must contain a
0708 * <code>RenderedImage</code> source.
0709 *
0710 * <p> The supplied thumbnails will be resized if needed, and any
0711 * thumbnails in excess of the supported number will be ignored.
0712 * If the format requires additional thumbnails that are not
0713 * provided, the writer will generate them internally.
0714 *
0715 * <p> An <code>ImageWriteParam</code> may optionally be supplied
0716 * to control the writing process. If <code>param</code> is
0717 * <code>null</code>, a default write param will be used.
0718 *
0719 * <p> If the supplied <code>ImageWriteParam</code> contains
0720 * optional setting values not supported by this writer (<i>e.g.</i>
0721 * progressive encoding or any format-specific settings), they
0722 * will be ignored.
0723 *
0724 * <p> The default implementation throws an
0725 * <code>IllegalStateException</code> if the output is
0726 * <code>null</code>, and otherwise throws an
0727 * <code>UnsupportedOperationException</code>.
0728 *
0729 * @param image an <code>IIOImage</code> object containing an
0730 * image, thumbnails, and metadata to be written.
0731 * @param param an <code>ImageWriteParam</code>, or
0732 * <code>null</code> to use a default
0733 * <code>ImageWriteParam</code>.
0734 *
0735 * @exception IllegalStateException if the output has not
0736 * been set, or <code>prepareWriteSequence</code> has not been called.
0737 * @exception UnsupportedOperationException if
0738 * <code>canWriteSequence</code> returns <code>false</code>.
0739 * @exception IllegalArgumentException if <code>image</code> is
0740 * <code>null</code>.
0741 * @exception UnsupportedOperationException if <code>image</code>
0742 * contains a <code>Raster</code> and <code>canWriteRasters</code>
0743 * returns <code>false</code>.
0744 * @exception IOException if an error occurs during writing.
0745 */
0746 public void writeToSequence(IIOImage image, ImageWriteParam param)
0747 throws IOException {
0748 unsupported();
0749 }
0750
0751 /**
0752 * Completes the writing of a sequence of images begun with
0753 * <code>prepareWriteSequence</code>. Any stream metadata that
0754 * should come at the end of the sequence of images is written out,
0755 * and any header information at the beginning of the sequence is
0756 * patched up if necessary. If the output is an
0757 * <code>ImageOutputStream</code>, data through the stream metadata
0758 * at the end of the sequence are flushed and need not be readable
0759 * or writable.
0760 *
0761 * <p> If <code>canWriteSequence</code> returns <code>false</code>,
0762 * this method will throw an
0763 * <code>UnsupportedOperationException</code>.
0764 *
0765 * <p> The default implementation throws an
0766 * <code>IllegalStateException</code> if the output is
0767 * <code>null</code>, and otherwise throws an
0768 * <code>UnsupportedOperationException</code>.
0769 *
0770 * @exception IllegalStateException if the output has not
0771 * been set, or <code>prepareWriteSequence</code> has not been called.
0772 * @exception UnsupportedOperationException if
0773 * <code>canWriteSequence</code> returns <code>false</code>.
0774 * @exception IOException if an error occurs during writing.
0775 */
0776 public void endWriteSequence() throws IOException {
0777 unsupported();
0778 }
0779
0780 // Metadata replacement
0781
0782 /**
0783 * Returns <code>true</code> if it is possible to replace the
0784 * stream metadata already present in the output.
0785 *
0786 * <p> The default implementation throws an
0787 * <code>IllegalStateException</code> if the output is
0788 * <code>null</code>, and otherwise returns <code>false</code>.
0789 *
0790 * @return <code>true</code> if replacement of stream metadata is
0791 * allowed.
0792 *
0793 * @exception IllegalStateException if the output has not
0794 * been set.
0795 * @exception IOException if an I/O error occurs during the query.
0796 */
0797 public boolean canReplaceStreamMetadata() throws IOException {
0798 if (getOutput() == null) {
0799 throw new IllegalStateException("getOutput() == null!");
0800 }
0801 return false;
0802 }
0803
0804 /**
0805 * Replaces the stream metadata in the output with new
0806 * information. If the output is an
0807 * <code>ImageOutputStream</code>, the prior contents of the
0808 * stream are examined and possibly edited to make room for the
0809 * new data. All of the prior contents of the output must be
0810 * available for reading and writing.
0811 *
0812 * <p> If <code>canReplaceStreamMetadata</code> returns
0813 * <code>false</code>, an
0814 * <code>UnsupportedOperationException</code> will be thrown.
0815 *
0816 * <p> The default implementation throws an
0817 * <code>IllegalStateException</code> if the output is
0818 * <code>null</code>, and otherwise throws an
0819 * <code>UnsupportedOperationException</code>.
0820 *
0821 * @param streamMetadata an <code>IIOMetadata</code> object representing
0822 * stream metadata, or <code>null</code> to use default values.
0823 *
0824 * @exception IllegalStateException if the output has not
0825 * been set.
0826 * @exception UnsupportedOperationException if the
0827 * <code>canReplaceStreamMetadata</code> returns
0828 * <code>false</code>. modes do not include
0829 * @exception IOException if an error occurs during writing.
0830 */
0831 public void replaceStreamMetadata(IIOMetadata streamMetadata)
0832 throws IOException {
0833 unsupported();
0834 }
0835
0836 /**
0837 * Returns <code>true</code> if it is possible to replace the
0838 * image metadata associated with an existing image with index
0839 * <code>imageIndex</code>. If this method returns
0840 * <code>false</code>, a call to
0841 * <code>replaceImageMetadata(imageIndex)</code> will throw an
0842 * <code>UnsupportedOperationException</code>.
0843 *
0844 * <p> A writer that does not support any image metadata
0845 * replacement may return <code>false</code> without performing
0846 * bounds checking on the index.
0847 *
0848 * <p> The default implementation throws an
0849 * <code>IllegalStateException</code> if the output is
0850 * <code>null</code>, and otherwise returns <code>false</code>
0851 * without checking the value of <code>imageIndex</code>.
0852 *
0853 * @param imageIndex the index of the image whose metadata is to
0854 * be replaced.
0855 *
0856 * @return <code>true</code> if the image metadata of the given
0857 * image can be replaced.
0858 *
0859 * @exception IllegalStateException if the output has not
0860 * been set.
0861 * @exception IndexOutOfBoundsException if the writer supports
0862 * image metadata replacement in general, but
0863 * <code>imageIndex</code> is less than 0 or greater than the
0864 * largest available index.
0865 * @exception IOException if an I/O error occurs during the query.
0866 */
0867 public boolean canReplaceImageMetadata(int imageIndex)
0868 throws IOException {
0869 if (getOutput() == null) {
0870 throw new IllegalStateException("getOutput() == null!");
0871 }
0872 return false;
0873 }
0874
0875 /**
0876 * Replaces the image metadata associated with an existing image.
0877 *
0878 * <p> If <code>canReplaceImageMetadata(imageIndex)</code> returns
0879 * <code>false</code>, an
0880 * <code>UnsupportedOperationException</code> will be thrown.
0881 *
0882 * <p> The default implementation throws an
0883 * <code>IllegalStateException</code> if the output is
0884 * <code>null</code>, and otherwise throws an
0885 * <code>UnsupportedOperationException</code>.
0886 *
0887 * @param imageIndex the index of the image whose metadata is to
0888 * be replaced.
0889 * @param imageMetadata an <code>IIOMetadata</code> object
0890 * representing image metadata, or <code>null</code>.
0891 *
0892 * @exception IllegalStateException if the output has not been
0893 * set.
0894 * @exception UnsupportedOperationException if
0895 * <code>canReplaceImageMetadata</code> returns
0896 * <code>false</code>.
0897 * @exception IndexOutOfBoundsException if <code>imageIndex</code>
0898 * is less than 0 or greater than the largest available index.
0899 * @exception IOException if an error occurs during writing.
0900 */
0901 public void replaceImageMetadata(int imageIndex,
0902 IIOMetadata imageMetadata) throws IOException {
0903 unsupported();
0904 }
0905
0906 // Image insertion
0907
0908 /**
0909 * Returns <code>true</code> if the writer supports the insertion
0910 * of a new image at the given index. Existing images with
0911 * indices greater than or equal to the insertion index will have
0912 * their indices increased by 1. A value for
0913 * <code>imageIndex</code> of <code>-1</code> may be used to
0914 * signify an index one larger than the current largest index.
0915 *
0916 * <p> A writer that does not support any image insertion may
0917 * return <code>false</code> without performing bounds checking on
0918 * the index.
0919 *
0920 * <p> The default implementation throws an
0921 * <code>IllegalStateException</code> if the output is
0922 * <code>null</code>, and otherwise returns <code>false</code>
0923 * withour checking the value of <code>imageIndex</code>.
0924 *
0925 * @param imageIndex the index at which the image is to be
0926 * inserted.
0927 *
0928 * @return <code>true</code> if an image may be inserted at the
0929 * given index.
0930 *
0931 * @exception IllegalStateException if the output has not
0932 * been set.
0933 * @exception IndexOutOfBoundsException if the writer supports
0934 * image insertion in general, but <code>imageIndex</code> is less
0935 * than -1 or greater than the largest available index.
0936 * @exception IOException if an I/O error occurs during the query.
0937 */
0938 public boolean canInsertImage(int imageIndex) throws IOException {
0939 if (getOutput() == null) {
0940 throw new IllegalStateException("getOutput() == null!");
0941 }
0942 return false;
0943 }
0944
0945 /**
0946 * Inserts a new image into an existing image stream. Existing
0947 * images with an index greater than <code>imageIndex</code> are
0948 * preserved, and their indices are each increased by 1. A value
0949 * for <code>imageIndex</code> of -1 may be used to signify an
0950 * index one larger than the previous largest index; that is, it
0951 * will cause the image to be logically appended to the end of the
0952 * sequence. If the output is an <code>ImageOutputStream</code>,
0953 * the entirety of the stream must be both readable and writeable.
0954 *
0955 * <p> If <code>canInsertImage(imageIndex)</code> returns
0956 * <code>false</code>, an
0957 * <code>UnsupportedOperationException</code> will be thrown.
0958 *
0959 * <p> An <code>ImageWriteParam</code> may optionally be supplied
0960 * to control the writing process. If <code>param</code> is
0961 * <code>null</code>, a default write param will be used.
0962 *
0963 * <p> If the supplied <code>ImageWriteParam</code> contains
0964 * optional setting values not supported by this writer (<i>e.g.</i>
0965 * progressive encoding or any format-specific settings), they
0966 * will be ignored.
0967 *
0968 * <p> The default implementation throws an
0969 * <code>IllegalStateException</code> if the output is
0970 * <code>null</code>, and otherwise throws an
0971 * <code>UnsupportedOperationException</code>.
0972 *
0973 * @param imageIndex the index at which to write the image.
0974 * @param image an <code>IIOImage</code> object containing an
0975 * image, thumbnails, and metadata to be written.
0976 * @param param an <code>ImageWriteParam</code>, or
0977 * <code>null</code> to use a default
0978 * <code>ImageWriteParam</code>.
0979 *
0980 * @exception IllegalStateException if the output has not
0981 * been set.
0982 * @exception UnsupportedOperationException if
0983 * <code>canInsertImage(imageIndex)</code> returns <code>false</code>.
0984 * @exception IllegalArgumentException if <code>image</code> is
0985 * <code>null</code>.
0986 * @exception IndexOutOfBoundsException if <code>imageIndex</code>
0987 * is less than -1 or greater than the largest available index.
0988 * @exception UnsupportedOperationException if <code>image</code>
0989 * contains a <code>Raster</code> and <code>canWriteRasters</code>
0990 * returns <code>false</code>.
0991 * @exception IOException if an error occurs during writing.
0992 */
0993 public void writeInsert(int imageIndex, IIOImage image,
0994 ImageWriteParam param) throws IOException {
0995 unsupported();
0996 }
0997
0998 // Image removal
0999
1000 /**
1001 * Returns <code>true</code> if the writer supports the removal
1002 * of an existing image at the given index. Existing images with
1003 * indices greater than the insertion index will have
1004 * their indices decreased by 1.
1005 *
1006 * <p> A writer that does not support any image removal may
1007 * return <code>false</code> without performing bounds checking on
1008 * the index.
1009 *
1010 * <p> The default implementation throws an
1011 * <code>IllegalStateException</code> if the output is
1012 * <code>null</code>, and otherwise returns <code>false</code>
1013 * without checking the value of <code>imageIndex</code>.
1014 *
1015 * @param imageIndex the index of the image to be removed.
1016 *
1017 * @return <code>true</code> if it is possible to remove the given
1018 * image.
1019 *
1020 * @exception IllegalStateException if the output has not
1021 * been set.
1022 * @exception IndexOutOfBoundsException if the writer supports
1023 * image removal in general, but <code>imageIndex</code> is less
1024 * than 0 or greater than the largest available index.
1025 * @exception IOException if an I/O error occurs during the
1026 * query.
1027 */
1028 public boolean canRemoveImage(int imageIndex) throws IOException {
1029 if (getOutput() == null) {
1030 throw new IllegalStateException("getOutput() == null!");
1031 }
1032 return false;
1033 }
1034
1035 /**
1036 * Removes an image from the stream.
1037 *
1038 * <p> If <code>canRemoveImage(imageIndex)</code> returns false,
1039 * an <code>UnsupportedOperationException</code>will be thrown.
1040 *
1041 * <p> The removal may or may not cause a reduction in the actual
1042 * file size.
1043 *
1044 * <p> The default implementation throws an
1045 * <code>IllegalStateException</code> if the output is
1046 * <code>null</code>, and otherwise throws an
1047 * <code>UnsupportedOperationException</code>.
1048 *
1049 * @param imageIndex the index of the image to be removed.
1050 *
1051 * @exception IllegalStateException if the output has not
1052 * been set.
1053 * @exception UnsupportedOperationException if
1054 * <code>canRemoveImage(imageIndex)</code> returns <code>false</code>.
1055 * @exception IndexOutOfBoundsException if <code>imageIndex</code>
1056 * is less than 0 or greater than the largest available index.
1057 * @exception IOException if an I/O error occurs during the
1058 * removal.
1059 */
1060 public void removeImage(int imageIndex) throws IOException {
1061 unsupported();
1062 }
1063
1064 // Empty images
1065
1066 /**
1067 * Returns <code>true</code> if the writer supports the writing of
1068 * a complete image stream consisting of a single image with
1069 * undefined pixel values and associated metadata and thumbnails
1070 * to the output. The pixel values may be defined by future
1071 * calls to the <code>replacePixels</code> methods. If the output
1072 * is an <code>ImageOutputStream</code>, its existing contents
1073 * prior to the current seek position are not affected, and need
1074 * not be readable or writable.
1075 *
1076 * <p> The default implementation throws an
1077 * <code>IllegalStateException</code> if the output is
1078 * <code>null</code>, and otherwise returns <code>false</code>.
1079 *
1080 * @return <code>true</code> if the writing of complete image
1081 * stream with contents to be defined later is supported.
1082 *
1083 * @exception IllegalStateException if the output has not been
1084 * set.
1085 * @exception IOException if an I/O error occurs during the
1086 * query.
1087 */
1088 public boolean canWriteEmpty() throws IOException {
1089 if (getOutput() == null) {
1090 throw new IllegalStateException("getOutput() == null!");
1091 }
1092 return false;
1093 }
1094
1095 /**
1096 * Begins the writing of a complete image stream, consisting of a
1097 * single image with undefined pixel values and associated
1098 * metadata and thumbnails, to the output. The pixel values will
1099 * be defined by future calls to the <code>replacePixels</code>
1100 * methods. If the output is an <code>ImageOutputStream</code>,
1101 * its existing contents prior to the current seek position are
1102 * not affected, and need not be readable or writable.
1103 *
1104 * <p> The writing is not complete until a call to
1105 * <code>endWriteEmpty</code> occurs. Calls to
1106 * <code>prepareReplacePixels</code>, <code>replacePixels</code>,
1107 * and <code>endReplacePixels</code> may occur between calls to
1108 * <code>prepareWriteEmpty</code> and <code>endWriteEmpty</code>.
1109 * However, calls to <code>prepareWriteEmpty</code> cannot be
1110 * nested, and calls to <code>prepareWriteEmpty</code> and
1111 * <code>prepareInsertEmpty</code> may not be interspersed.
1112 *
1113 * <p> If <code>canWriteEmpty</code> returns <code>false</code>,
1114 * an <code>UnsupportedOperationException</code> will be thrown.
1115 *
1116 * <p> An <code>ImageWriteParam</code> may optionally be supplied
1117 * to control the writing process. If <code>param</code> is
1118 * <code>null</code>, a default write param will be used.
1119 *
1120 * <p> If the supplied <code>ImageWriteParam</code> contains
1121 * optional setting values not supported by this writer (<i>e.g.</i>
1122 * progressive encoding or any format-specific settings), they
1123 * will be ignored.
1124 *
1125 * <p> The default implementation throws an
1126 * <code>IllegalStateException</code> if the output is
1127 * <code>null</code>, and otherwise throws an
1128 * <code>UnsupportedOperationException</code>.
1129 *
1130 * @param streamMetadata an <code>IIOMetadata</code> object representing
1131 * stream metadata, or <code>null</code> to use default values.
1132 * @param imageType an <code>ImageTypeSpecifier</code> describing
1133 * the layout of the image.
1134 * @param width the width of the image.
1135 * @param height the height of the image.
1136 * @param imageMetadata an <code>IIOMetadata</code> object
1137 * representing image metadata, or <code>null</code>.
1138 * @param thumbnails a <code>List</code> of
1139 * <code>BufferedImage</code> thumbnails for this image, or
1140 * <code>null</code>.
1141 * @param param an <code>ImageWriteParam</code>, or
1142 * <code>null</code> to use a default
1143 * <code>ImageWriteParam</code>.
1144 *
1145 * @exception IllegalStateException if the output has not
1146 * been set.
1147 * @exception UnsupportedOperationException if
1148 * <code>canWriteEmpty</code> returns <code>false</code>.
1149 * @exception IllegalStateException if a previous call to
1150 * <code>prepareWriteEmpty</code> has been made without a
1151 * corresponding call to <code>endWriteEmpty</code>.
1152 * @exception IllegalStateException if a previous call to
1153 * <code>prepareInsertEmpty</code> has been made without a
1154 * corresponding call to <code>endInsertEmpty</code>.
1155 * @exception IllegalArgumentException if <code>imageType</code>
1156 * is <code>null</code> or <code>thumbnails</code> contains
1157 * <code>null</code> references or objects other than
1158 * <code>BufferedImage</code>s.
1159 * @exception IllegalArgumentException if width or height are less
1160 * than 1.
1161 * @exception IOException if an I/O error occurs during writing.
1162 */
1163 public void prepareWriteEmpty(IIOMetadata streamMetadata,
1164 ImageTypeSpecifier imageType, int width, int height,
1165 IIOMetadata imageMetadata,
1166 List<? extends BufferedImage> thumbnails,
1167 ImageWriteParam param) throws IOException {
1168 unsupported();
1169 }
1170
1171 /**
1172 * Completes the writing of a new image that was begun with a
1173 * prior call to <code>prepareWriteEmpty</code>.
1174 *
1175 * <p> If <code>canWriteEmpty()</code> returns <code>false</code>,
1176 * an <code>UnsupportedOperationException</code> will be thrown.
1177 *
1178 * <p> The default implementation throws an
1179 * <code>IllegalStateException</code> if the output is
1180 * <code>null</code>, and otherwise throws an
1181 * <code>UnsupportedOperationException</code>.
1182 *
1183 * @exception IllegalStateException if the output has not
1184 * been set.
1185 * @exception UnsupportedOperationException if
1186 * <code>canWriteEmpty(imageIndex)</code> returns
1187 * <code>false</code>.
1188 * @exception IllegalStateException if a previous call to
1189 * <code>prepareWriteEmpty</code> without a corresponding call to
1190 * <code>endWriteEmpty</code> has not been made.
1191 * @exception IllegalStateException if a previous call to
1192 * <code>prepareInsertEmpty</code> without a corresponding call to
1193 * <code>endInsertEmpty</code> has been made.
1194 * @exception IllegalStateException if a call to
1195 * <code>prepareReiplacePixels</code> has been made without a
1196 * matching call to <code>endReplacePixels</code>.
1197 * @exception IOException if an I/O error occurs during writing.
1198 */
1199 public void endWriteEmpty() throws IOException {
1200 if (getOutput() == null) {
1201 throw new IllegalStateException("getOutput() == null!");
1202 }
1203 throw new IllegalStateException("No call to prepareWriteEmpty!");
1204 }
1205
1206 /**
1207 * Returns <code>true</code> if the writer supports the insertion
1208 * of a new, empty image at the given index. The pixel values of
1209 * the image are undefined, and may be specified in pieces using
1210 * the <code>replacePixels</code> methods. Existing images with
1211 * indices greater than or equal to the insertion index will have
1212 * their indices increased by 1. A value for
1213 * <code>imageIndex</code> of <code>-1</code> may be used to
1214 * signify an index one larger than the current largest index.
1215 *
1216 * <p> A writer that does not support insertion of empty images
1217 * may return <code>false</code> without performing bounds
1218 * checking on the index.
1219 *
1220 * <p> The default implementation throws an
1221 * <code>IllegalStateException</code> if the output is
1222 * <code>null</code>, and otherwise returns <code>false</code>
1223 * without checking the value of <code>imageIndex</code>.
1224 *
1225 * @param imageIndex the index at which the image is to be
1226 * inserted.
1227 *
1228 * @return <code>true</code> if an empty image may be inserted at
1229 * the given index.
1230 *
1231 * @exception IllegalStateException if the output has not been
1232 * set.
1233 * @exception IndexOutOfBoundsException if the writer supports
1234 * empty image insertion in general, but <code>imageIndex</code>
1235 * is less than -1 or greater than the largest available index.
1236 * @exception IOException if an I/O error occurs during the
1237 * query.
1238 */
1239 public boolean canInsertEmpty(int imageIndex) throws IOException {
1240 if (getOutput() == null) {
1241 throw new IllegalStateException("getOutput() == null!");
1242 }
1243 return false;
1244 }
1245
1246 /**
1247 * Begins the insertion of a new image with undefined pixel values
1248 * into an existing image stream. Existing images with an index
1249 * greater than <code>imageIndex</code> are preserved, and their
1250 * indices are each increased by 1. A value for
1251 * <code>imageIndex</code> of -1 may be used to signify an index
1252 * one larger than the previous largest index; that is, it will
1253 * cause the image to be logically appended to the end of the
1254 * sequence. If the output is an <code>ImageOutputStream</code>,
1255 * the entirety of the stream must be both readable and writeable.
1256 *
1257 * <p> The image contents may be
1258 * supplied later using the <code>replacePixels</code> method.
1259 * The insertion is not complete until a call to
1260 * <code>endInsertEmpty</code> occurs. Calls to
1261 * <code>prepareReplacePixels</code>, <code>replacePixels</code>,
1262 * and <code>endReplacePixels</code> may occur between calls to
1263 * <code>prepareInsertEmpty</code> and
1264 * <code>endInsertEmpty</code>. However, calls to
1265 * <code>prepareInsertEmpty</code> cannot be nested, and calls to
1266 * <code>prepareWriteEmpty</code> and
1267 * <code>prepareInsertEmpty</code> may not be interspersed.
1268 *
1269 * <p> If <code>canInsertEmpty(imageIndex)</code> returns
1270 * <code>false</code>, an
1271 * <code>UnsupportedOperationException</code> will be thrown.
1272 *
1273 * <p> An <code>ImageWriteParam</code> may optionally be supplied
1274 * to control the writing process. If <code>param</code> is
1275 * <code>null</code>, a default write param will be used.
1276 *
1277 * <p> If the supplied <code>ImageWriteParam</code> contains
1278 * optional setting values not supported by this writer (<i>e.g.</i>
1279 * progressive encoding or any format-specific settings), they
1280 * will be ignored.
1281 *
1282 * <p> The default implementation throws an
1283 * <code>IllegalStateException</code> if the output is
1284 * <code>null</code>, and otherwise throws an
1285 * <code>UnsupportedOperationException</code>.
1286 *
1287 * @param imageIndex the index at which to write the image.
1288 * @param imageType an <code>ImageTypeSpecifier</code> describing
1289 * the layout of the image.
1290 * @param width the width of the image.
1291 * @param height the height of the image.
1292 * @param imageMetadata an <code>IIOMetadata</code> object
1293 * representing image metadata, or <code>null</code>.
1294 * @param thumbnails a <code>List</code> of
1295 * <code>BufferedImage</code> thumbnails for this image, or
1296 * <code>null</code>.
1297 * @param param an <code>ImageWriteParam</code>, or
1298 * <code>null</code> to use a default
1299 * <code>ImageWriteParam</code>.
1300 *
1301 * @exception IllegalStateException if the output has not
1302 * been set.
1303 * @exception UnsupportedOperationException if
1304 * <code>canInsertEmpty(imageIndex)</code> returns
1305 * <code>false</code>.
1306 * @exception IndexOutOfBoundsException if <code>imageIndex</code>
1307 * is less than -1 or greater than the largest available index.
1308 * @exception IllegalStateException if a previous call to
1309 * <code>prepareInsertEmpty</code> has been made without a
1310 * corresponding call to <code>endInsertEmpty</code>.
1311 * @exception IllegalStateException if a previous call to
1312 * <code>prepareWriteEmpty</code> has been made without a
1313 * corresponding call to <code>endWriteEmpty</code>.
1314 * @exception IllegalArgumentException if <code>imageType</code>
1315 * is <code>null</code> or <code>thumbnails</code> contains
1316 * <code>null</code> references or objects other than
1317 * <code>BufferedImage</code>s.
1318 * @exception IllegalArgumentException if width or height are less
1319 * than 1.
1320 * @exception IOException if an I/O error occurs during writing.
1321 */
1322 public void prepareInsertEmpty(int imageIndex,
1323 ImageTypeSpecifier imageType, int width, int height,
1324 IIOMetadata imageMetadata,
1325 List<? extends BufferedImage> thumbnails,
1326 ImageWriteParam param) throws IOException {
1327 unsupported();
1328 }
1329
1330 /**
1331 * Completes the insertion of a new image that was begun with a
1332 * prior call to <code>prepareInsertEmpty</code>.
1333 *
1334 * <p> The default implementation throws an
1335 * <code>IllegalStateException</code> if the output is
1336 * <code>null</code>, and otherwise throws an
1337 * <code>UnsupportedOperationException</code>.
1338 *
1339 * @exception IllegalStateException if the output has not
1340 * been set.
1341 * @exception UnsupportedOperationException if
1342 * <code>canInsertEmpty(imageIndex)</code> returns
1343 * <code>false</code>.
1344 * @exception IllegalStateException if a previous call to
1345 * <code>prepareInsertEmpty</code> without a corresponding call to
1346 * <code>endInsertEmpty</code> has not been made.
1347 * @exception IllegalStateException if a previous call to
1348 * <code>prepareWriteEmpty</code> without a corresponding call to
1349 * <code>endWriteEmpty</code> has been made.
1350 * @exception IllegalStateException if a call to
1351 * <code>prepareReplacePixels</code> has been made without a
1352 * matching call to <code>endReplacePixels</code>.
1353 * @exception IOException if an I/O error occurs during writing.
1354 */
1355 public void endInsertEmpty() throws IOException {
1356 unsupported();
1357 }
1358
1359 // Pixel replacement
1360
1361 /**
1362 * Returns <code>true</code> if the writer allows pixels of the
1363 * given image to be replaced using the <code>replacePixels</code>
1364 * methods.
1365 *
1366 * <p> A writer that does not support any pixel replacement may
1367 * return <code>false</code> without performing bounds checking on
1368 * the index.
1369 *
1370 * <p> The default implementation throws an
1371 * <code>IllegalStateException</code> if the output is
1372 * <code>null</code>, and otherwise returns <code>false</code>
1373 * without checking the value of <code>imageIndex</code>.
1374 *
1375 * @param imageIndex the index of the image whose pixels are to be
1376 * replaced.
1377 *
1378 * @return <code>true</code> if the pixels of the given
1379 * image can be replaced.
1380 *
1381 * @exception IllegalStateException if the output has not been
1382 * set.
1383 * @exception IndexOutOfBoundsException if the writer supports
1384 * pixel replacement in general, but <code>imageIndex</code> is
1385 * less than 0 or greater than the largest available index.
1386 * @exception IOException if an I/O error occurs during the query.
1387 */
1388 public boolean canReplacePixels(int imageIndex) throws IOException {
1389 if (getOutput() == null) {
1390 throw new IllegalStateException("getOutput() == null!");
1391 }
1392 return false;
1393 }
1394
1395 /**
1396 * Prepares the writer to handle a series of calls to the
1397 * <code>replacePixels</code> methods. The affected pixel area
1398 * will be clipped against the supplied
1399 *
1400 * <p> If <code>canReplacePixels</code> returns
1401 * <code>false</code>, and
1402 * <code>UnsupportedOperationException</code> will be thrown.
1403 *
1404 * <p> The default implementation throws an
1405 * <code>IllegalStateException</code> if the output is
1406 * <code>null</code>, and otherwise throws an
1407 * <code>UnsupportedOperationException</code>.
1408 *
1409 * @param imageIndex the index of the image whose pixels are to be
1410 * replaced.
1411 * @param region a <code>Rectangle</code> that will be used to clip
1412 * future pixel regions.
1413 *
1414 * @exception IllegalStateException if the output has not
1415 * been set.
1416 * @exception UnsupportedOperationException if
1417 * <code>canReplacePixels(imageIndex)</code> returns
1418 * <code>false</code>.
1419 * @exception IndexOutOfBoundsException if <code>imageIndex</code>
1420 * is less than 0 or greater than the largest available index.
1421 * @exception IllegalStateException if there is a previous call to
1422 * <code>prepareReplacePixels</code> without a matching call to
1423 * <code>endReplacePixels</code> (<i>i.e.</i>, nesting is not
1424 * allowed).
1425 * @exception IllegalArgumentException if <code>region</code> is
1426 * <code>null</code> or has a width or height less than 1.
1427 * @exception IOException if an I/O error occurs during the
1428 * preparation.
1429 */
1430 public void prepareReplacePixels(int imageIndex, Rectangle region)
1431 throws IOException {
1432 unsupported();
1433 }
1434
1435 /**
1436 * Replaces a portion of an image already present in the output
1437 * with a portion of the given image. The image data must match,
1438 * or be convertible to, the image layout of the existing image.
1439 *
1440 * <p> The destination region is specified in the
1441 * <code>param</code> argument, and will be clipped to the image
1442 * boundaries and the region supplied to
1443 * <code>prepareReplacePixels</code>. At least one pixel of the
1444 * source must not be clipped, or an exception is thrown.
1445 *
1446 * <p> An <code>ImageWriteParam</code> may optionally be supplied
1447 * to control the writing process. If <code>param</code> is
1448 * <code>null</code>, a default write param will be used.
1449 *
1450 * <p> If the supplied <code>ImageWriteParam</code> contains
1451 * optional setting values not supported by this writer (<i>e.g.</i>
1452 * progressive encoding or any format-specific settings), they
1453 * will be ignored.
1454 *
1455 * <p> This method may only be called after a call to
1456 * <code>prepareReplacePixels</code>, or else an
1457 * <code>IllegalStateException</code> will be thrown.
1458 *
1459 * <p> The default implementation throws an
1460 * <code>IllegalStateException</code> if the output is
1461 * <code>null</code>, and otherwise throws an
1462 * <code>UnsupportedOperationException</code>.
1463 *
1464 * @param image a <code>RenderedImage</code> containing source
1465 * pixels.
1466 * @param param an <code>ImageWriteParam</code>, or
1467 * <code>null</code> to use a default
1468 * <code>ImageWriteParam</code>.
1469 *
1470 * @exception IllegalStateException if the output has not
1471 * been set.
1472 * @exception UnsupportedOperationException if
1473 * <code>canReplacePixels(imageIndex)</code> returns
1474 * <code>false</code>.
1475 * @exception IllegalStateException if there is no previous call to
1476 * <code>prepareReplacePixels</code> without a matching call to
1477 * <code>endReplacePixels</code>.
1478 * @exception IllegalArgumentException if any of the following are true:
1479 * <ul>
1480 * <li> <code>image</code> is <code>null</code>.
1481 * <li> <code>param</code> is <code>null</code>.
1482 * <li> the intersected region does not contain at least one pixel.
1483 * <li> the layout of <code>image</code> does not match, or this
1484 * writer cannot convert it to, the existing image layout.
1485 * </ul>
1486 * @exception IOException if an I/O error occurs during writing.
1487 */
1488 public void replacePixels(RenderedImage image, ImageWriteParam param)
1489 throws IOException {
1490 unsupported();
1491 }
1492
1493 /**
1494 * Replaces a portion of an image already present in the output
1495 * with a portion of the given <code>Raster</code>. The image
1496 * data must match, or be convertible to, the image layout of the
1497 * existing image.
1498 *
1499 * <p> An <code>ImageWriteParam</code> may optionally be supplied
1500 * to control the writing process. If <code>param</code> is
1501 * <code>null</code>, a default write param will be used.
1502 *
1503 * <p> The destination region is specified in the
1504 * <code>param</code> argument, and will be clipped to the image
1505 * boundaries and the region supplied to
1506 * <code>prepareReplacePixels</code>. At least one pixel of the
1507 * source must not be clipped, or an exception is thrown.
1508 *
1509 * <p> If the supplied <code>ImageWriteParam</code> contains
1510 * optional setting values not supported by this writer (<i>e.g.</i>
1511 * progressive encoding or any format-specific settings), they
1512 * will be ignored.
1513 *
1514 * <p> This method may only be called after a call to
1515 * <code>prepareReplacePixels</code>, or else an
1516 * <code>IllegalStateException</code> will be thrown.
1517 *
1518 * <p> The default implementation throws an
1519 * <code>IllegalStateException</code> if the output is
1520 * <code>null</code>, and otherwise throws an
1521 * <code>UnsupportedOperationException</code>.
1522 *
1523 * @param raster a <code>Raster</code> containing source
1524 * pixels.
1525 * @param param an <code>ImageWriteParam</code>, or
1526 * <code>null</code> to use a default
1527 * <code>ImageWriteParam</code>.
1528 *
1529 * @exception IllegalStateException if the output has not
1530 * been set.
1531 * @exception UnsupportedOperationException if
1532 * <code>canReplacePixels(imageIndex)</code> returns
1533 * <code>false</code>.
1534 * @exception IllegalStateException if there is no previous call to
1535 * <code>prepareReplacePixels</code> without a matching call to
1536 * <code>endReplacePixels</code>.
1537 * @exception UnsupportedOperationException if
1538 * <code>canWriteRasters</code> returns <code>false</code>.
1539 * @exception IllegalArgumentException if any of the following are true:
1540 * <ul>
1541 * <li> <code>raster</code> is <code>null</code>.
1542 * <li> <code>param</code> is <code>null</code>.
1543 * <li> the intersected region does not contain at least one pixel.
1544 * <li> the layout of <code>raster</code> does not match, or this
1545 * writer cannot convert it to, the existing image layout.
1546 * </ul>
1547 * @exception IOException if an I/O error occurs during writing.
1548 */
1549 public void replacePixels(Raster raster, ImageWriteParam param)
1550 throws IOException {
1551 unsupported();
1552 }
1553
1554 /**
1555 * Terminates a sequence of calls to <code>replacePixels</code>.
1556 *
1557 * <p> If <code>canReplacePixels</code> returns
1558 * <code>false</code>, and
1559 * <code>UnsupportedOperationException</code> will be thrown.
1560 *
1561 * <p> The default implementation throws an
1562 * <code>IllegalStateException</code> if the output is
1563 * <code>null</code>, and otherwise throws an
1564 * <code>UnsupportedOperationException</code>.
1565 *
1566 * @exception IllegalStateException if the output has not
1567 * been set.
1568 * @exception UnsupportedOperationException if
1569 * <code>canReplacePixels(imageIndex)</code> returns
1570 * <code>false</code>.
1571 * @exception IllegalStateException if there is no previous call
1572 * to <code>prepareReplacePixels</code> without a matching call to
1573 * <code>endReplacePixels</code>.
1574 * @exception IOException if an I/O error occurs during writing.
1575 */
1576 public void endReplacePixels() throws IOException {
1577 unsupported();
1578 }
1579
1580 // Abort
1581
1582 /**
1583 * Requests that any current write operation be aborted. The
1584 * contents of the output following the abort will be undefined.
1585 *
1586 * <p> Writers should call <code>clearAbortRequest</code> at the
1587 * beginning of each write operation, and poll the value of
1588 * <code>abortRequested</code> regularly during the write.
1589 */
1590 public synchronized void abort() {
1591 this .abortFlag = true;
1592 }
1593
1594 /**
1595 * Returns <code>true</code> if a request to abort the current
1596 * write operation has been made since the writer was instantiated or
1597 * <code>clearAbortRequest</code> was called.
1598 *
1599 * @return <code>true</code> if the current write operation should
1600 * be aborted.
1601 *
1602 * @see #abort
1603 * @see #clearAbortRequest
1604 */
1605 protected synchronized boolean abortRequested() {
1606 return this .abortFlag;
1607 }
1608
1609 /**
1610 * Clears any previous abort request. After this method has been
1611 * called, <code>abortRequested</code> will return
1612 * <code>false</code>.
1613 *
1614 * @see #abort
1615 * @see #abortRequested
1616 */
1617 protected synchronized void clearAbortRequest() {
1618 this .abortFlag = false;
1619 }
1620
1621 // Listeners
1622
1623 /**
1624 * Adds an <code>IIOWriteWarningListener</code> to the list of
1625 * registered warning listeners. If <code>listener</code> is
1626 * <code>null</code>, no exception will be thrown and no action
1627 * will be taken. Messages sent to the given listener will be
1628 * localized, if possible, to match the current
1629 * <code>Locale</code>. If no <code>Locale</code> has been set,
1630 * warning messages may be localized as the writer sees fit.
1631 *
1632 * @param listener an <code>IIOWriteWarningListener</code> to be
1633 * registered.
1634 *
1635 * @see #removeIIOWriteWarningListener
1636 */
1637 public void addIIOWriteWarningListener(
1638 IIOWriteWarningListener listener) {
1639 if (listener == null) {
1640 return;
1641 }
1642 warningListeners = ImageReader.addToList(warningListeners,
1643 listener);
1644 warningLocales = ImageReader.addToList(warningLocales,
1645 getLocale());
1646 }
1647
1648 /**
1649 * Removes an <code>IIOWriteWarningListener</code> from the list
1650 * of registered warning listeners. If the listener was not
1651 * previously registered, or if <code>listener</code> is
1652 * <code>null</code>, no exception will be thrown and no action
1653 * will be taken.
1654 *
1655 * @param listener an <code>IIOWriteWarningListener</code> to be
1656 * deregistered.
1657 *
1658 * @see #addIIOWriteWarningListener
1659 */
1660 public void removeIIOWriteWarningListener(
1661 IIOWriteWarningListener listener) {
1662 if (listener == null || warningListeners == null) {
1663 return;
1664 }
1665 int index = warningListeners.indexOf(listener);
1666 if (index != -1) {
1667 warningListeners.remove(index);
1668 warningLocales.remove(index);
1669 if (warningListeners.size() == 0) {
1670 warningListeners = null;
1671 warningLocales = null;
1672 }
1673 }
1674 }
1675
1676 /**
1677 * Removes all currently registered
1678 * <code>IIOWriteWarningListener</code> objects.
1679 *
1680 * <p> The default implementation sets the
1681 * <code>warningListeners</code> and <code>warningLocales</code>
1682 * instance variables to <code>null</code>.
1683 */
1684 public void removeAllIIOWriteWarningListeners() {
1685 this .warningListeners = null;
1686 this .warningLocales = null;
1687 }
1688
1689 /**
1690 * Adds an <code>IIOWriteProgressListener</code> to the list of
1691 * registered progress listeners. If <code>listener</code> is
1692 * <code>null</code>, no exception will be thrown and no action
1693 * will be taken.
1694 *
1695 * @param listener an <code>IIOWriteProgressListener</code> to be
1696 * registered.
1697 *
1698 * @see #removeIIOWriteProgressListener
1699 */
1700 public void addIIOWriteProgressListener(
1701 IIOWriteProgressListener listener) {
1702 if (listener == null) {
1703 return;
1704 }
1705 progressListeners = ImageReader.addToList(progressListeners,
1706 listener);
1707 }
1708
1709 /**
1710 * Removes an <code>IIOWriteProgressListener</code> from the list
1711 * of registered progress listeners. If the listener was not
1712 * previously registered, or if <code>listener</code> is
1713 * <code>null</code>, no exception will be thrown and no action
1714 * will be taken.
1715 *
1716 * @param listener an <code>IIOWriteProgressListener</code> to be
1717 * deregistered.
1718 *
1719 * @see #addIIOWriteProgressListener
1720 */
1721 public void removeIIOWriteProgressListener(
1722 IIOWriteProgressListener listener) {
1723 if (listener == null || progressListeners == null) {
1724 return;
1725 }
1726 progressListeners = ImageReader.removeFromList(
1727 progressListeners, listener);
1728 }
1729
1730 /**
1731 * Removes all currently registered
1732 * <code>IIOWriteProgressListener</code> objects.
1733 *
1734 * <p> The default implementation sets the
1735 * <code>progressListeners</code> instance variable to
1736 * <code>null</code>.
1737 */
1738 public void removeAllIIOWriteProgressListeners() {
1739 this .progressListeners = null;
1740 }
1741
1742 /**
1743 * Broadcasts the start of an image write to all registered
1744 * <code>IIOWriteProgressListener</code>s by calling their
1745 * <code>imageStarted</code> method. Subclasses may use this
1746 * method as a convenience.
1747 *
1748 * @param imageIndex the index of the image about to be written.
1749 */
1750 protected void processImageStarted(int imageIndex) {
1751 if (progressListeners == null) {
1752 return;
1753 }
1754 int numListeners = progressListeners.size();
1755 for (int i = 0; i < numListeners; i++) {
1756 IIOWriteProgressListener listener = (IIOWriteProgressListener) progressListeners
1757 .get(i);
1758 listener.imageStarted(this , imageIndex);
1759 }
1760 }
1761
1762 /**
1763 * Broadcasts the current percentage of image completion to all
1764 * registered <code>IIOWriteProgressListener</code>s by calling
1765 * their <code>imageProgress</code> method. Subclasses may use
1766 * this method as a convenience.
1767 *
1768 * @param percentageDone the current percentage of completion,
1769 * as a <code>float</code>.
1770 */
1771 protected void processImageProgress(float percentageDone) {
1772 if (progressListeners == null) {
1773 return;
1774 }
1775 int numListeners = progressListeners.size();
1776 for (int i = 0; i < numListeners; i++) {
1777 IIOWriteProgressListener listener = (IIOWriteProgressListener) progressListeners
1778 .get(i);
1779 listener.imageProgress(this , percentageDone);
1780 }
1781 }
1782
1783 /**
1784 * Broadcasts the completion of an image write to all registered
1785 * <code>IIOWriteProgressListener</code>s by calling their
1786 * <code>imageComplete</code> method. Subclasses may use this
1787 * method as a convenience.
1788 */
1789 protected void processImageComplete() {
1790 if (progressListeners == null) {
1791 return;
1792 }
1793 int numListeners = progressListeners.size();
1794 for (int i = 0; i < numListeners; i++) {
1795 IIOWriteProgressListener listener = (IIOWriteProgressListener) progressListeners
1796 .get(i);
1797 listener.imageComplete(this );
1798 }
1799 }
1800
1801 /**
1802 * Broadcasts the start of a thumbnail write to all registered
1803 * <code>IIOWriteProgressListener</code>s by calling their
1804 * <code>thumbnailStarted</code> method. Subclasses may use this
1805 * method as a convenience.
1806 *
1807 * @param imageIndex the index of the image associated with the
1808 * thumbnail.
1809 * @param thumbnailIndex the index of the thumbnail.
1810 */
1811 protected void processThumbnailStarted(int imageIndex,
1812 int thumbnailIndex) {
1813 if (progressListeners == null) {
1814 return;
1815 }
1816 int numListeners = progressListeners.size();
1817 for (int i = 0; i < numListeners; i++) {
1818 IIOWriteProgressListener listener = (IIOWriteProgressListener) progressListeners
1819 .get(i);
1820 listener.thumbnailStarted(this , imageIndex, thumbnailIndex);
1821 }
1822 }
1823
1824 /**
1825 * Broadcasts the current percentage of thumbnail completion to
1826 * all registered <code>IIOWriteProgressListener</code>s by calling
1827 * their <code>thumbnailProgress</code> method. Subclasses may
1828 * use this method as a convenience.
1829 *
1830 * @param percentageDone the current percentage of completion,
1831 * as a <code>float</code>.
1832 */
1833 protected void processThumbnailProgress(float percentageDone) {
1834 if (progressListeners == null) {
1835 return;
1836 }
1837 int numListeners = progressListeners.size();
1838 for (int i = 0; i < numListeners; i++) {
1839 IIOWriteProgressListener listener = (IIOWriteProgressListener) progressListeners
1840 .get(i);
1841 listener.thumbnailProgress(this , percentageDone);
1842 }
1843 }
1844
1845 /**
1846 * Broadcasts the completion of a thumbnail write to all registered
1847 * <code>IIOWriteProgressListener</code>s by calling their
1848 * <code>thumbnailComplete</code> method. Subclasses may use this
1849 * method as a convenience.
1850 */
1851 protected void processThumbnailComplete() {
1852 if (progressListeners == null) {
1853 return;
1854 }
1855 int numListeners = progressListeners.size();
1856 for (int i = 0; i < numListeners; i++) {
1857 IIOWriteProgressListener listener = (IIOWriteProgressListener) progressListeners
1858 .get(i);
1859 listener.thumbnailComplete(this );
1860 }
1861 }
1862
1863 /**
1864 * Broadcasts that the write has been aborted to all registered
1865 * <code>IIOWriteProgressListener</code>s by calling their
1866 * <code>writeAborted</code> method. Subclasses may use this
1867 * method as a convenience.
1868 */
1869 protected void processWriteAborted() {
1870 if (progressListeners == null) {
1871 return;
1872 }
1873 int numListeners = progressListeners.size();
1874 for (int i = 0; i < numListeners; i++) {
1875 IIOWriteProgressListener listener = (IIOWriteProgressListener) progressListeners
1876 .get(i);
1877 listener.writeAborted(this );
1878 }
1879 }
1880
1881 /**
1882 * Broadcasts a warning message to all registered
1883 * <code>IIOWriteWarningListener</code>s by calling their
1884 * <code>warningOccurred</code> method. Subclasses may use this
1885 * method as a convenience.
1886 *
1887 * @param imageIndex the index of the image on which the warning
1888 * occurred.
1889 * @param warning the warning message.
1890 *
1891 * @exception IllegalArgumentException if <code>warning</code>
1892 * is <code>null</code>.
1893 */
1894 protected void processWarningOccurred(int imageIndex, String warning) {
1895 if (warningListeners == null) {
1896 return;
1897 }
1898 if (warning == null) {
1899 throw new IllegalArgumentException("warning == null!");
1900 }
1901 int numListeners = warningListeners.size();
1902 for (int i = 0; i < numListeners; i++) {
1903 IIOWriteWarningListener listener = (IIOWriteWarningListener) warningListeners
1904 .get(i);
1905
1906 listener.warningOccurred(this , imageIndex, warning);
1907 }
1908 }
1909
1910 /**
1911 * Broadcasts a localized warning message to all registered
1912 * <code>IIOWriteWarningListener</code>s by calling their
1913 * <code>warningOccurred</code> method with a string taken
1914 * from a <code>ResourceBundle</code>. Subclasses may use this
1915 * method as a convenience.
1916 *
1917 * @param imageIndex the index of the image on which the warning
1918 * occurred.
1919 * @param baseName the base name of a set of
1920 * <code>ResourceBundle</code>s containing localized warning
1921 * messages.
1922 * @param keyword the keyword used to index the warning message
1923 * within the set of <code>ResourceBundle</code>s.
1924 *
1925 * @exception IllegalArgumentException if <code>baseName</code>
1926 * is <code>null</code>.
1927 * @exception IllegalArgumentException if <code>keyword</code>
1928 * is <code>null</code>.
1929 * @exception IllegalArgumentException if no appropriate
1930 * <code>ResourceBundle</code> may be located.
1931 * @exception IllegalArgumentException if the named resource is
1932 * not found in the located <code>ResourceBundle</code>.
1933 * @exception IllegalArgumentException if the object retrieved
1934 * from the <code>ResourceBundle</code> is not a
1935 * <code>String</code>.
1936 */
1937 protected void processWarningOccurred(int imageIndex,
1938 String baseName, String keyword) {
1939 if (warningListeners == null) {
1940 return;
1941 }
1942 if (baseName == null) {
1943 throw new IllegalArgumentException("baseName == null!");
1944 }
1945 if (keyword == null) {
1946 throw new IllegalArgumentException("keyword == null!");
1947 }
1948 int numListeners = warningListeners.size();
1949 for (int i = 0; i < numListeners; i++) {
1950 IIOWriteWarningListener listener = (IIOWriteWarningListener) warningListeners
1951 .get(i);
1952 Locale locale = (Locale) warningLocales.get(i);
1953 if (locale == null) {
1954 locale = Locale.getDefault();
1955 }
1956
1957 /**
1958 * If an applet supplies an implementation of ImageWriter and
1959 * resource bundles, then the resource bundle will need to be
1960 * accessed via the applet class loader. So first try the context
1961 * class loader to locate the resource bundle.
1962 * If that throws MissingResourceException, then try the
1963 * system class loader.
1964 */
1965 ClassLoader loader = (ClassLoader) java.security.AccessController
1966 .doPrivileged(new java.security.PrivilegedAction() {
1967 public Object run() {
1968 return Thread.currentThread()
1969 .getContextClassLoader();
1970 }
1971 });
1972
1973 ResourceBundle bundle = null;
1974 try {
1975 bundle = ResourceBundle.getBundle(baseName, locale,
1976 loader);
1977 } catch (MissingResourceException mre) {
1978 try {
1979 bundle = ResourceBundle.getBundle(baseName, locale);
1980 } catch (MissingResourceException mre1) {
1981 throw new IllegalArgumentException(
1982 "Bundle not found!");
1983 }
1984 }
1985
1986 String warning = null;
1987 try {
1988 warning = bundle.getString(keyword);
1989 } catch (ClassCastException cce) {
1990 throw new IllegalArgumentException(
1991 "Resource is not a String!");
1992 } catch (MissingResourceException mre) {
1993 throw new IllegalArgumentException(
1994 "Resource is missing!");
1995 }
1996
1997 listener.warningOccurred(this , imageIndex, warning);
1998 }
1999 }
2000
2001 // State management
2002
2003 /**
2004 * Restores the <code>ImageWriter</code> to its initial state.
2005 *
2006 * <p> The default implementation calls
2007 * <code>setOutput(null)</code>, <code>setLocale(null)</code>,
2008 * <code>removeAllIIOWriteWarningListeners()</code>,
2009 * <code>removeAllIIOWriteProgressListeners()</code>, and
2010 * <code>clearAbortRequest</code>.
2011 */
2012 public void reset() {
2013 setOutput(null);
2014 setLocale(null);
2015 removeAllIIOWriteWarningListeners();
2016 removeAllIIOWriteProgressListeners();
2017 clearAbortRequest();
2018 }
2019
2020 /**
2021 * Allows any resources held by this object to be released. The
2022 * result of calling any other method (other than
2023 * <code>finalize</code>) subsequent to a call to this method
2024 * is undefined.
2025 *
2026 * <p>It is important for applications to call this method when they
2027 * know they will no longer be using this <code>ImageWriter</code>.
2028 * Otherwise, the writer may continue to hold on to resources
2029 * indefinitely.
2030 *
2031 * <p>The default implementation of this method in the superclass does
2032 * nothing. Subclass implementations should ensure that all resources,
2033 * especially native resources, are released.
2034 */
2035 public void dispose() {
2036 }
2037 }
|