KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > imageio > ImageWriter


1 /*
2  * @(#)ImageWriter.java 1.94 04/05/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.imageio;
9
10 import java.awt.Dimension JavaDoc;
11 import java.awt.Rectangle JavaDoc;
12 import java.awt.image.BufferedImage JavaDoc;
13 import java.awt.image.RenderedImage JavaDoc;
14 import java.awt.image.Raster JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Locale JavaDoc;
19 import java.util.MissingResourceException JavaDoc;
20 import java.util.ResourceBundle JavaDoc;
21 import javax.imageio.event.IIOWriteWarningListener JavaDoc;
22 import javax.imageio.event.IIOWriteProgressListener JavaDoc;
23 import javax.imageio.metadata.IIOMetadata JavaDoc;
24 import javax.imageio.stream.ImageOutputStream JavaDoc;
25 import javax.imageio.spi.ImageWriterSpi JavaDoc;
26
27 /**
28  * An abstract superclass for encoding and writing images. This class
29  * must be subclassed by classes that write out images in the context
30  * of the Java Image I/O framework.
31  *
32  * <p> <code>ImageWriter</code> objects are normally instantiated by
33  * the service provider class for the specific format. Service
34  * provider classes are registered with the <code>IIORegistry</code>,
35  * which uses them for format recognition and presentation of
36  * available format readers and writers.
37  *
38  * <p>
39  *
40  * @see ImageReader
41  * @see ImageWriteParam
42  * @see javax.imageio.spi.IIORegistry
43  * @see javax.imageio.spi.ImageWriterSpi
44  *
45  * @version 0.5
46  */

47 public abstract class ImageWriter implements ImageTranscoder JavaDoc {
48
49     /**
50      * The <code>ImageWriterSpi</code> that instantiated this object,
51      * or <code>null</code> if its identity is not known or none
52      * exists. By default it is initialized to <code>null</code>.
53      */

54     protected ImageWriterSpi JavaDoc originatingProvider = null;
55
56     /**
57      * The <code>ImageOutputStream</code> or other <code>Object</code>
58      * set by <code>setOutput</code> and retrieved by
59      * <code>getOutput</code>. By default it is initialized to
60      * <code>null</code>.
61      */

62     protected Object JavaDoc output = null;
63
64     /**
65      * An array of <code>Locale</code>s that may be used to localize
66      * warning messages and compression setting values, or
67      * <code>null</code> if localization is not supported. By default
68      * it is initialized to <code>null</code>.
69      */

70     protected Locale JavaDoc[] availableLocales = null;
71
72     /**
73      * The current <code>Locale</code> to be used for localization, or
74      * <code>null</code> if none has been set. By default it is
75      * initialized to <code>null</code>.
76      */

77     protected Locale JavaDoc locale = null;
78
79     /**
80      * A <code>List</code> of currently registered
81      * <code>IIOWriteWarningListener</code>s, initialized by default to
82      * <code>null</code>, which is synonymous with an empty
83      * <code>List</code>.
84      */

85     protected List JavaDoc<IIOWriteWarningListener JavaDoc> warningListeners = null;
86
87     /**
88      * A <code>List</code> of <code>Locale</code>s, one for each
89      * element of <code>warningListeners</code>, initialized by default
90      * <code>null</code>, which is synonymous with an empty
91      * <code>List</code>.
92      */

93     protected List JavaDoc<Locale JavaDoc> warningLocales = null;
94
95     /**
96      * A <code>List</code> of currently registered
97      * <code>IIOWriteProgressListener</code>s, initialized by default
98      * <code>null</code>, which is synonymous with an empty
99      * <code>List</code>.
100      */

101     protected List JavaDoc<IIOWriteProgressListener JavaDoc> progressListeners = null;
102
103     /**
104      * If <code>true</code>, the current write operation should be
105      * aborted.
106      */

107     private boolean abortFlag = false;
108
109     /**
110      * Constructs an <code>ImageWriter</code> and sets its
111      * <code>originatingProvider</code> instance variable to the
112      * supplied value.
113      *
114      * <p> Subclasses that make use of extensions should provide a
115      * constructor with signature <code>(ImageWriterSpi,
116      * Object)</code> in order to retrieve the extension object. If
117      * the extension object is unsuitable, an
118      * <code>IllegalArgumentException</code> should be thrown.
119      *
120      * @param originatingProvider the <code>ImageWriterSpi</code> that
121      * is constructing this object, or <code>null</code>.
122      */

123     protected ImageWriter(ImageWriterSpi JavaDoc originatingProvider) {
124         this.originatingProvider = originatingProvider;
125     }
126
127     /**
128      * Returns the <code>ImageWriterSpi</code> object that created
129      * this <code>ImageWriter</code>, or <code>null</code> if this
130      * object was not created through the <code>IIORegistry</code>.
131      *
132      * <p> The default implementation returns the value of the
133      * <code>originatingProvider</code> instance variable.
134      *
135      * @return an <code>ImageWriterSpi</code>, or <code>null</code>.
136      *
137      * @see ImageWriterSpi
138      */

139     public ImageWriterSpi JavaDoc getOriginatingProvider() {
140         return originatingProvider;
141     }
142
143     /**
144      * Sets the destination to the given
145      * <code>ImageOutputStream</code> or other <code>Object</code>.
146      * The destination is assumed to be ready to accept data, and will
147      * not be closed at the end of each write. This allows distributed
148      * imaging applications to transmit a series of images over a
149      * single network connection. If <code>output</code> is
150      * <code>null</code>, any currently set output will be removed.
151      *
152      * <p> If <code>output</code> is an
153      * <code>ImageOutputStream</code>, calls to the
154      * <code>write</code>, <code>writeToSequence</code>, and
155      * <code>prepareWriteEmpty</code>/<code>endWriteEmpty</code>
156      * methods will preserve the existing contents of the stream.
157      * Other write methods, such as <code>writeInsert</code>,
158      * <code>replaceStreamMetadata</code>,
159      * <code>replaceImageMetadata</code>, <code>replacePixels</code>,
160      * <code>prepareInsertEmpty</code>/<code>endInsertEmpty</code>,
161      * and <code>endWriteSequence</code>, require the full contents
162      * of the stream to be readable and writable, and may alter any
163      * portion of the stream.
164      *
165      * <p> Use of a general <code>Object</code> other than an
166      * <code>ImageOutputStream</code> is intended for writers that
167      * interact directly with an output device or imaging protocol.
168      * The set of legal classes is advertised by the writer's service
169      * provider's <code>getOutputTypes</code> method; most writers
170      * will return a single-element array containing only
171      * <code>ImageOutputStream.class</code> to indicate that they
172      * accept only an <code>ImageOutputStream</code>.
173      *
174      * <p> The default implementation sets the <code>output</code>
175      * instance variable to the value of <code>output</code> after
176      * checking <code>output</code> against the set of classes
177      * advertised by the originating provider, if there is one.
178      *
179      * @param output the <code>ImageOutputStream</code> or other
180      * <code>Object</code> to use for future writing.
181      *
182      * @exception IllegalArgumentException if <code>output</code> is
183      * not an instance of one of the classes returned by the
184      * originating service provider's <code>getOutputTypes</code>
185      * method.
186      *
187      * @see #getOutput
188      */

189     public void setOutput(Object JavaDoc output) {
190         if (output != null) {
191             ImageWriterSpi JavaDoc provider = getOriginatingProvider();
192             if (provider != null) {
193                 Class JavaDoc[] classes = provider.getOutputTypes();
194                 boolean found = false;
195                 for (int i = 0; i < classes.length; i++) {
196                     if (classes[i].isInstance(output)) {
197                         found = true;
198                         break;
199                     }
200                 }
201                 if (!found) {
202                     throw new IllegalArgumentException JavaDoc("Illegal output type!");
203                 }
204             }
205         }
206
207         this.output = output;
208     }
209
210     /**
211      * Returns the <code>ImageOutputStream</code> or other
212      * <code>Object</code> set by the most recent call to the
213      * <code>setOutput</code> method. If no destination has been
214      * set, <code>null</code> is returned.
215      *
216      * <p> The default implementation returns the value of the
217      * <code>output</code> instance variable.
218      *
219      * @return the <code>Object</code> that was specified using
220      * <code>setOutput</code>, or <code>null</code>.
221      *
222      * @see #setOutput
223      */

224     public Object JavaDoc getOutput() {
225         return output;
226     }
227
228     // Localization
229

230     /**
231      * Returns an array of <code>Locale</code>s that may be used to
232      * localize warning listeners and compression settings. A return
233      * value of <code>null</code> indicates that localization is not
234      * supported.
235      *
236      * <p> The default implementation returns a clone of the
237      * <code>availableLocales</code> instance variable if it is
238      * non-<code>null</code>, or else returns <code>null</code>.
239      *
240      * @return an array of <code>Locale</code>s that may be used as
241      * arguments to <code>setLocale</code>, or <code>null</code>.
242      */

243     public Locale JavaDoc[] getAvailableLocales() {
244         return (availableLocales == null) ?
245             null : (Locale JavaDoc[])availableLocales.clone();
246     }
247
248     /**
249      * Sets the current <code>Locale</code> of this
250      * <code>ImageWriter</code> to the given value. A value of
251      * <code>null</code> removes any previous setting, and indicates
252      * that the writer should localize as it sees fit.
253      *
254      * <p> The default implementation checks <code>locale</code>
255      * against the values returned by
256      * <code>getAvailableLocales</code>, and sets the
257      * <code>locale</code> instance variable if it is found. If
258      * <code>locale</code> is <code>null</code>, the instance variable
259      * is set to <code>null</code> without any checking.
260      *
261      * @param locale the desired <code>Locale</code>, or
262      * <code>null</code>.
263      *
264      * @exception IllegalArgumentException if <code>locale</code> is
265      * non-<code>null</code> but is not one of the values returned by
266      * <code>getAvailableLocales</code>.
267      *
268      * @see #getLocale
269      */

270     public void setLocale(Locale JavaDoc locale) {
271         if (locale != null) {
272             Locale JavaDoc[] locales = getAvailableLocales();
273             boolean found = false;
274             if (locales != null) {
275                 for (int i = 0; i < locales.length; i++) {
276                     if (locale.equals(locales[i])) {
277                         found = true;
278                         break;
279                     }
280                 }
281             }
282             if (!found) {
283                 throw new IllegalArgumentException JavaDoc("Invalid locale!");
284             }
285         }
286         this.locale = locale;
287     }
288
289     /**
290      * Returns the currently set <code>Locale</code>, or
291      * <code>null</code> if none has been set.
292      *
293      * <p> The default implementation returns the value of the
294      * <code>locale</code> instance variable.
295      *
296      * @return the current <code>Locale</code>, or <code>null</code>.
297      *
298      * @see #setLocale
299      */

300     public Locale JavaDoc getLocale() {
301         return locale;
302     }
303
304     // Write params
305

306     /**
307      * Returns a new <code>ImageWriteParam</code> object of the
308      * appropriate type for this file format containing default
309      * values, that is, those values that would be used
310      * if no <code>ImageWriteParam</code> object were specified. This
311      * is useful as a starting point for tweaking just a few parameters
312      * and otherwise leaving the default settings alone.
313      *
314      * <p> The default implementation constructs and returns a new
315      * <code>ImageWriteParam</code> object that does not allow tiling,
316      * progressive encoding, or compression, and that will be
317      * localized for the current <code>Locale</code> (<i>i.e.</i>,
318      * what you would get by calling <code>new
319      * ImageWriteParam(getLocale())</code>.
320      *
321      * <p> Individual plug-ins may return an instance of
322      * <code>ImageWriteParam</code> with additional optional features
323      * enabled, or they may return an instance of a plug-in specific
324      * subclass of <code>ImageWriteParam</code>.
325      *
326      * @return a new <code>ImageWriteParam</code> object containing
327      * default values.
328      */

329     public ImageWriteParam JavaDoc getDefaultWriteParam() {
330         return new ImageWriteParam JavaDoc(getLocale());
331     }
332
333     // Metadata
334

335     /**
336      * Returns an <code>IIOMetadata</code> object containing default
337      * values for encoding a stream of images. The contents of the
338      * object may be manipulated using either the XML tree structure
339      * returned by the <code>IIOMetadata.getAsTree</code> method, an
340      * <code>IIOMetadataController</code> object, or via plug-in
341      * specific interfaces, and the resulting data supplied to one of
342      * the <code>write</code> methods that take a stream metadata
343      * parameter.
344      *
345      * <p> An optional <code>ImageWriteParam</code> may be supplied
346      * for cases where it may affect the structure of the stream
347      * metadata.
348      *
349      * <p> If the supplied <code>ImageWriteParam</code> contains
350      * optional setting values not supported by this writer (<i>e.g.</i>
351      * progressive encoding or any format-specific settings), they
352      * will be ignored.
353      *
354      * <p> Writers that do not make use of stream metadata
355      * (<i>e.g.</i>, writers for single-image formats) should return
356      * <code>null</code>.
357      *
358      * @param param an <code>ImageWriteParam</code> that will be used to
359      * encode the image, or <code>null</code>.
360      *
361      * @return an <code>IIOMetadata</code> object.
362      */

363     public abstract IIOMetadata JavaDoc
364         getDefaultStreamMetadata(ImageWriteParam JavaDoc param);
365
366     /**
367      * Returns an <code>IIOMetadata</code> object containing default
368      * values for encoding an image of the given type. The contents
369      * of the object may be manipulated using either the XML tree
370      * structure returned by the <code>IIOMetadata.getAsTree</code>
371      * method, an <code>IIOMetadataController</code> object, or via
372      * plug-in specific interfaces, and the resulting data supplied to
373      * one of the <code>write</code> methods that take a stream
374      * metadata parameter.
375      *
376      * <p> An optional <code>ImageWriteParam</code> may be supplied
377      * for cases where it may affect the structure of the image
378      * metadata.
379      *
380      * <p> If the supplied <code>ImageWriteParam</code> contains
381      * optional setting values not supported by this writer (<i>e.g.</i>
382      * progressive encoding or any format-specific settings), they
383      * will be ignored.
384      *
385      * @param imageType an <code>ImageTypeSpecifier</code> indicating the
386      * format of the image to be written later.
387      * @param param an <code>ImageWriteParam</code> that will be used to
388      * encode the image, or <code>null</code>.
389      *
390      * @return an <code>IIOMetadata</code> object.
391      */

392     public abstract IIOMetadata JavaDoc
393         getDefaultImageMetadata(ImageTypeSpecifier JavaDoc imageType,
394                                 ImageWriteParam JavaDoc param);
395
396     // comment inherited
397
public abstract IIOMetadata JavaDoc convertStreamMetadata(IIOMetadata JavaDoc inData,
398                                                       ImageWriteParam JavaDoc param);
399
400     // comment inherited
401
public abstract IIOMetadata JavaDoc
402         convertImageMetadata(IIOMetadata JavaDoc inData,
403                              ImageTypeSpecifier JavaDoc imageType,
404                              ImageWriteParam JavaDoc param);
405
406     // Thumbnails
407

408     /**
409      * Returns the number of thumbnails suported by the format being
410      * written, given the image type and any additional write
411      * parameters and metadata objects that will be used during
412      * encoding. A return value of <code>-1</code> indicates that
413      * insufficient information is available.
414      *
415      * <p> An <code>ImageWriteParam</code> may optionally be supplied
416      * for cases where it may affect thumbnail handling.
417      *
418      * <p> If the supplied <code>ImageWriteParam</code> contains
419      * optional setting values not supported by this writer (<i>e.g.</i>
420      * progressive encoding or any format-specific settings), they
421      * will be ignored.
422      *
423      * <p> The default implementation returns 0.
424      *
425      * @param imageType an <code>ImageTypeSpecifier</code> indicating
426      * the type of image to be written, or <code>null</code>.
427      * @param param the <code>ImageWriteParam</code> that will be used for
428      * writing, or <code>null</code>.
429      * @param streamMetadata an <code>IIOMetadata</code> object that will
430      * be used for writing, or <code>null</code>.
431      * @param imageMetadata an <code>IIOMetadata</code> object that will
432      * be used for writing, or <code>null</code>.
433      *
434      * @return the number of thumbnails that may be written given the
435      * supplied parameters, or <code>-1</code> if insufficient
436      * information is available.
437      */

438     public int getNumThumbnailsSupported(ImageTypeSpecifier JavaDoc imageType,
439                                          ImageWriteParam JavaDoc param,
440                                          IIOMetadata JavaDoc streamMetadata,
441                                          IIOMetadata JavaDoc imageMetadata) {
442         return 0;
443     }
444
445     /**
446      * Returns an array of <code>Dimension</code>s indicating the
447      * legal size ranges for thumbnail images as they will be encoded
448      * in the output file or stream. This information is merely
449      * advisory; the writer will resize any supplied thumbnails as
450      * necessary.
451      *
452      * <p> The information is returned as a set of pairs; the first
453      * element of a pair contains an (inclusive) minimum width and
454      * height, and the second element contains an (inclusive) maximum
455      * width and height. Together, each pair defines a valid range of
456      * sizes. To specify a fixed size, the same width and height will
457      * appear for both elements. A return value of <code>null</code>
458      * indicates that the size is arbitrary or unknown.
459      *
460      * <p> An <code>ImageWriteParam</code> may optionally be supplied
461      * for cases where it may affect thumbnail handling.
462      *
463      * <p> If the supplied <code>ImageWriteParam</code> contains
464      * optional setting values not supported by this writer (<i>e.g.</i>
465      * progressive encoding or any format-specific settings), they
466      * will be ignored.
467      *
468      * <p> The default implementation returns <code>null</code>.
469      *
470      * @param imageType an <code>ImageTypeSpecifier</code> indicating the
471      * type of image to be written, or <code>null</code>.
472      * @param param the <code>ImageWriteParam</code> that will be used for
473      * writing, or <code>null</code>.
474      * @param streamMetadata an <code>IIOMetadata</code> object that will
475      * be used for writing, or <code>null</code>.
476      * @param imageMetadata an <code>IIOMetadata</code> object that will
477      * be used for writing, or <code>null</code>.
478      *
479      * @return an array of <code>Dimension</code>s with an even length
480      * of at least two, or <code>null</code>.
481      */

482     public Dimension JavaDoc[] getPreferredThumbnailSizes(ImageTypeSpecifier JavaDoc imageType,
483                                                   ImageWriteParam JavaDoc param,
484                                                   IIOMetadata JavaDoc streamMetadata,
485                                                   IIOMetadata JavaDoc imageMetadata) {
486         return null;
487     }
488
489     /**
490      * Returns <code>true</code> if the methods that take an
491      * <code>IIOImage</code> parameter are capable of dealing with a
492      * <code>Raster</code> (as opposed to <code>RenderedImage</code>)
493      * source image. If this method returns <code>false</code>, then
494      * those methods will throw an
495      * <code>UnsupportedOperationException</code> if supplied with an
496      * <code>IIOImage</code> containing a <code>Raster</code>.
497      *
498      * <p> The default implementation returns <code>false</code>.
499      *
500      * @return <code>true</code> if <code>Raster</code> sources are
501      * supported.
502      */

503     public boolean canWriteRasters() {
504         return false;
505     }
506
507     /**
508      * Appends a complete image stream containing a single image and
509      * associated stream and image metadata and thumbnails to the
510      * output. Any necessary header information is included. If the
511      * output is an <code>ImageOutputStream</code>, its existing
512      * contents prior to the current seek position are not affected,
513      * and need not be readable or writable.
514      *
515      * <p> The output must have been set beforehand using the
516      * <code>setOutput</code> method.
517      *
518      * <p> Stream metadata may optionally be supplied; if it is
519      * <code>null</code>, default stream metadata will be used.
520      *
521      * <p> If <code>canWriteRasters</code> returns <code>true</code>,
522      * the <code>IIOImage</code> may contain a <code>Raster</code>
523      * source. Otherwise, it must contain a
524      * <code>RenderedImage</code> source.
525      *
526      * <p> The supplied thumbnails will be resized if needed, and any
527      * thumbnails in excess of the supported number will be ignored.
528      * If the format requires additional thumbnails that are not
529      * provided, the writer should generate them internally.
530      *
531      * <p> An <code>ImageWriteParam</code> may
532      * optionally be supplied to control the writing process. If
533      * <code>param</code> is <code>null</code>, a default write param
534      * will be used.
535      *
536      * <p> If the supplied <code>ImageWriteParam</code> contains
537      * optional setting values not supported by this writer (<i>e.g.</i>
538      * progressive encoding or any format-specific settings), they
539      * will be ignored.
540      *
541      * @param streamMetadata an <code>IIOMetadata</code> object representing
542      * stream metadata, or <code>null</code> to use default values.
543      * @param image an <code>IIOImage</code> object containing an
544      * image, thumbnails, and metadata to be written.
545      * @param param an <code>ImageWriteParam</code>, or
546      * <code>null</code> to use a default
547      * <code>ImageWriteParam</code>.
548      *
549      * @exception IllegalStateException if the output has not
550      * been set.
551      * @exception UnsupportedOperationException if <code>image</code>
552      * contains a <code>Raster</code> and <code>canWriteRasters</code>
553      * returns <code>false</code>.
554      * @exception IllegalArgumentException if <code>image</code> is
555      * <code>null</code>.
556      * @exception IOException if an error occurs during writing.
557      */

558     public abstract void write(IIOMetadata JavaDoc streamMetadata,
559                                IIOImage JavaDoc image,
560                                ImageWriteParam JavaDoc param) throws IOException JavaDoc;
561
562     /**
563      * Appends a complete image stream containing a single image with
564      * default metadata and thumbnails to the output. This method is
565      * a shorthand for <code>write(null, image, null)</code>.
566      *
567      * @param image an <code>IIOImage</code> object containing an
568      * image, thumbnails, and metadata to be written.
569      *
570      * @exception IllegalStateException if the output has not
571      * been set.
572      * @exception IllegalArgumentException if <code>image</code> is
573      * <code>null</code>.
574      * @exception UnsupportedOperationException if <code>image</code>
575      * contains a <code>Raster</code> and <code>canWriteRasters</code>
576      * returns <code>false</code>.
577      * @exception IOException if an error occurs during writing.
578      */

579     public void write(IIOImage JavaDoc image) throws IOException JavaDoc {
580         write(null, image, null);
581     }
582
583     /**
584      * Appends a complete image stream consisting of a single image
585      * with default metadata and thumbnails to the output. This
586      * method is a shorthand for <code>write(null, new IIOImage(image,
587      * null, null), null)</code>.
588      *
589      * @param image a <code>RenderedImage</code> to be written.
590      *
591      * @exception IllegalStateException if the output has not
592      * been set.
593      * @exception IllegalArgumentException if <code>image</code> is
594      * <code>null</code>.
595      * @exception IOException if an error occurs during writing.
596      */

597     public void write(RenderedImage JavaDoc image) throws IOException JavaDoc {
598         write(null, new IIOImage JavaDoc(image, null, null), null);
599     }
600
601     // Check that the output has been set, then throw an
602
// UnsupportedOperationException.
603
private void unsupported() {
604         if (getOutput() == null) {
605             throw new IllegalStateException JavaDoc("getOutput() == null!");
606         }
607         throw new UnsupportedOperationException JavaDoc("Unsupported write variant!");
608     }
609
610     // Sequence writes
611

612     /**
613      * Returns <code>true</code> if the writer is able to append an
614      * image to an image stream that already contains header
615      * information and possibly prior images.
616      *
617      * <p> If <code>canWriteSequence</code> returns <code>false</code>,
618      * <code>writeToSequence</code> and <code>endWriteSequence</code>
619      * will throw an <code>UnsupportedOperationException</code>.
620      *
621      * <p> The default implementation returns <code>false</code>.
622      *
623      * @return <code>true</code> if images may be appended sequentially.
624      */

625     public boolean canWriteSequence() {
626         return false;
627     }
628
629     /**
630      * Prepares a stream to accept a series of subsequent
631      * <code>writeToSequence</code> calls, using the provided stream
632      * metadata object. The metadata will be written to the stream if
633      * it should precede the image data. If the argument is <code>null</code>,
634      * default stream metadata is used.
635      *
636      * <p> If the output is an <code>ImageOutputStream</code>, the existing
637      * contents of the output prior to the current seek position are
638      * flushed, and need not be readable or writable. If the format
639      * requires that <code>endWriteSequence</code> be able to rewind to
640      * patch up the header information, such as for a sequence of images
641      * in a single TIFF file, then the metadata written by this method
642      * must remain in a writable portion of the stream. Other formats
643      * may flush the stream after this method and after each image.
644      *
645      * <p> If <code>canWriteSequence</code> returns <code>false</code>,
646      * this method will throw an
647      * <code>UnsupportedOperationException</code>.
648      *
649      * <p> The output must have been set beforehand using either
650      * the <code>setOutput</code> method.
651      *
652      * <p> The default implementation throws an
653      * <code>IllegalStateException</code> if the output is
654      * <code>null</code>, and otherwise throws an
655      * <code>UnsupportedOperationException</code>.
656      *
657      * @param streamMetadata A stream metadata object, or <code>null</code>.
658      *
659      * @exception IllegalStateException if the output has not
660      * been set.
661      * @exception UnsupportedOperationException if
662      * <code>canWriteSequence</code> returns <code>false</code>.
663      * @exception IOException if an error occurs writing the stream
664      * metadata.
665      */

666     public void prepareWriteSequence(IIOMetadata JavaDoc streamMetadata)
667         throws IOException JavaDoc {
668         unsupported();
669     }
670
671     /**
672      * Appends a single image and possibly associated metadata and
673      * thumbnails, to the output. If the output is an
674      * <code>ImageOutputStream</code>, the existing contents of the
675      * output prior to the current seek position may be flushed, and
676      * need not be readable or writable, unless the plug-in needs to
677      * be able to patch up the header information when
678      * <code>endWriteSequence</code> is called (<italic>e.g.</italic> TIFF).
679      *
680      * <p> If <code>canWriteSequence</code> returns <code>false</code>,
681      * this method will throw an
682      * <code>UnsupportedOperationException</code>.
683      *
684      * <p> The output must have been set beforehand using
685      * the <code>setOutput</code> method.
686      *
687      * <p> <code>prepareWriteSequence</code> must have been called
688      * beforehand, or an <code>IllegalStateException</code> is thrown.
689      *
690      * <p> If <code>canWriteRasters</code> returns <code>true</code>,
691      * the <code>IIOImage</code> may contain a <code>Raster</code>
692      * source. Otherwise, it must contain a
693      * <code>RenderedImage</code> source.
694      *
695      * <p> The supplied thumbnails will be resized if needed, and any
696      * thumbnails in excess of the supported number will be ignored.
697      * If the format requires additional thumbnails that are not
698      * provided, the writer will generate them internally.
699      *
700      * <p> An <code>ImageWriteParam</code> may optionally be supplied
701      * to control the writing process. If <code>param</code> is
702      * <code>null</code>, a default write param will be used.
703      *
704      * <p> If the supplied <code>ImageWriteParam</code> contains
705      * optional setting values not supported by this writer (<i>e.g.</i>
706      * progressive encoding or any format-specific settings), they
707      * will be ignored.
708      *
709      * <p> The default implementation throws an
710      * <code>IllegalStateException</code> if the output is
711      * <code>null</code>, and otherwise throws an
712      * <code>UnsupportedOperationException</code>.
713      *
714      * @param image an <code>IIOImage</code> object containing an
715      * image, thumbnails, and metadata to be written.
716      * @param param an <code>ImageWriteParam</code>, or
717      * <code>null</code> to use a default
718      * <code>ImageWriteParam</code>.
719      *
720      * @exception IllegalStateException if the output has not
721      * been set, or <code>prepareWriteSequence</code> has not been called.
722      * @exception UnsupportedOperationException if
723      * <code>canWriteSequence</code> returns <code>false</code>.
724      * @exception IllegalArgumentException if <code>image</code> is
725      * <code>null</code>.
726      * @exception UnsupportedOperationException if <code>image</code>
727      * contains a <code>Raster</code> and <code>canWriteRasters</code>
728      * returns <code>false</code>.
729      * @exception IOException if an error occurs during writing.
730      */

731     public void writeToSequence(IIOImage JavaDoc image, ImageWriteParam JavaDoc param)
732         throws IOException JavaDoc {
733         unsupported();
734     }
735
736     /**
737      * Completes the writing of a sequence of images begun with
738      * <code>prepareWriteSequence</code>. Any stream metadata that
739      * should come at the end of the sequence of images is written out,
740      * and any header information at the beginning of the sequence is
741      * patched up if necessary. If the output is an
742      * <code>ImageOutputStream</code>, data through the stream metadata
743      * at the end of the sequence are flushed and need not be readable
744      * or writable.
745      *
746      * <p> If <code>canWriteSequence</code> returns <code>false</code>,
747      * this method will throw an
748      * <code>UnsupportedOperationException</code>.
749      *
750      * <p> The default implementation throws an
751      * <code>IllegalStateException</code> if the output is
752      * <code>null</code>, and otherwise throws an
753      * <code>UnsupportedOperationException</code>.
754      *
755      * @exception IllegalStateException if the output has not
756      * been set, or <code>prepareWriteSequence</code> has not been called.
757      * @exception UnsupportedOperationException if
758      * <code>canWriteSequence</code> returns <code>false</code>.
759      * @exception IOException if an error occurs during writing.
760      */

761     public void endWriteSequence() throws IOException JavaDoc {
762         unsupported();
763     }
764
765     // Metadata replacement
766

767     /**
768      * Returns <code>true</code> if it is possible to replace the
769      * stream metadata already present in the output.
770      *
771      * <p> The default implementation throws an
772      * <code>IllegalStateException</code> if the output is
773      * <code>null</code>, and otherwise returns <code>false</code>.
774      *
775      * @return <code>true</code> if replacement of stream metadata is
776      * allowed.
777      *
778      * @exception IllegalStateException if the output has not
779      * been set.
780      * @exception IOException if an I/O error occurs during the query.
781      */

782     public boolean canReplaceStreamMetadata() throws IOException JavaDoc {
783         if (getOutput() == null) {
784             throw new IllegalStateException JavaDoc("getOutput() == null!");
785         }
786         return false;
787     }
788
789     /**
790      * Replaces the stream metadata in the output with new
791      * information. If the output is an
792      * <code>ImageOutputStream</code>, the prior contents of the
793      * stream are examined and possibly edited to make room for the
794      * new data. All of the prior contents of the output must be
795      * available for reading and writing.
796      *
797      * <p> If <code>canReplaceStreamMetadata</code> returns
798      * <code>false</code>, an
799      * <code>UnsupportedOperationException</code> will be thrown.
800      *
801      * <p> The default implementation throws an
802      * <code>IllegalStateException</code> if the output is
803      * <code>null</code>, and otherwise throws an
804      * <code>UnsupportedOperationException</code>.
805      *
806      * @param streamMetadata an <code>IIOMetadata</code> object representing
807      * stream metadata, or <code>null</code> to use default values.
808      *
809      * @exception IllegalStateException if the output has not
810      * been set.
811      * @exception UnsupportedOperationException if the
812      * <code>canReplaceStreamMetadata</code> returns
813      * <code>false</code>. modes do not include
814      * @exception IOException if an error occurs during writing.
815      */

816     public void replaceStreamMetadata(IIOMetadata JavaDoc streamMetadata)
817         throws IOException JavaDoc {
818         unsupported();
819     }
820
821     /**
822      * Returns <code>true</code> if it is possible to replace the
823      * image metadata associated with an existing image with index
824      * <code>imageIndex</code>. If this method returns
825      * <code>false</code>, a call to
826      * <code>replaceImageMetadata(imageIndex)</code> will throw an
827      * <code>UnsupportedOperationException</code>.
828      *
829      * <p> A writer that does not support any image metadata
830      * replacement may return <code>false</code> without performing
831      * bounds checking on the index.
832      *
833      * <p> The default implementation throws an
834      * <code>IllegalStateException</code> if the output is
835      * <code>null</code>, and otherwise returns <code>false</code>
836      * without checking the value of <code>imageIndex</code>.
837      *
838      * @param imageIndex the index of the image whose metadata is to
839      * be replaced.
840      *
841      * @return <code>true</code> if the image metadata of the given
842      * image can be replaced.
843      *
844      * @exception IllegalStateException if the output has not
845      * been set.
846      * @exception IndexOutOfBoundsException if the writer supports
847      * image metadata replacement in general, but
848      * <code>imageIndex</code> is less than 0 or greater than the
849      * largest available index.
850      * @exception IOException if an I/O error occurs during the query.
851      */

852     public boolean canReplaceImageMetadata(int imageIndex)
853         throws IOException JavaDoc {
854         if (getOutput() == null) {
855             throw new IllegalStateException JavaDoc("getOutput() == null!");
856         }
857         return false;
858     }
859
860     /**
861      * Replaces the image metadata associated with an existing image.
862      *
863      * <p> If <code>canReplaceImageMetadata(imageIndex)</code> returns
864      * <code>false</code>, an
865      * <code>UnsupportedOperationException</code> will be thrown.
866      *
867      * <p> The default implementation throws an
868      * <code>IllegalStateException</code> if the output is
869      * <code>null</code>, and otherwise throws an
870      * <code>UnsupportedOperationException</code>.
871      *
872      * @param imageIndex the index of the image whose metadata is to
873      * be replaced.
874      * @param imageMetadata an <code>IIOMetadata</code> object
875      * representing image metadata, or <code>null</code>.
876      *
877      * @exception IllegalStateException if the output has not been
878      * set.
879      * @exception UnsupportedOperationException if
880      * <code>canReplaceImageMetadata</code> returns
881      * <code>false</code>.
882      * @exception IndexOutOfBoundsException if <code>imageIndex</code>
883      * is less than 0 or greater than the largest available index.
884      * @exception IOException if an error occurs during writing.
885      */

886     public void replaceImageMetadata(int imageIndex,
887                                      IIOMetadata JavaDoc imageMetadata)
888         throws IOException JavaDoc {
889         unsupported();
890     }
891
892     // Image insertion
893

894     /**
895      * Returns <code>true</code> if the writer supports the insertion
896      * of a new image at the given index. Existing images with
897      * indices greater than or equal to the insertion index will have
898      * their indices increased by 1. A value for
899      * <code>imageIndex</code> of <code>-1</code> may be used to
900      * signify an index one larger than the current largest index.
901      *
902      * <p> A writer that does not support any image insertion may
903      * return <code>false</code> without performing bounds checking on
904      * the index.
905      *
906      * <p> The default implementation throws an
907      * <code>IllegalStateException</code> if the output is
908      * <code>null</code>, and otherwise returns <code>false</code>
909      * withour checking the value of <code>imageIndex</code>.
910      *
911      * @param imageIndex the index at which the image is to be
912      * inserted.
913      *
914      * @return <code>true</code> if an image may be inserted at the
915      * given index.
916      *
917      * @exception IllegalStateException if the output has not
918      * been set.
919      * @exception IndexOutOfBoundsException if the writer supports
920      * image insertion in general, but <code>imageIndex</code> is less
921      * than -1 or greater than the largest available index.
922      * @exception IOException if an I/O error occurs during the query.
923      */

924     public boolean canInsertImage(int imageIndex) throws IOException JavaDoc {
925         if (getOutput() == null) {
926             throw new IllegalStateException JavaDoc("getOutput() == null!");
927         }
928         return false;
929     }
930
931     /**
932      * Inserts a new image into an existing image stream. Existing
933      * images with an index greater than <code>imageIndex</code> are
934      * preserved, and their indices are each increased by 1. A value
935      * for <code>imageIndex</code> of -1 may be used to signify an
936      * index one larger than the previous largest index; that is, it
937      * will cause the image to be logically appended to the end of the
938      * sequence. If the output is an <code>ImageOutputStream</code>,
939      * the entirety of the stream must be both readable and writeable.
940      *
941      * <p> If <code>canInsertImage(imageIndex)</code> returns
942      * <code>false</code>, an
943      * <code>UnsupportedOperationException</code> will be thrown.
944      *
945      * <p> An <code>ImageWriteParam</code> may optionally be supplied
946      * to control the writing process. If <code>param</code> is
947      * <code>null</code>, a default write param will be used.
948      *
949      * <p> If the supplied <code>ImageWriteParam</code> contains
950      * optional setting values not supported by this writer (<i>e.g.</i>
951      * progressive encoding or any format-specific settings), they
952      * will be ignored.
953      *
954      * <p> The default implementation throws an
955      * <code>IllegalStateException</code> if the output is
956      * <code>null</code>, and otherwise throws an
957      * <code>UnsupportedOperationException</code>.
958      *
959      * @param imageIndex the index at which to write the image.
960      * @param image an <code>IIOImage</code> object containing an
961      * image, thumbnails, and metadata to be written.
962      * @param param an <code>ImageWriteParam</code>, or
963      * <code>null</code> to use a default
964      * <code>ImageWriteParam</code>.
965      *
966      * @exception IllegalStateException if the output has not
967      * been set.
968      * @exception UnsupportedOperationException if
969      * <code>canInsertImage(imageIndex)</code> returns <code>false</code>.
970      * @exception IllegalArgumentException if <code>image</code> is
971      * <code>null</code>.
972      * @exception IndexOutOfBoundsException if <code>imageIndex</code>
973      * is less than -1 or greater than the largest available index.
974      * @exception UnsupportedOperationException if <code>image</code>
975      * contains a <code>Raster</code> and <code>canWriteRasters</code>
976      * returns <code>false</code>.
977      * @exception IOException if an error occurs during writing.
978      */

979     public void writeInsert(int imageIndex,
980                             IIOImage JavaDoc image,
981                             ImageWriteParam JavaDoc param) throws IOException JavaDoc {
982         unsupported();
983     }
984
985     // Image removal
986

987     /**
988      * Returns <code>true</code> if the writer supports the removal
989      * of an existing image at the given index. Existing images with
990      * indices greater than the insertion index will have
991      * their indices decreased by 1.
992      *
993      * <p> A writer that does not support any image removal may
994      * return <code>false</code> without performing bounds checking on
995      * the index.
996      *
997      * <p> The default implementation throws an
998      * <code>IllegalStateException</code> if the output is
999      * <code>null</code>, and otherwise returns <code>false</code>
1000     * without checking the value of <code>imageIndex</code>.
1001     *
1002     * @param imageIndex the index of the image to be removed.
1003     *
1004     * @return <code>true</code> if it is possible to remove the given
1005     * image.
1006     *
1007     * @exception IllegalStateException if the output has not
1008     * been set.
1009     * @exception IndexOutOfBoundsException if the writer supports
1010     * image removal in general, but <code>imageIndex</code> is less
1011     * than 0 or greater than the largest available index.
1012     * @exception IOException if an I/O error occurs during the
1013     * query.
1014     */

1015    public boolean canRemoveImage(int imageIndex) throws IOException JavaDoc {
1016        if (getOutput() == null) {
1017            throw new IllegalStateException JavaDoc("getOutput() == null!");
1018        }
1019        return false;
1020    }
1021
1022    /**
1023     * Removes an image from the stream.
1024     *
1025     * <p> If <code>canRemoveImage(imageIndex)</code> returns false,
1026     * an <code>UnsupportedOperationException</code>will be thrown.
1027     *
1028     * <p> The removal may or may not cause a reduction in the actual
1029     * file size.
1030     *
1031     * <p> The default implementation throws an
1032     * <code>IllegalStateException</code> if the output is
1033     * <code>null</code>, and otherwise throws an
1034     * <code>UnsupportedOperationException</code>.
1035     *
1036     * @param imageIndex the index of the image to be removed.
1037     *
1038     * @exception IllegalStateException if the output has not
1039     * been set.
1040     * @exception UnsupportedOperationException if
1041     * <code>canRemoveImage(imageIndex)</code> returns <code>false</code>.
1042     * @exception IndexOutOfBoundsException if <code>imageIndex</code>
1043     * is less than 0 or greater than the largest available index.
1044     * @exception IOException if an I/O error occurs during the
1045     * removal.
1046     */

1047    public void removeImage(int imageIndex) throws IOException JavaDoc {
1048        unsupported();
1049    }
1050
1051    // Empty images
1052

1053    /**
1054     * Returns <code>true</code> if the writer supports the writing of
1055     * a complete image stream consisting of a single image with
1056     * undefined pixel values and associated metadata and thumbnails
1057     * to the output. The pixel values may be defined by future
1058     * calls to the <code>replacePixels</code> methods. If the output
1059     * is an <code>ImageOutputStream</code>, its existing contents
1060     * prior to the current seek position are not affected, and need
1061     * not be readable or writable.
1062     *
1063     * <p> The default implementation throws an
1064     * <code>IllegalStateException</code> if the output is
1065     * <code>null</code>, and otherwise returns <code>false</code>.
1066     *
1067     * @return <code>true</code> if the writing of complete image
1068     * stream with contents to be defined later is supported.
1069     *
1070     * @exception IllegalStateException if the output has not been
1071     * set.
1072     * @exception IOException if an I/O error occurs during the
1073     * query.
1074     */

1075    public boolean canWriteEmpty() throws IOException JavaDoc {
1076        if (getOutput() == null) {
1077            throw new IllegalStateException JavaDoc("getOutput() == null!");
1078        }
1079        return false;
1080    }
1081
1082    /**
1083     * Begins the writing of a complete image stream, consisting of a
1084     * single image with undefined pixel values and associated
1085     * metadata and thumbnails, to the output. The pixel values will
1086     * be defined by future calls to the <code>replacePixels</code>
1087     * methods. If the output is an <code>ImageOutputStream</code>,
1088     * its existing contents prior to the current seek position are
1089     * not affected, and need not be readable or writable.
1090     *
1091     * <p> The writing is not complete until a call to
1092     * <code>endWriteEmpty</code> occurs. Calls to
1093     * <code>prepareReplacePixels</code>, <code>replacePixels</code>,
1094     * and <code>endReplacePixels</code> may occur between calls to
1095     * <code>prepareWriteEmpty</code> and <code>endWriteEmpty</code>.
1096     * However, calls to <code>prepareWriteEmpty</code> cannot be
1097     * nested, and calls to <code>prepareWriteEmpty</code> and
1098     * <code>prepareInsertEmpty</code> may not be interspersed.
1099     *
1100     * <p> If <code>canWriteEmpty</code> returns <code>false</code>,
1101     * an <code>UnsupportedOperationException</code> will be thrown.
1102     *
1103     * <p> An <code>ImageWriteParam</code> may optionally be supplied
1104     * to control the writing process. If <code>param</code> is
1105     * <code>null</code>, a default write param will be used.
1106     *
1107     * <p> If the supplied <code>ImageWriteParam</code> contains
1108     * optional setting values not supported by this writer (<i>e.g.</i>
1109     * progressive encoding or any format-specific settings), they
1110     * will be ignored.
1111     *
1112     * <p> The default implementation throws an
1113     * <code>IllegalStateException</code> if the output is
1114     * <code>null</code>, and otherwise throws an
1115     * <code>UnsupportedOperationException</code>.
1116     *
1117     * @param streamMetadata an <code>IIOMetadata</code> object representing
1118     * stream metadata, or <code>null</code> to use default values.
1119     * @param imageType an <code>ImageTypeSpecifier</code> describing
1120     * the layout of the image.
1121     * @param width the width of the image.
1122     * @param height the height of the image.
1123     * @param imageMetadata an <code>IIOMetadata</code> object
1124     * representing image metadata, or <code>null</code>.
1125     * @param thumbnails a <code>List</code> of
1126     * <code>BufferedImage</code> thumbnails for this image, or
1127     * <code>null</code>.
1128     * @param param an <code>ImageWriteParam</code>, or
1129     * <code>null</code> to use a default
1130     * <code>ImageWriteParam</code>.
1131     *
1132     * @exception IllegalStateException if the output has not
1133     * been set.
1134     * @exception UnsupportedOperationException if
1135     * <code>canWriteEmpty</code> returns <code>false</code>.
1136     * @exception IllegalStateException if a previous call to
1137     * <code>prepareWriteEmpty</code> has been made without a
1138     * corresponding call to <code>endWriteEmpty</code>.
1139     * @exception IllegalStateException if a previous call to
1140     * <code>prepareInsertEmpty</code> has been made without a
1141     * corresponding call to <code>endInsertEmpty</code>.
1142     * @exception IllegalArgumentException if <code>imageType</code>
1143     * is <code>null</code> or <code>thumbnails</code> contains
1144     * <code>null</code> references or objects other than
1145     * <code>BufferedImage</code>s.
1146     * @exception IllegalArgumentException if width or height are less
1147     * than 1.
1148     * @exception IOException if an I/O error occurs during writing.
1149     */

1150    public void prepareWriteEmpty(IIOMetadata JavaDoc streamMetadata,
1151                                  ImageTypeSpecifier JavaDoc imageType,
1152                                  int width, int height,
1153                                  IIOMetadata JavaDoc imageMetadata,
1154                                  List JavaDoc<? extends BufferedImage JavaDoc> thumbnails,
1155                                  ImageWriteParam JavaDoc param) throws IOException JavaDoc {
1156        unsupported();
1157    }
1158
1159    /**
1160     * Completes the writing of a new image that was begun with a
1161     * prior call to <code>prepareWriteEmpty</code>.
1162     *
1163     * <p> If <code>canWriteEmpty()</code> returns <code>false</code>,
1164     * an <code>UnsupportedOperationException</code> will be thrown.
1165     *
1166     * <p> The default implementation throws an
1167     * <code>IllegalStateException</code> if the output is
1168     * <code>null</code>, and otherwise throws an
1169     * <code>UnsupportedOperationException</code>.
1170     *
1171     * @exception IllegalStateException if the output has not
1172     * been set.
1173     * @exception UnsupportedOperationException if
1174     * <code>canWriteEmpty(imageIndex)</code> returns
1175     * <code>false</code>.
1176     * @exception IllegalStateException if a previous call to
1177     * <code>prepareWriteEmpty</code> without a corresponding call to
1178     * <code>endWriteEmpty</code> has not been made.
1179     * @exception IllegalStateException if a previous call to
1180     * <code>prepareInsertEmpty</code> without a corresponding call to
1181     * <code>endInsertEmpty</code> has been made.
1182     * @exception IllegalStateException if a call to
1183     * <code>prepareReiplacePixels</code> has been made without a
1184     * matching call to <code>endReplacePixels</code>.
1185     * @exception IOException if an I/O error occurs during writing.
1186     */

1187    public void endWriteEmpty() throws IOException JavaDoc {
1188        if (getOutput() == null) {
1189            throw new IllegalStateException JavaDoc("getOutput() == null!");
1190        }
1191        throw new IllegalStateException JavaDoc("No call to prepareWriteEmpty!");
1192    }
1193
1194    /**
1195     * Returns <code>true</code> if the writer supports the insertion
1196     * of a new, empty image at the given index. The pixel values of
1197     * the image are undefined, and may be specified in pieces using
1198     * the <code>replacePixels</code> methods. Existing images with
1199     * indices greater than or equal to the insertion index will have
1200     * their indices increased by 1. A value for
1201     * <code>imageIndex</code> of <code>-1</code> may be used to
1202     * signify an index one larger than the current largest index.
1203     *
1204     * <p> A writer that does not support insertion of empty images
1205     * may return <code>false</code> without performing bounds
1206     * checking on the index.
1207     *
1208     * <p> The default implementation throws an
1209     * <code>IllegalStateException</code> if the output is
1210     * <code>null</code>, and otherwise returns <code>false</code>
1211     * without checking the value of <code>imageIndex</code>.
1212     *
1213     * @param imageIndex the index at which the image is to be
1214     * inserted.
1215     *
1216     * @return <code>true</code> if an empty image may be inserted at
1217     * the given index.
1218     *
1219     * @exception IllegalStateException if the output has not been
1220     * set.
1221     * @exception IndexOutOfBoundsException if the writer supports
1222     * empty image insertion in general, but <code>imageIndex</code>
1223     * is less than -1 or greater than the largest available index.
1224     * @exception IOException if an I/O error occurs during the
1225     * query.
1226     */

1227    public boolean canInsertEmpty(int imageIndex) throws IOException JavaDoc {
1228        if (getOutput() == null) {
1229            throw new IllegalStateException JavaDoc("getOutput() == null!");
1230        }
1231        return false;
1232    }
1233
1234    /**
1235     * Begins the insertion of a new image with undefined pixel values
1236     * into an existing image stream. Existing images with an index
1237     * greater than <code>imageIndex</code> are preserved, and their
1238     * indices are each increased by 1. A value for
1239     * <code>imageIndex</code> of -1 may be used to signify an index
1240     * one larger than the previous largest index; that is, it will
1241     * cause the image to be logically appended to the end of the
1242     * sequence. If the output is an <code>ImageOutputStream</code>,
1243     * the entirety of the stream must be both readable and writeable.
1244     *
1245     * <p> The image contents may be
1246     * supplied later using the <code>replacePixels</code> method.
1247     * The insertion is not complete until a call to
1248     * <code>endInsertEmpty</code> occurs. Calls to
1249     * <code>prepareReplacePixels</code>, <code>replacePixels</code>,
1250     * and <code>endReplacePixels</code> may occur between calls to
1251     * <code>prepareInsertEmpty</code> and
1252     * <code>endInsertEmpty</code>. However, calls to
1253     * <code>prepareInsertEmpty</code> cannot be nested, and calls to
1254     * <code>prepareWriteEmpty</code> and
1255     * <code>prepareInsertEmpty</code> may not be interspersed.
1256     *
1257     * <p> If <code>canInsertEmpty(imageIndex)</code> returns
1258     * <code>false</code>, an
1259     * <code>UnsupportedOperationException</code> will be thrown.
1260     *
1261     * <p> An <code>ImageWriteParam</code> may optionally be supplied
1262     * to control the writing process. If <code>param</code> is
1263     * <code>null</code>, a default write param will be used.
1264     *
1265     * <p> If the supplied <code>ImageWriteParam</code> contains
1266     * optional setting values not supported by this writer (<i>e.g.</i>
1267     * progressive encoding or any format-specific settings), they
1268     * will be ignored.
1269     *
1270     * <p> The default implementation throws an
1271     * <code>IllegalStateException</code> if the output is
1272     * <code>null</code>, and otherwise throws an
1273     * <code>UnsupportedOperationException</code>.
1274     *
1275     * @param imageIndex the index at which to write the image.
1276     * @param imageType an <code>ImageTypeSpecifier</code> describing
1277     * the layout of the image.
1278     * @param width the width of the image.
1279     * @param height the height of the image.
1280     * @param imageMetadata an <code>IIOMetadata</code> object
1281     * representing image metadata, or <code>null</code>.
1282     * @param thumbnails a <code>List</code> of
1283     * <code>BufferedImage</code> thumbnails for this image, or
1284     * <code>null</code>.
1285     * @param param an <code>ImageWriteParam</code>, or
1286     * <code>null</code> to use a default
1287     * <code>ImageWriteParam</code>.
1288     *
1289     * @exception IllegalStateException if the output has not
1290     * been set.
1291     * @exception UnsupportedOperationException if
1292     * <code>canInsertEmpty(imageIndex)</code> returns
1293     * <code>false</code>.
1294     * @exception IndexOutOfBoundsException if <code>imageIndex</code>
1295     * is less than -1 or greater than the largest available index.
1296     * @exception IllegalStateException if a previous call to
1297     * <code>prepareInsertEmpty</code> has been made without a
1298     * corresponding call to <code>endInsertEmpty</code>.
1299     * @exception IllegalStateException if a previous call to
1300     * <code>prepareWriteEmpty</code> has been made without a
1301     * corresponding call to <code>endWriteEmpty</code>.
1302     * @exception IllegalArgumentException if <code>imageType</code>
1303     * is <code>null</code> or <code>thumbnails</code> contains
1304     * <code>null</code> references or objects other than
1305     * <code>BufferedImage</code>s.
1306     * @exception IllegalArgumentException if width or height are less
1307     * than 1.
1308     * @exception IOException if an I/O error occurs during writing.
1309     */

1310    public void prepareInsertEmpty(int imageIndex,
1311                                   ImageTypeSpecifier JavaDoc imageType,
1312                                   int width, int height,
1313                                   IIOMetadata JavaDoc imageMetadata,
1314                                   List JavaDoc<? extends BufferedImage JavaDoc> thumbnails,
1315                                   ImageWriteParam JavaDoc param) throws IOException JavaDoc {
1316        unsupported();
1317    }
1318
1319    /**
1320     * Completes the insertion of a new image that was begun with a
1321     * prior call to <code>prepareInsertEmpty</code>.
1322     *
1323     * <p> The default implementation throws an
1324     * <code>IllegalStateException</code> if the output is
1325     * <code>null</code>, and otherwise throws an
1326     * <code>UnsupportedOperationException</code>.
1327     *
1328     * @exception IllegalStateException if the output has not
1329     * been set.
1330     * @exception UnsupportedOperationException if
1331     * <code>canInsertEmpty(imageIndex)</code> returns
1332     * <code>false</code>.
1333     * @exception IllegalStateException if a previous call to
1334     * <code>prepareInsertEmpty</code> without a corresponding call to
1335     * <code>endInsertEmpty</code> has not been made.
1336     * @exception IllegalStateException if a previous call to
1337     * <code>prepareWriteEmpty</code> without a corresponding call to
1338     * <code>endWriteEmpty</code> has been made.
1339     * @exception IllegalStateException if a call to
1340     * <code>prepareReplacePixels</code> has been made without a
1341     * matching call to <code>endReplacePixels</code>.
1342     * @exception IOException if an I/O error occurs during writing.
1343     */

1344    public void endInsertEmpty() throws IOException JavaDoc {
1345        unsupported();
1346    }
1347
1348    // Pixel replacement
1349

1350    /**
1351     * Returns <code>true</code> if the writer allows pixels of the
1352     * given image to be replaced using the <code>replacePixels</code>
1353     * methods.
1354     *
1355     * <p> A writer that does not support any pixel replacement may
1356     * return <code>false</code> without performing bounds checking on
1357     * the index.
1358     *
1359     * <p> The default implementation throws an
1360     * <code>IllegalStateException</code> if the output is
1361     * <code>null</code>, and otherwise returns <code>false</code>
1362     * without checking the value of <code>imageIndex</code>.
1363     *
1364     * @param imageIndex the index of the image whose pixels are to be
1365     * replaced.
1366     *
1367     * @return <code>true</code> if the pixels of the given
1368     * image can be replaced.
1369     *
1370     * @exception IllegalStateException if the output has not been
1371     * set.
1372     * @exception IndexOutOfBoundsException if the writer supports
1373     * pixel replacement in general, but <code>imageIndex</code> is
1374     * less than 0 or greater than the largest available index.
1375     * @exception IOException if an I/O error occurs during the query.
1376     */

1377    public boolean canReplacePixels(int imageIndex) throws IOException JavaDoc {
1378        if (getOutput() == null) {
1379            throw new IllegalStateException JavaDoc("getOutput() == null!");
1380        }
1381        return false;
1382    }
1383
1384    /**
1385     * Prepares the writer to handle a series of calls to the
1386     * <code>replacePixels</code> methods. The affected pixel area
1387     * will be clipped against the supplied
1388     *
1389     * <p> If <code>canReplacePixels</code> returns
1390     * <code>false</code>, and
1391     * <code>UnsupportedOperationException</code> will be thrown.
1392     *
1393     * <p> The default implementation throws an
1394     * <code>IllegalStateException</code> if the output is
1395     * <code>null</code>, and otherwise throws an
1396     * <code>UnsupportedOperationException</code>.
1397     *
1398     * @param imageIndex the index of the image whose pixels are to be
1399     * replaced.
1400     * @param region a <code>Rectangle</code> that will be used to clip
1401     * future pixel regions.
1402     *
1403     * @exception IllegalStateException if the output has not
1404     * been set.
1405     * @exception UnsupportedOperationException if
1406     * <code>canReplacePixels(imageIndex)</code> returns
1407     * <code>false</code>.
1408     * @exception IndexOutOfBoundsException if <code>imageIndex</code>
1409     * is less than 0 or greater than the largest available index.
1410     * @exception IllegalStateException if there is a previous call to
1411     * <code>prepareReplacePixels</code> without a matching call to
1412     * <code>endReplacePixels</code> (<i>i.e.</i>, nesting is not
1413     * allowed).
1414     * @exception IllegalArgumentException if <code>region</code> is
1415     * <code>null</code> or has a width or height less than 1.
1416     * @exception IOException if an I/O error occurs during the
1417     * preparation.
1418     */

1419    public void prepareReplacePixels(int imageIndex,
1420                                     Rectangle JavaDoc region) throws IOException JavaDoc {
1421        unsupported();
1422    }
1423
1424    /**
1425     * Replaces a portion of an image already present in the output
1426     * with a portion of the given image. The image data must match,
1427     * or be convertible to, the image layout of the existing image.
1428     *
1429     * <p> The destination region is specified in the
1430     * <code>param</code> argument, and will be clipped to the image
1431     * boundaries and the region supplied to
1432     * <code>prepareReplacePixels</code>. At least one pixel of the
1433     * source must not be clipped, or an exception is thrown.
1434     *
1435     * <p> An <code>ImageWriteParam</code> may optionally be supplied
1436     * to control the writing process. If <code>param</code> is
1437     * <code>null</code>, a default write param will be used.
1438     *
1439     * <p> If the supplied <code>ImageWriteParam</code> contains
1440     * optional setting values not supported by this writer (<i>e.g.</i>
1441     * progressive encoding or any format-specific settings), they
1442     * will be ignored.
1443     *
1444     * <p> This method may only be called after a call to
1445     * <code>prepareReplacePixels</code>, or else an
1446     * <code>IllegalStateException</code> will be thrown.
1447     *
1448     * <p> The default implementation throws an
1449     * <code>IllegalStateException</code> if the output is
1450     * <code>null</code>, and otherwise throws an
1451     * <code>UnsupportedOperationException</code>.
1452     *
1453     * @param image a <code>RenderedImage</code> containing source
1454     * pixels.
1455     * @param param an <code>ImageWriteParam</code>, or
1456     * <code>null</code> to use a default
1457     * <code>ImageWriteParam</code>.
1458     *
1459     * @exception IllegalStateException if the output has not
1460     * been set.
1461     * @exception UnsupportedOperationException if
1462     * <code>canReplacePixels(imageIndex)</code> returns
1463     * <code>false</code>.
1464     * @exception IllegalStateException if there is no previous call to
1465     * <code>prepareReplacePixels</code> without a matching call to
1466     * <code>endReplacePixels</code>.
1467     * @exception IllegalArgumentException if any of the following are true:
1468     * <li> <code>image</code> is <code>null</code>.
1469     * <li> <code>param</code> is <code>null</code>.
1470     * <li> the intersected region does not contain at least one pixel.
1471     * <li> the layout of <code>image</code> does not match, or this
1472     * writer cannot convert it to, the existing image layout.
1473     * </ul>
1474     * @exception IOException if an I/O error occurs during writing.
1475     */

1476    public void replacePixels(RenderedImage JavaDoc image, ImageWriteParam JavaDoc param)
1477        throws IOException JavaDoc {
1478        unsupported();
1479    }
1480
1481    /**
1482     * Replaces a portion of an image already present in the output
1483     * with a portion of the given <code>Raster</code>. The image
1484     * data must match, or be convertible to, the image layout of the
1485     * existing image.
1486     *
1487     * <p> An <code>ImageWriteParam</code> may optionally be supplied
1488     * to control the writing process. If <code>param</code> is
1489     * <code>null</code>, a default write param will be used.
1490     *
1491     * <p> The destination region is specified in the
1492     * <code>param</code> argument, and will be clipped to the image
1493     * boundaries and the region supplied to
1494     * <code>prepareReplacePixels</code>. At least one pixel of the
1495     * source must not be clipped, or an exception is thrown.
1496     *
1497     * <p> If the supplied <code>ImageWriteParam</code> contains
1498     * optional setting values not supported by this writer (<i>e.g.</i>
1499     * progressive encoding or any format-specific settings), they
1500     * will be ignored.
1501     *
1502     * <p> This method may only be called after a call to
1503     * <code>prepareReplacePixels</code>, or else an
1504     * <code>IllegalStateException</code> will be thrown.
1505     *
1506     * <p> The default implementation throws an
1507     * <code>IllegalStateException</code> if the output is
1508     * <code>null</code>, and otherwise throws an
1509     * <code>UnsupportedOperationException</code>.
1510     *
1511     * @param raster a <code>Raster</code> containing source
1512     * pixels.
1513     * @param param an <code>ImageWriteParam</code>, or
1514     * <code>null</code> to use a default
1515     * <code>ImageWriteParam</code>.
1516     *
1517     * @exception IllegalStateException if the output has not
1518     * been set.
1519     * @exception UnsupportedOperationException if
1520     * <code>canReplacePixels(imageIndex)</code> returns
1521     * <code>false</code>.
1522     * @exception IllegalStateException if there is no previous call to
1523     * <code>prepareReplacePixels</code> without a matching call to
1524     * <code>endReplacePixels</code>.
1525     * @exception UnsupportedOperationException if
1526     * <code>canWriteRasters</code> returns <code>false</code>.
1527     * @exception IllegalArgumentException if any of the following are true:
1528     * <li> <code>raster</code> is <code>null</code>.
1529     * <li> <code>param</code> is <code>null</code>.
1530     * <li> the intersected region does not contain at least one pixel.
1531     * <li> the layout of <code>raster</code> does not match, or this
1532     * writer cannot convert it to, the existing image layout.
1533     * </ul>
1534     * @exception IOException if an I/O error occurs during writing.
1535     */

1536    public void replacePixels(Raster JavaDoc raster, ImageWriteParam JavaDoc param)
1537        throws IOException JavaDoc {
1538        unsupported();
1539    }
1540
1541    /**
1542     * Terminates a sequence of calls to <code>replacePixels</code>.
1543     *
1544     * <p> If <code>canReplacePixels</code> returns
1545     * <code>false</code>, and
1546     * <code>UnsupportedOperationException</code> will be thrown.
1547     *
1548     * <p> The default implementation throws an
1549     * <code>IllegalStateException</code> if the output is
1550     * <code>null</code>, and otherwise throws an
1551     * <code>UnsupportedOperationException</code>.
1552     *
1553     * @exception IllegalStateException if the output has not
1554     * been set.
1555     * @exception UnsupportedOperationException if
1556     * <code>canReplacePixels(imageIndex)</code> returns
1557     * <code>false</code>.
1558     * @exception IllegalStateException if there is no previous call
1559     * to <code>prepareReplacePixels</code> without a matching call to
1560     * <code>endReplacePixels</code>.
1561     * @exception IOException if an I/O error occurs during writing.
1562     */

1563    public void endReplacePixels() throws IOException JavaDoc {
1564        unsupported();
1565    }
1566
1567    // Abort
1568

1569    /**
1570     * Requests that any current write operation be aborted. The
1571     * contents of the output following the abort will be undefined.
1572     *
1573     * <p> Writers should call <code>clearAbortRequest</code> at the
1574     * beginning of each write operation, and poll the value of
1575     * <code>abortRequested</code> regularly during the write.
1576     */

1577    public synchronized void abort() {
1578        this.abortFlag = true;
1579    }
1580
1581    /**
1582     * Returns <code>true</code> if a request to abort the current
1583     * write operation has been made since the writer was instantiated or
1584     * <code>clearAbortRequest</code> was called.
1585     *
1586     * @return <code>true</code> if the current write operation should
1587     * be aborted.
1588     *
1589     * @see #abort
1590     * @see #clearAbortRequest
1591     */

1592    protected synchronized boolean abortRequested() {
1593        return this.abortFlag;
1594    }
1595
1596    /**
1597     * Clears any previous abort request. After this method has been
1598     * called, <code>abortRequested</code> will return
1599     * <code>false</code>.
1600     *
1601     * @see #abort
1602     * @see #abortRequested
1603     */

1604    protected synchronized void clearAbortRequest() {
1605        this.abortFlag = false;
1606    }
1607
1608    // Listeners
1609

1610    /**
1611     * Adds an <code>IIOWriteWarningListener</code> to the list of
1612     * registered warning listeners. If <code>listener</code> is
1613     * <code>null</code>, no exception will be thrown and no action
1614     * will be taken. Messages sent to the given listener will be
1615     * localized, if possible, to match the current
1616     * <code>Locale</code>. If no <code>Locale</code> has been set,
1617     * warning messages may be localized as the writer sees fit.
1618     *
1619     * @param listener an <code>IIOWriteWarningListener</code> to be
1620     * registered.
1621     *
1622     * @see #removeIIOWriteWarningListener
1623     */

1624    public void addIIOWriteWarningListener(IIOWriteWarningListener JavaDoc listener) {
1625        if (listener == null) {
1626            return;
1627        }
1628        warningListeners = ImageReader.addToList(warningListeners, listener);
1629        warningLocales = ImageReader.addToList(warningLocales, getLocale());
1630    }
1631
1632    /**
1633     * Removes an <code>IIOWriteWarningListener</code> from the list
1634     * of registered warning listeners. If the listener was not
1635     * previously registered, or if <code>listener</code> is
1636     * <code>null</code>, no exception will be thrown and no action
1637     * will be taken.
1638     *
1639     * @param listener an <code>IIOWriteWarningListener</code> to be
1640     * deregistered.
1641     *
1642     * @see #addIIOWriteWarningListener
1643     */

1644    public
1645        void removeIIOWriteWarningListener(IIOWriteWarningListener JavaDoc listener) {
1646        if (listener == null || warningListeners == null) {
1647            return;
1648        }
1649        int index = warningListeners.indexOf(listener);
1650        if (index != -1) {
1651            warningListeners.remove(index);
1652            warningLocales.remove(index);
1653            if (warningListeners.size() == 0) {
1654                warningListeners = null;
1655        warningLocales = null;
1656            }
1657        }
1658    }
1659
1660    /**
1661     * Removes all currently registered
1662     * <code>IIOWriteWarningListener</code> objects.
1663     *
1664     * <p> The default implementation sets the
1665     * <code>warningListeners</code> and <code>warningLocales</code>
1666     * instance variables to <code>null</code>.
1667     */

1668    public void removeAllIIOWriteWarningListeners() {
1669        this.warningListeners = null;
1670        this.warningLocales = null;
1671    }
1672
1673    /**
1674     * Adds an <code>IIOWriteProgressListener</code> to the list of
1675     * registered progress listeners. If <code>listener</code> is
1676     * <code>null</code>, no exception will be thrown and no action
1677     * will be taken.
1678     *
1679     * @param listener an <code>IIOWriteProgressListener</code> to be
1680     * registered.
1681     *
1682     * @see #removeIIOWriteProgressListener
1683     */

1684    public void
1685        addIIOWriteProgressListener(IIOWriteProgressListener JavaDoc listener) {
1686        if (listener == null) {
1687            return;
1688        }
1689        progressListeners = ImageReader.addToList(progressListeners, listener);
1690    }
1691
1692    /**
1693     * Removes an <code>IIOWriteProgressListener</code> from the list
1694     * of registered progress listeners. If the listener was not
1695     * previously registered, or if <code>listener</code> is
1696     * <code>null</code>, no exception will be thrown and no action
1697     * will be taken.
1698     *
1699     * @param listener an <code>IIOWriteProgressListener</code> to be
1700     * deregistered.
1701     *
1702     * @see #addIIOWriteProgressListener
1703     */

1704    public void
1705        removeIIOWriteProgressListener(IIOWriteProgressListener JavaDoc listener) {
1706        if (listener == null || progressListeners == null) {
1707            return;
1708        }
1709        progressListeners =
1710            ImageReader.removeFromList(progressListeners, listener);
1711    }
1712
1713    /**
1714     * Removes all currently registered
1715     * <code>IIOWriteProgressListener</code> objects.
1716     *
1717     * <p> The default implementation sets the
1718     * <code>progressListeners</code> instance variable to
1719     * <code>null</code>.
1720     */

1721    public void removeAllIIOWriteProgressListeners() {
1722        this.progressListeners = null;
1723    }
1724
1725    /**
1726     * Broadcasts the start of an image write to all registered
1727     * <code>IIOWriteProgressListener</code>s by calling their
1728     * <code>imageStarted</code> method. Subclasses may use this
1729     * method as a convenience.
1730     *
1731     * @param imageIndex the index of the image about to be written.
1732     */

1733    protected void processImageStarted(int imageIndex) {
1734        if (progressListeners == null) {
1735            return;
1736        }
1737        int numListeners = progressListeners.size();
1738        for (int i = 0; i < numListeners; i++) {
1739            IIOWriteProgressListener JavaDoc listener =
1740                (IIOWriteProgressListener JavaDoc)progressListeners.get(i);
1741            listener.imageStarted(this, imageIndex);
1742        }
1743    }
1744
1745    /**
1746     * Broadcasts the current percentage of image completion to all
1747     * registered <code>IIOWriteProgressListener</code>s by calling
1748     * their <code>imageProgress</code> method. Subclasses may use
1749     * this method as a convenience.
1750     *
1751     * @param percentageDone the current percentage of completion,
1752     * as a <code>float</code>.
1753     */

1754    protected void processImageProgress(float percentageDone) {
1755        if (progressListeners == null) {
1756            return;
1757        }
1758        int numListeners = progressListeners.size();
1759        for (int i = 0; i < numListeners; i++) {
1760            IIOWriteProgressListener JavaDoc listener =
1761                (IIOWriteProgressListener JavaDoc)progressListeners.get(i);
1762            listener.imageProgress(this, percentageDone);
1763        }
1764    }
1765
1766    /**
1767     * Broadcasts the completion of an image write to all registered
1768     * <code>IIOWriteProgressListener</code>s by calling their
1769     * <code>imageComplete</code> method. Subclasses may use this
1770     * method as a convenience.
1771     */

1772    protected void processImageComplete() {
1773        if (progressListeners == null) {
1774            return;
1775        }
1776        int numListeners = progressListeners.size();
1777        for (int i = 0; i < numListeners; i++) {
1778            IIOWriteProgressListener JavaDoc listener =
1779                (IIOWriteProgressListener JavaDoc)progressListeners.get(i);
1780            listener.imageComplete(this);
1781        }
1782    }
1783
1784    /**
1785     * Broadcasts the start of a thumbnail write to all registered
1786     * <code>IIOWriteProgressListener</code>s by calling their
1787     * <code>thumbnailStarted</code> method. Subclasses may use this
1788     * method as a convenience.
1789     *
1790     * @param imageIndex the index of the image associated with the
1791     * thumbnail.
1792     * @param thumbnailIndex the index of the thumbnail.
1793     */

1794    protected void processThumbnailStarted(int imageIndex,
1795                                           int thumbnailIndex) {
1796        if (progressListeners == null) {
1797            return;
1798        }
1799        int numListeners = progressListeners.size();
1800        for (int i = 0; i < numListeners; i++) {
1801            IIOWriteProgressListener JavaDoc listener =
1802                (IIOWriteProgressListener JavaDoc)progressListeners.get(i);
1803            listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
1804        }
1805    }
1806
1807    /**
1808     * Broadcasts the current percentage of thumbnail completion to
1809     * all registered <code>IIOWriteProgressListener</code>s by calling
1810     * their <code>thumbnailProgress</code> method. Subclasses may
1811     * use this method as a convenience.
1812     *
1813     * @param percentageDone the current percentage of completion,
1814     * as a <code>float</code>.
1815     */

1816    protected void processThumbnailProgress(float percentageDone) {
1817        if (progressListeners == null) {
1818            return;
1819        }
1820        int numListeners = progressListeners.size();
1821        for (int i = 0; i < numListeners; i++) {
1822            IIOWriteProgressListener JavaDoc listener =
1823                (IIOWriteProgressListener JavaDoc)progressListeners.get(i);
1824            listener.thumbnailProgress(this, percentageDone);
1825        }
1826    }
1827
1828    /**
1829     * Broadcasts the completion of a thumbnail write to all registered
1830     * <code>IIOWriteProgressListener</code>s by calling their
1831     * <code>thumbnailComplete</code> method. Subclasses may use this
1832     * method as a convenience.
1833     */

1834    protected void processThumbnailComplete() {
1835        if (progressListeners == null) {
1836            return;
1837        }
1838        int numListeners = progressListeners.size();
1839        for (int i = 0; i < numListeners; i++) {
1840            IIOWriteProgressListener JavaDoc listener =
1841                (IIOWriteProgressListener JavaDoc)progressListeners.get(i);
1842            listener.thumbnailComplete(this);
1843        }
1844    }
1845
1846    /**
1847     * Broadcasts that the write has been aborted to all registered
1848     * <code>IIOWriteProgressListener</code>s by calling their
1849     * <code>writeAborted</code> method. Subclasses may use this
1850     * method as a convenience.
1851     */

1852    protected void processWriteAborted() {
1853        if (progressListeners == null) {
1854            return;
1855        }
1856        int numListeners = progressListeners.size();
1857        for (int i = 0; i < numListeners; i++) {
1858            IIOWriteProgressListener JavaDoc listener =
1859                (IIOWriteProgressListener JavaDoc)progressListeners.get(i);
1860            listener.writeAborted(this);
1861        }
1862    }
1863
1864    /**
1865     * Broadcasts a warning message to all registered
1866     * <code>IIOWriteWarningListener</code>s by calling their
1867     * <code>warningOccurred</code> method. Subclasses may use this
1868     * method as a convenience.
1869     *
1870     * @param imageIndex the index of the image on which the warning
1871     * occurred.
1872     * @param warning the warning message.
1873     *
1874     * @exception IllegalArgumentException if <code>warning</code>
1875     * is <code>null</code>.
1876     */

1877    protected void processWarningOccurred(int imageIndex,
1878                                          String JavaDoc warning) {
1879        if (warningListeners == null) {
1880            return;
1881        }
1882        if (warning == null) {
1883            throw new IllegalArgumentException JavaDoc("warning == null!");
1884        }
1885        int numListeners = warningListeners.size();
1886        for (int i = 0; i < numListeners; i++) {
1887            IIOWriteWarningListener JavaDoc listener =
1888                (IIOWriteWarningListener JavaDoc)warningListeners.get(i);
1889            
1890            listener.warningOccurred(this, imageIndex, warning);
1891        }
1892    }
1893
1894    /**
1895     * Broadcasts a localized warning message to all registered
1896     * <code>IIOWriteWarningListener</code>s by calling their
1897     * <code>warningOccurred</code> method with a string taken
1898     * from a <code>ResourceBundle</code>. Subclasses may use this
1899     * method as a convenience.
1900     *
1901     * @param imageIndex the index of the image on which the warning
1902     * occurred.
1903     * @param baseName the base name of a set of
1904     * <code>ResourceBundle</code>s containing localized warning
1905     * messages.
1906     * @param keyword the keyword used to index the warning message
1907     * within the set of <code>ResourceBundle</code>s.
1908     *
1909     * @exception IllegalArgumentException if <code>baseName</code>
1910     * is <code>null</code>.
1911     * @exception IllegalArgumentException if <code>keyword</code>
1912     * is <code>null</code>.
1913     * @exception IllegalArgumentException if no appropriate
1914     * <code>ResourceBundle</code> may be located.
1915     * @exception IllegalArgumentException if the named resource is
1916     * not found in the located <code>ResourceBundle</code>.
1917     * @exception IllegalArgumentException if the object retrieved
1918     * from the <code>ResourceBundle</code> is not a
1919     * <code>String</code>.
1920     */

1921    protected void processWarningOccurred(int imageIndex,
1922                                          String JavaDoc baseName,
1923                                          String JavaDoc keyword) {
1924        if (warningListeners == null) {
1925            return;
1926        }
1927        if (baseName == null) {
1928            throw new IllegalArgumentException JavaDoc("baseName == null!");
1929        }
1930        if (keyword == null) {
1931            throw new IllegalArgumentException JavaDoc("keyword == null!");
1932        }
1933        int numListeners = warningListeners.size();
1934        for (int i = 0; i < numListeners; i++) {
1935            IIOWriteWarningListener JavaDoc listener =
1936                (IIOWriteWarningListener JavaDoc)warningListeners.get(i);
1937            Locale JavaDoc locale = (Locale JavaDoc)warningLocales.get(i);
1938        if (locale == null) {
1939        locale = Locale.getDefault();
1940        }
1941
1942        /**
1943             * If an applet supplies an implementation of ImageWriter and
1944         * resource bundles, then the resource bundle will need to be
1945         * accessed via the applet class loader. So first try the context
1946         * class loader to locate the resource bundle.
1947         * If that throws MissingResourceException, then try the
1948         * system class loader.
1949         */

1950        ClassLoader JavaDoc loader = (ClassLoader JavaDoc)
1951            java.security.AccessController.doPrivileged(
1952           new java.security.PrivilegedAction JavaDoc() {
1953              public Object JavaDoc run() {
1954                        return Thread.currentThread().getContextClassLoader();
1955              }
1956                });
1957
1958            ResourceBundle JavaDoc bundle = null;
1959            try {
1960                bundle = ResourceBundle.getBundle(baseName, locale, loader);
1961            } catch (MissingResourceException JavaDoc mre) {
1962        try {
1963            bundle = ResourceBundle.getBundle(baseName, locale);
1964        } catch (MissingResourceException JavaDoc mre1) {
1965            throw new IllegalArgumentException JavaDoc("Bundle not found!");
1966        }
1967            }
1968
1969            String JavaDoc warning = null;
1970            try {
1971                warning = bundle.getString(keyword);
1972            } catch (ClassCastException JavaDoc cce) {
1973                throw new IllegalArgumentException JavaDoc("Resource is not a String!");
1974            } catch (MissingResourceException JavaDoc mre) {
1975                throw new IllegalArgumentException JavaDoc("Resource is missing!");
1976            }
1977            
1978            listener.warningOccurred(this, imageIndex, warning);
1979        }
1980    }
1981
1982    // State management
1983

1984    /**
1985     * Restores the <code>ImageWriter</code> to its initial state.
1986     *
1987     * <p> The default implementation calls
1988     * <code>setOutput(null)</code>, <code>setLocale(null)</code>,
1989     * <code>removeAllIIOWriteWarningListeners()</code>,
1990     * <code>removeAllIIOWriteProgressListeners()</code>, and
1991     * <code>clearAbortRequest</code>.
1992     */

1993    public void reset() {
1994        setOutput(null);
1995        setLocale(null);
1996        removeAllIIOWriteWarningListeners();
1997        removeAllIIOWriteProgressListeners();
1998        clearAbortRequest();
1999    }
2000
2001    /**
2002     * Allows any resources held by this object to be released. The
2003     * result of calling any other method (other than
2004     * <code>finalize</code>) subsequent to a call to this method
2005     * is undefined.
2006     *
2007     * <p>It is important for applications to call this method when they
2008     * know they will no longer be using this <code>ImageWriter</code>.
2009     * Otherwise, the writer may continue to hold on to resources
2010     * indefinitely.
2011     *
2012     * <p>The default implementation of this method in the superclass does
2013     * nothing. Subclass implementations should ensure that all resources,
2014     * especially native resources, are released.
2015     */

2016    public void dispose() {
2017    }
2018}
2019
Popular Tags