1/*
2 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.imageio;
27
28import java.awt.Dimension;
29import java.awt.Rectangle;
30import java.awt.image.BufferedImage;
31import java.awt.image.RenderedImage;
32import java.awt.image.Raster;
33import java.io.IOException;
34import java.util.ArrayList;
35import java.util.List;
36import java.util.Locale;
37import java.util.MissingResourceException;
38import java.util.ResourceBundle;
39import javax.imageio.event.IIOWriteWarningListener;
40import javax.imageio.event.IIOWriteProgressListener;
41import javax.imageio.metadata.IIOMetadata;
42import javax.imageio.stream.ImageOutputStream;
43import javax.imageio.spi.ImageWriterSpi;
44
45/**
46 * An abstract superclass for encoding and writing images.  This class
47 * must be subclassed by classes that write out images in the context
48 * of the Java Image I/O framework.
49 *
50 * <p> {@code ImageWriter} objects are normally instantiated by
51 * the service provider class for the specific format.  Service
52 * provider classes are registered with the {@code IIORegistry},
53 * which uses them for format recognition and presentation of
54 * available format readers and writers.
55 *
56 * @see ImageReader
57 * @see ImageWriteParam
58 * @see javax.imageio.spi.IIORegistry
59 * @see javax.imageio.spi.ImageWriterSpi
60 *
61 */
62public abstract class ImageWriter implements ImageTranscoder {
63
64    /**
65     * The {@code ImageWriterSpi} that instantiated this object,
66     * or {@code null} if its identity is not known or none
67     * exists.  By default it is initialized to {@code null}.
68     */
69    protected ImageWriterSpi originatingProvider = null;
70
71    /**
72     * The {@code ImageOutputStream} or other {@code Object}
73     * set by {@code setOutput} and retrieved by
74     * {@code getOutput}.  By default it is initialized to
75     * {@code null}.
76     */
77    protected Object output = null;
78
79    /**
80     * An array of {@code Locale}s that may be used to localize
81     * warning messages and compression setting values, or
82     * {@code null} if localization is not supported.  By default
83     * it is initialized to {@code null}.
84     */
85    protected Locale[] availableLocales = null;
86
87    /**
88     * The current {@code Locale} to be used for localization, or
89     * {@code null} if none has been set.  By default it is
90     * initialized to {@code null}.
91     */
92    protected Locale locale = null;
93
94    /**
95     * A {@code List} of currently registered
96     * {@code IIOWriteWarningListener}s, initialized by default to
97     * {@code null}, which is synonymous with an empty
98     * {@code List}.
99     */
100    protected List<IIOWriteWarningListener> warningListeners = null;
101
102    /**
103     * A {@code List} of {@code Locale}s, one for each
104     * element of {@code warningListeners}, initialized by default
105     * {@code null}, which is synonymous with an empty
106     * {@code List}.
107     */
108    protected List<Locale> warningLocales = null;
109
110    /**
111     * A {@code List} of currently registered
112     * {@code IIOWriteProgressListener}s, initialized by default
113     * {@code null}, which is synonymous with an empty
114     * {@code List}.
115     */
116    protected List<IIOWriteProgressListener> progressListeners = null;
117
118    /**
119     * If {@code true}, the current write operation should be
120     * aborted.
121     */
122    private boolean abortFlag = false;
123
124    /**
125     * Constructs an {@code ImageWriter} and sets its
126     * {@code originatingProvider} instance variable to the
127     * supplied value.
128     *
129     * <p> Subclasses that make use of extensions should provide a
130     * constructor with signature {@code (ImageWriterSpi, Object)}
131     * in order to retrieve the extension object.  If
132     * the extension object is unsuitable, an
133     * {@code IllegalArgumentException} should be thrown.
134     *
135     * @param originatingProvider the {@code ImageWriterSpi} that
136     * is constructing this object, or {@code null}.
137     */
138    protected ImageWriter(ImageWriterSpi originatingProvider) {
139        this.originatingProvider = originatingProvider;
140    }
141
142    /**
143     * Returns the {@code ImageWriterSpi} object that created
144     * this {@code ImageWriter}, or {@code null} if this
145     * object was not created through the {@code IIORegistry}.
146     *
147     * <p> The default implementation returns the value of the
148     * {@code originatingProvider} instance variable.
149     *
150     * @return an {@code ImageWriterSpi}, or {@code null}.
151     *
152     * @see ImageWriterSpi
153     */
154    public ImageWriterSpi getOriginatingProvider() {
155        return originatingProvider;
156    }
157
158    /**
159     * Sets the destination to the given
160     * {@code ImageOutputStream} or other {@code Object}.
161     * The destination is assumed to be ready to accept data, and will
162     * not be closed at the end of each write. This allows distributed
163     * imaging applications to transmit a series of images over a
164     * single network connection.  If {@code output} is
165     * {@code null}, any currently set output will be removed.
166     *
167     * <p> If {@code output} is an
168     * {@code ImageOutputStream}, calls to the
169     * {@code write}, {@code writeToSequence}, and
170     * {@code prepareWriteEmpty}/{@code endWriteEmpty}
171     * methods will preserve the existing contents of the stream.
172     * Other write methods, such as {@code writeInsert},
173     * {@code replaceStreamMetadata},
174     * {@code replaceImageMetadata}, {@code replacePixels},
175     * {@code prepareInsertEmpty}/{@code endInsertEmpty},
176     * and {@code endWriteSequence}, require the full contents
177     * of the stream to be readable and writable, and may alter any
178     * portion of the stream.
179     *
180     * <p> Use of a general {@code Object} other than an
181     * {@code ImageOutputStream} is intended for writers that
182     * interact directly with an output device or imaging protocol.
183     * The set of legal classes is advertised by the writer's service
184     * provider's {@code getOutputTypes} method; most writers
185     * will return a single-element array containing only
186     * {@code ImageOutputStream.class} to indicate that they
187     * accept only an {@code ImageOutputStream}.
188     *
189     * <p> The default implementation sets the {@code output}
190     * instance variable to the value of {@code output} after
191     * checking {@code output} against the set of classes
192     * advertised by the originating provider, if there is one.
193     *
194     * @param output the {@code ImageOutputStream} or other
195     * {@code Object} to use for future writing.
196     *
197     * @exception IllegalArgumentException if {@code output} is
198     * not an instance of one of the classes returned by the
199     * originating service provider's {@code getOutputTypes}
200     * method.
201     *
202     * @see #getOutput
203     */
204    public void setOutput(Object output) {
205        if (output != null) {
206            ImageWriterSpi provider = getOriginatingProvider();
207            if (provider != null) {
208                Class<?>[] classes = provider.getOutputTypes();
209                boolean found = false;
210                for (int i = 0; i < classes.length; i++) {
211                    if (classes[i].isInstance(output)) {
212                        found = true;
213                        break;
214                    }
215                }
216                if (!found) {
217                    throw new IllegalArgumentException("Illegal output type!");
218                }
219            }
220        }
221
222        this.output = output;
223    }
224
225    /**
226     * Returns the {@code ImageOutputStream} or other
227     * {@code Object} set by the most recent call to the
228     * {@code setOutput} method.  If no destination has been
229     * set, {@code null} is returned.
230     *
231     * <p> The default implementation returns the value of the
232     * {@code output} instance variable.
233     *
234     * @return the {@code Object} that was specified using
235     * {@code setOutput}, or {@code null}.
236     *
237     * @see #setOutput
238     */
239    public Object getOutput() {
240        return output;
241    }
242
243    // Localization
244
245    /**
246     * Returns an array of {@code Locale}s that may be used to
247     * localize warning listeners and compression settings.  A return
248     * value of {@code null} indicates that localization is not
249     * supported.
250     *
251     * <p> The default implementation returns a clone of the
252     * {@code availableLocales} instance variable if it is
253     * non-{@code null}, or else returns {@code null}.
254     *
255     * @return an array of {@code Locale}s that may be used as
256     * arguments to {@code setLocale}, or {@code null}.
257     */
258    public Locale[] getAvailableLocales() {
259        return (availableLocales == null) ?
260            null : availableLocales.clone();
261    }
262
263    /**
264     * Sets the current {@code Locale} of this
265     * {@code ImageWriter} to the given value.  A value of
266     * {@code null} removes any previous setting, and indicates
267     * that the writer should localize as it sees fit.
268     *
269     * <p> The default implementation checks {@code locale}
270     * against the values returned by
271     * {@code getAvailableLocales}, and sets the
272     * {@code locale} instance variable if it is found.  If
273     * {@code locale} is {@code null}, the instance variable
274     * is set to {@code null} without any checking.
275     *
276     * @param locale the desired {@code Locale}, or
277     * {@code null}.
278     *
279     * @exception IllegalArgumentException if {@code locale} is
280     * non-{@code null} but is not one of the values returned by
281     * {@code getAvailableLocales}.
282     *
283     * @see #getLocale
284     */
285    public void setLocale(Locale locale) {
286        if (locale != null) {
287            Locale[] locales = getAvailableLocales();
288            boolean found = false;
289            if (locales != null) {
290                for (int i = 0; i < locales.length; i++) {
291                    if (locale.equals(locales[i])) {
292                        found = true;
293                        break;
294                    }
295                }
296            }
297            if (!found) {
298                throw new IllegalArgumentException("Invalid locale!");
299            }
300        }
301        this.locale = locale;
302    }
303
304    /**
305     * Returns the currently set {@code Locale}, or
306     * {@code null} if none has been set.
307     *
308     * <p> The default implementation returns the value of the
309     * {@code locale} instance variable.
310     *
311     * @return the current {@code Locale}, or {@code null}.
312     *
313     * @see #setLocale
314     */
315    public Locale getLocale() {
316        return locale;
317    }
318
319    // Write params
320
321    /**
322     * Returns a new {@code ImageWriteParam} object of the
323     * appropriate type for this file format containing default
324     * values, that is, those values that would be used
325     * if no {@code ImageWriteParam} object were specified.  This
326     * is useful as a starting point for tweaking just a few parameters
327     * and otherwise leaving the default settings alone.
328     *
329     * <p> The default implementation constructs and returns a new
330     * {@code ImageWriteParam} object that does not allow tiling,
331     * progressive encoding, or compression, and that will be
332     * localized for the current {@code Locale} (<i>i.e.</i>,
333     * what you would get by calling
334     * {@code new ImageWriteParam(getLocale())}.
335     *
336     * <p> Individual plug-ins may return an instance of
337     * {@code ImageWriteParam} with additional optional features
338     * enabled, or they may return an instance of a plug-in specific
339     * subclass of {@code ImageWriteParam}.
340     *
341     * @return a new {@code ImageWriteParam} object containing
342     * default values.
343     */
344    public ImageWriteParam getDefaultWriteParam() {
345        return new ImageWriteParam(getLocale());
346    }
347
348    // Metadata
349
350    /**
351     * Returns an {@code IIOMetadata} object containing default
352     * values for encoding a stream of images.  The contents of the
353     * object may be manipulated using either the XML tree structure
354     * returned by the {@code IIOMetadata.getAsTree} method, an
355     * {@code IIOMetadataController} object, or via plug-in
356     * specific interfaces, and the resulting data supplied to one of
357     * the {@code write} methods that take a stream metadata
358     * parameter.
359     *
360     * <p> An optional {@code ImageWriteParam} may be supplied
361     * for cases where it may affect the structure of the stream
362     * metadata.
363     *
364     * <p> If the supplied {@code ImageWriteParam} contains
365     * optional setting values not supported by this writer (<i>e.g.</i>
366     * progressive encoding or any format-specific settings), they
367     * will be ignored.
368     *
369     * <p> Writers that do not make use of stream metadata
370     * (<i>e.g.</i>, writers for single-image formats) should return
371     * {@code null}.
372     *
373     * @param param an {@code ImageWriteParam} that will be used to
374     * encode the image, or {@code null}.
375     *
376     * @return an {@code IIOMetadata} object.
377     */
378    public abstract IIOMetadata
379        getDefaultStreamMetadata(ImageWriteParam param);
380
381    /**
382     * Returns an {@code IIOMetadata} object containing default
383     * values for encoding an image of the given type.  The contents
384     * of the object may be manipulated using either the XML tree
385     * structure returned by the {@code IIOMetadata.getAsTree}
386     * method, an {@code IIOMetadataController} object, or via
387     * plug-in specific interfaces, and the resulting data supplied to
388     * one of the {@code write} methods that take a stream
389     * metadata parameter.
390     *
391     * <p> An optional {@code ImageWriteParam} may be supplied
392     * for cases where it may affect the structure of the image
393     * metadata.
394     *
395     * <p> If the supplied {@code ImageWriteParam} contains
396     * optional setting values not supported by this writer (<i>e.g.</i>
397     * progressive encoding or any format-specific settings), they
398     * will be ignored.
399     *
400     * @param imageType an {@code ImageTypeSpecifier} indicating the
401     * format of the image to be written later.
402     * @param param an {@code ImageWriteParam} that will be used to
403     * encode the image, or {@code null}.
404     *
405     * @return an {@code IIOMetadata} object.
406     */
407    public abstract IIOMetadata
408        getDefaultImageMetadata(ImageTypeSpecifier imageType,
409                                ImageWriteParam param);
410
411    // comment inherited
412    public abstract IIOMetadata convertStreamMetadata(IIOMetadata inData,
413                                                      ImageWriteParam param);
414
415    // comment inherited
416    public abstract IIOMetadata
417        convertImageMetadata(IIOMetadata inData,
418                             ImageTypeSpecifier imageType,
419                             ImageWriteParam param);
420
421    // Thumbnails
422
423    /**
424     * Returns the number of thumbnails supported by the format being
425     * written, given the image type and any additional write
426     * parameters and metadata objects that will be used during
427     * encoding.  A return value of {@code -1} indicates that
428     * insufficient information is available.
429     *
430     * <p> An {@code ImageWriteParam} may optionally be supplied
431     * for cases where it may affect thumbnail handling.
432     *
433     * <p> If the supplied {@code ImageWriteParam} contains
434     * optional setting values not supported by this writer (<i>e.g.</i>
435     * progressive encoding or any format-specific settings), they
436     * will be ignored.
437     *
438     * <p> The default implementation returns 0.
439     *
440     * @param imageType an {@code ImageTypeSpecifier} indicating
441     * the type of image to be written, or {@code null}.
442     * @param param the {@code ImageWriteParam} that will be used for
443     * writing, or {@code null}.
444     * @param streamMetadata an {@code IIOMetadata} object that will
445     * be used for writing, or {@code null}.
446     * @param imageMetadata an {@code IIOMetadata} object that will
447     * be used for writing, or {@code null}.
448     *
449     * @return the number of thumbnails that may be written given the
450     * supplied parameters, or {@code -1} if insufficient
451     * information is available.
452     */
453    public int getNumThumbnailsSupported(ImageTypeSpecifier imageType,
454                                         ImageWriteParam param,
455                                         IIOMetadata streamMetadata,
456                                         IIOMetadata imageMetadata) {
457        return 0;
458    }
459
460    /**
461     * Returns an array of {@code Dimension}s indicating the
462     * legal size ranges for thumbnail images as they will be encoded
463     * in the output file or stream.  This information is merely
464     * advisory; the writer will resize any supplied thumbnails as
465     * necessary.
466     *
467     * <p> The information is returned as a set of pairs; the first
468     * element of a pair contains an (inclusive) minimum width and
469     * height, and the second element contains an (inclusive) maximum
470     * width and height.  Together, each pair defines a valid range of
471     * sizes.  To specify a fixed size, the same width and height will
472     * appear for both elements.  A return value of {@code null}
473     * indicates that the size is arbitrary or unknown.
474     *
475     * <p> An {@code ImageWriteParam} may optionally be supplied
476     * for cases where it may affect thumbnail handling.
477     *
478     * <p> If the supplied {@code ImageWriteParam} contains
479     * optional setting values not supported by this writer (<i>e.g.</i>
480     * progressive encoding or any format-specific settings), they
481     * will be ignored.
482     *
483     * <p> The default implementation returns {@code null}.
484     *
485     * @param imageType an {@code ImageTypeSpecifier} indicating the
486     * type of image to be written, or {@code null}.
487     * @param param the {@code ImageWriteParam} that will be used for
488     * writing, or {@code null}.
489     * @param streamMetadata an {@code IIOMetadata} object that will
490     * be used for writing, or {@code null}.
491     * @param imageMetadata an {@code IIOMetadata} object that will
492     * be used for writing, or {@code null}.
493     *
494     * @return an array of {@code Dimension}s with an even length
495     * of at least two, or {@code null}.
496     */
497    public Dimension[] getPreferredThumbnailSizes(ImageTypeSpecifier imageType,
498                                                  ImageWriteParam param,
499                                                  IIOMetadata streamMetadata,
500                                                  IIOMetadata imageMetadata) {
501        return null;
502    }
503
504    /**
505     * Returns {@code true} if the methods that take an
506     * {@code IIOImage} parameter are capable of dealing with a
507     * {@code Raster} (as opposed to {@code RenderedImage})
508     * source image.  If this method returns {@code false}, then
509     * those methods will throw an
510     * {@code UnsupportedOperationException} if supplied with an
511     * {@code IIOImage} containing a {@code Raster}.
512     *
513     * <p> The default implementation returns {@code false}.
514     *
515     * @return {@code true} if {@code Raster} sources are
516     * supported.
517     */
518    public boolean canWriteRasters() {
519        return false;
520    }
521
522    /**
523     * Appends a complete image stream containing a single image and
524     * associated stream and image metadata and thumbnails to the
525     * output.  Any necessary header information is included.  If the
526     * output is an {@code ImageOutputStream}, its existing
527     * contents prior to the current seek position are not affected,
528     * and need not be readable or writable.
529     *
530     * <p> The output must have been set beforehand using the
531     * {@code setOutput} method.
532     *
533     * <p> Stream metadata may optionally be supplied; if it is
534     * {@code null}, default stream metadata will be used.
535     *
536     * <p> If {@code canWriteRasters} returns {@code true},
537     * the {@code IIOImage} may contain a {@code Raster}
538     * source.  Otherwise, it must contain a
539     * {@code RenderedImage} source.
540     *
541     * <p> The supplied thumbnails will be resized if needed, and any
542     * thumbnails in excess of the supported number will be ignored.
543     * If the format requires additional thumbnails that are not
544     * provided, the writer should generate them internally.
545     *
546     * <p>  An {@code ImageWriteParam} may
547     * optionally be supplied to control the writing process.  If
548     * {@code param} is {@code null}, a default write param
549     * will be used.
550     *
551     * <p> If the supplied {@code ImageWriteParam} contains
552     * optional setting values not supported by this writer (<i>e.g.</i>
553     * progressive encoding or any format-specific settings), they
554     * will be ignored.
555     *
556     * @param streamMetadata an {@code IIOMetadata} object representing
557     * stream metadata, or {@code null} to use default values.
558     * @param image an {@code IIOImage} object containing an
559     * image, thumbnails, and metadata to be written.
560     * @param param an {@code ImageWriteParam}, or
561     * {@code null} to use a default
562     * {@code ImageWriteParam}.
563     *
564     * @exception IllegalStateException if the output has not
565     * been set.
566     * @exception UnsupportedOperationException if {@code image}
567     * contains a {@code Raster} and {@code canWriteRasters}
568     * returns {@code false}.
569     * @exception IllegalArgumentException if {@code image} is
570     * {@code null}.
571     * @exception IOException if an error occurs during writing.
572     */
573    public abstract void write(IIOMetadata streamMetadata,
574                               IIOImage image,
575                               ImageWriteParam param) throws IOException;
576
577    /**
578     * Appends a complete image stream containing a single image with
579     * default metadata and thumbnails to the output.  This method is
580     * a shorthand for {@code write(null, image, null)}.
581     *
582     * @param image an {@code IIOImage} object containing an
583     * image, thumbnails, and metadata to be written.
584     *
585     * @exception IllegalStateException if the output has not
586     * been set.
587     * @exception IllegalArgumentException if {@code image} is
588     * {@code null}.
589     * @exception UnsupportedOperationException if {@code image}
590     * contains a {@code Raster} and {@code canWriteRasters}
591     * returns {@code false}.
592     * @exception IOException if an error occurs during writing.
593     */
594    public void write(IIOImage image) throws IOException {
595        write(null, image, null);
596    }
597
598    /**
599     * Appends a complete image stream consisting of a single image
600     * with default metadata and thumbnails to the output.  This
601     * method is a shorthand for
602     * {@code write(null, new IIOImage(image, null, null), null)}.
603     *
604     * @param image a {@code RenderedImage} to be written.
605     *
606     * @exception IllegalStateException if the output has not
607     * been set.
608     * @exception IllegalArgumentException if {@code image} is
609     * {@code null}.
610     * @exception IOException if an error occurs during writing.
611     */
612    public void write(RenderedImage image) throws IOException {
613        write(null, new IIOImage(image, null, null), null);
614    }
615
616    // Check that the output has been set, then throw an
617    // UnsupportedOperationException.
618    private void unsupported() {
619        if (getOutput() == null) {
620            throw new IllegalStateException("getOutput() == null!");
621        }
622        throw new UnsupportedOperationException("Unsupported write variant!");
623    }
624
625    // Sequence writes
626
627    /**
628     * Returns {@code true} if the writer is able to append an
629     * image to an image stream that already contains header
630     * information and possibly prior images.
631     *
632     * <p> If {@code canWriteSequence} returns {@code false},
633     * {@code writeToSequence} and {@code endWriteSequence}
634     * will throw an {@code UnsupportedOperationException}.
635     *
636     * <p> The default implementation returns {@code false}.
637     *
638     * @return {@code true} if images may be appended sequentially.
639     */
640    public boolean canWriteSequence() {
641        return false;
642    }
643
644    /**
645     * Prepares a stream to accept a series of subsequent
646     * {@code writeToSequence} calls, using the provided stream
647     * metadata object.  The metadata will be written to the stream if
648     * it should precede the image data.  If the argument is {@code null},
649     * default stream metadata is used.
650     *
651     * <p> If the output is an {@code ImageOutputStream}, the existing
652     * contents of the output prior to the current seek position are
653     * flushed, and need not be readable or writable.  If the format
654     * requires that {@code endWriteSequence} be able to rewind to
655     * patch up the header information, such as for a sequence of images
656     * in a single TIFF file, then the metadata written by this method
657     * must remain in a writable portion of the stream.  Other formats
658     * may flush the stream after this method and after each image.
659     *
660     * <p> If {@code canWriteSequence} returns {@code false},
661     * this method will throw an
662     * {@code UnsupportedOperationException}.
663     *
664     * <p> The output must have been set beforehand using either
665     * the {@code setOutput} method.
666     *
667     * <p> The default implementation throws an
668     * {@code IllegalStateException} if the output is
669     * {@code null}, and otherwise throws an
670     * {@code UnsupportedOperationException}.
671     *
672     * @param streamMetadata A stream metadata object, or {@code null}.
673     *
674     * @exception IllegalStateException if the output has not
675     * been set.
676     * @exception UnsupportedOperationException if
677     * {@code canWriteSequence} returns {@code false}.
678     * @exception IOException if an error occurs writing the stream
679     * metadata.
680     */
681    public void prepareWriteSequence(IIOMetadata streamMetadata)
682        throws IOException {
683        unsupported();
684    }
685
686    /**
687     * Appends a single image and possibly associated metadata and
688     * thumbnails, to the output.  If the output is an
689     * {@code ImageOutputStream}, the existing contents of the
690     * output prior to the current seek position may be flushed, and
691     * need not be readable or writable, unless the plug-in needs to
692     * be able to patch up the header information when
693     * {@code endWriteSequence} is called (<i>e.g.</i> TIFF).
694     *
695     * <p> If {@code canWriteSequence} returns {@code false},
696     * this method will throw an
697     * {@code UnsupportedOperationException}.
698     *
699     * <p> The output must have been set beforehand using
700     * the {@code setOutput} method.
701     *
702     * <p> {@code prepareWriteSequence} must have been called
703     * beforehand, or an {@code IllegalStateException} is thrown.
704     *
705     * <p> If {@code canWriteRasters} returns {@code true},
706     * the {@code IIOImage} may contain a {@code Raster}
707     * source.  Otherwise, it must contain a
708     * {@code RenderedImage} source.
709     *
710     * <p> The supplied thumbnails will be resized if needed, and any
711     * thumbnails in excess of the supported number will be ignored.
712     * If the format requires additional thumbnails that are not
713     * provided, the writer will generate them internally.
714     *
715     * <p> An {@code ImageWriteParam} may optionally be supplied
716     * to control the writing process.  If {@code param} is
717     * {@code null}, a default write param will be used.
718     *
719     * <p> If the supplied {@code ImageWriteParam} contains
720     * optional setting values not supported by this writer (<i>e.g.</i>
721     * progressive encoding or any format-specific settings), they
722     * will be ignored.
723     *
724     * <p> The default implementation throws an
725     * {@code IllegalStateException} if the output is
726     * {@code null}, and otherwise throws an
727     * {@code UnsupportedOperationException}.
728     *
729     * @param image an {@code IIOImage} object containing an
730     * image, thumbnails, and metadata to be written.
731     * @param param an {@code ImageWriteParam}, or
732     * {@code null} to use a default
733     * {@code ImageWriteParam}.
734     *
735     * @exception IllegalStateException if the output has not
736     * been set, or {@code prepareWriteSequence} has not been called.
737     * @exception UnsupportedOperationException if
738     * {@code canWriteSequence} returns {@code false}.
739     * @exception IllegalArgumentException if {@code image} is
740     * {@code null}.
741     * @exception UnsupportedOperationException if {@code image}
742     * contains a {@code Raster} and {@code canWriteRasters}
743     * returns {@code false}.
744     * @exception IOException if an error occurs during writing.
745     */
746    public void writeToSequence(IIOImage image, ImageWriteParam param)
747        throws IOException {
748        unsupported();
749    }
750
751    /**
752     * Completes the writing of a sequence of images begun with
753     * {@code prepareWriteSequence}.  Any stream metadata that
754     * should come at the end of the sequence of images is written out,
755     * and any header information at the beginning of the sequence is
756     * patched up if necessary.  If the output is an
757     * {@code ImageOutputStream}, data through the stream metadata
758     * at the end of the sequence are flushed and need not be readable
759     * or writable.
760     *
761     * <p> If {@code canWriteSequence} returns {@code false},
762     * this method will throw an
763     * {@code UnsupportedOperationException}.
764     *
765     * <p> The default implementation throws an
766     * {@code IllegalStateException} if the output is
767     * {@code null}, and otherwise throws an
768     * {@code UnsupportedOperationException}.
769     *
770     * @exception IllegalStateException if the output has not
771     * been set, or {@code prepareWriteSequence} has not been called.
772     * @exception UnsupportedOperationException if
773     * {@code canWriteSequence} returns {@code false}.
774     * @exception IOException if an error occurs during writing.
775     */
776    public void endWriteSequence() throws IOException {
777        unsupported();
778    }
779
780    // Metadata replacement
781
782    /**
783     * Returns {@code true} if it is possible to replace the
784     * stream metadata already present in the output.
785     *
786     * <p> The default implementation throws an
787     * {@code IllegalStateException} if the output is
788     * {@code null}, and otherwise returns {@code false}.
789     *
790     * @return {@code true} if replacement of stream metadata is
791     * allowed.
792     *
793     * @exception IllegalStateException if the output has not
794     * been set.
795     * @exception IOException if an I/O error occurs during the query.
796     */
797    public boolean canReplaceStreamMetadata() throws IOException {
798        if (getOutput() == null) {
799            throw new IllegalStateException("getOutput() == null!");
800        }
801        return false;
802    }
803
804    /**
805     * Replaces the stream metadata in the output with new
806     * information.  If the output is an
807     * {@code ImageOutputStream}, the prior contents of the
808     * stream are examined and possibly edited to make room for the
809     * new data.  All of the prior contents of the output must be
810     * available for reading and writing.
811     *
812     * <p> If {@code canReplaceStreamMetadata} returns
813     * {@code false}, an
814     * {@code UnsupportedOperationException} will be thrown.
815     *
816     * <p> The default implementation throws an
817     * {@code IllegalStateException} if the output is
818     * {@code null}, and otherwise throws an
819     * {@code UnsupportedOperationException}.
820     *
821     * @param streamMetadata an {@code IIOMetadata} object representing
822     * stream metadata, or {@code null} to use default values.
823     *
824     * @exception IllegalStateException if the output has not
825     * been set.
826     * @exception UnsupportedOperationException if the
827     * {@code canReplaceStreamMetadata} returns
828     * {@code false}.  modes do not include
829     * @exception IOException if an error occurs during writing.
830     */
831    public void replaceStreamMetadata(IIOMetadata streamMetadata)
832        throws IOException {
833        unsupported();
834    }
835
836    /**
837     * Returns {@code true} if it is possible to replace the
838     * image metadata associated with an existing image with index
839     * {@code imageIndex}.  If this method returns
840     * {@code false}, a call to
841     * {@code replaceImageMetadata(imageIndex)} will throw an
842     * {@code UnsupportedOperationException}.
843     *
844     * <p> A writer that does not support any image metadata
845     * replacement may return {@code false} without performing
846     * bounds checking on the index.
847     *
848     * <p> The default implementation throws an
849     * {@code IllegalStateException} if the output is
850     * {@code null}, and otherwise returns {@code false}
851     * without checking the value of {@code imageIndex}.
852     *
853     * @param imageIndex the index of the image whose metadata is to
854     * be replaced.
855     *
856     * @return {@code true} if the image metadata of the given
857     * image can be replaced.
858     *
859     * @exception IllegalStateException if the output has not
860     * been set.
861     * @exception IndexOutOfBoundsException if the writer supports
862     * image metadata replacement in general, but
863     * {@code imageIndex} is less than 0 or greater than the
864     * largest available index.
865     * @exception IOException if an I/O error occurs during the query.
866     */
867    public boolean canReplaceImageMetadata(int imageIndex)
868        throws IOException {
869        if (getOutput() == null) {
870            throw new IllegalStateException("getOutput() == null!");
871        }
872        return false;
873    }
874
875    /**
876     * Replaces the image metadata associated with an existing image.
877     *
878     * <p> If {@code canReplaceImageMetadata(imageIndex)} returns
879     * {@code false}, an
880     * {@code UnsupportedOperationException} will be thrown.
881     *
882     * <p> The default implementation throws an
883     * {@code IllegalStateException} if the output is
884     * {@code null}, and otherwise throws an
885     * {@code UnsupportedOperationException}.
886     *
887     * @param imageIndex the index of the image whose metadata is to
888     * be replaced.
889     * @param imageMetadata an {@code IIOMetadata} object
890     * representing image metadata, or {@code null}.
891     *
892     * @exception IllegalStateException if the output has not been
893     * set.
894     * @exception UnsupportedOperationException if
895     * {@code canReplaceImageMetadata} returns
896     * {@code false}.
897     * @exception IndexOutOfBoundsException if {@code imageIndex}
898     * is less than 0 or greater than the largest available index.
899     * @exception IOException if an error occurs during writing.
900     */
901    public void replaceImageMetadata(int imageIndex,
902                                     IIOMetadata imageMetadata)
903        throws IOException {
904        unsupported();
905    }
906
907    // Image insertion
908
909    /**
910     * Returns {@code true} if the writer supports the insertion
911     * of a new image at the given index.  Existing images with
912     * indices greater than or equal to the insertion index will have
913     * their indices increased by 1.  A value for
914     * {@code imageIndex} of {@code -1} may be used to
915     * signify an index one larger than the current largest index.
916     *
917     * <p> A writer that does not support any image insertion may
918     * return {@code false} without performing bounds checking on
919     * the index.
920     *
921     * <p> The default implementation throws an
922     * {@code IllegalStateException} if the output is
923     * {@code null}, and otherwise returns {@code false}
924     * without checking the value of {@code imageIndex}.
925     *
926     * @param imageIndex the index at which the image is to be
927     * inserted.
928     *
929     * @return {@code true} if an image may be inserted at the
930     * given index.
931     *
932     * @exception IllegalStateException if the output has not
933     * been set.
934     * @exception IndexOutOfBoundsException if the writer supports
935     * image insertion in general, but {@code imageIndex} is less
936     * than -1 or greater than the largest available index.
937     * @exception IOException if an I/O error occurs during the query.
938     */
939    public boolean canInsertImage(int imageIndex) throws IOException {
940        if (getOutput() == null) {
941            throw new IllegalStateException("getOutput() == null!");
942        }
943        return false;
944    }
945
946    /**
947     * Inserts a new image into an existing image stream.  Existing
948     * images with an index greater than {@code imageIndex} are
949     * preserved, and their indices are each increased by 1.  A value
950     * for {@code imageIndex} of -1 may be used to signify an
951     * index one larger than the previous largest index; that is, it
952     * will cause the image to be logically appended to the end of the
953     * sequence.  If the output is an {@code ImageOutputStream},
954     * the entirety of the stream must be both readable and writeable.
955     *
956     * <p> If {@code canInsertImage(imageIndex)} returns
957     * {@code false}, an
958     * {@code UnsupportedOperationException} will be thrown.
959     *
960     * <p> An {@code ImageWriteParam} may optionally be supplied
961     * to control the writing process.  If {@code param} is
962     * {@code null}, a default write param will be used.
963     *
964     * <p> If the supplied {@code ImageWriteParam} contains
965     * optional setting values not supported by this writer (<i>e.g.</i>
966     * progressive encoding or any format-specific settings), they
967     * will be ignored.
968     *
969     * <p> The default implementation throws an
970     * {@code IllegalStateException} if the output is
971     * {@code null}, and otherwise throws an
972     * {@code UnsupportedOperationException}.
973     *
974     * @param imageIndex the index at which to write the image.
975     * @param image an {@code IIOImage} object containing an
976     * image, thumbnails, and metadata to be written.
977     * @param param an {@code ImageWriteParam}, or
978     * {@code null} to use a default
979     * {@code ImageWriteParam}.
980     *
981     * @exception IllegalStateException if the output has not
982     * been set.
983     * @exception UnsupportedOperationException if
984     * {@code canInsertImage(imageIndex)} returns {@code false}.
985     * @exception IllegalArgumentException if {@code image} is
986     * {@code null}.
987     * @exception IndexOutOfBoundsException if {@code imageIndex}
988     * is less than -1 or greater than the largest available index.
989     * @exception UnsupportedOperationException if {@code image}
990     * contains a {@code Raster} and {@code canWriteRasters}
991     * returns {@code false}.
992     * @exception IOException if an error occurs during writing.
993     */
994    public void writeInsert(int imageIndex,
995                            IIOImage image,
996                            ImageWriteParam param) throws IOException {
997        unsupported();
998    }
999
1000    // Image removal
1001
1002    /**
1003     * Returns {@code true} if the writer supports the removal
1004     * of an existing image at the given index.  Existing images with
1005     * indices greater than the insertion index will have
1006     * their indices decreased by 1.
1007     *
1008     * <p> A writer that does not support any image removal may
1009     * return {@code false} without performing bounds checking on
1010     * the index.
1011     *
1012     * <p> The default implementation throws an
1013     * {@code IllegalStateException} if the output is
1014     * {@code null}, and otherwise returns {@code false}
1015     * without checking the value of {@code imageIndex}.
1016     *
1017     * @param imageIndex the index of the image to be removed.
1018     *
1019     * @return {@code true} if it is possible to remove the given
1020     * image.
1021     *
1022     * @exception IllegalStateException if the output has not
1023     * been set.
1024     * @exception IndexOutOfBoundsException if the writer supports
1025     * image removal in general, but {@code imageIndex} is less
1026     * than 0 or greater than the largest available index.
1027     * @exception IOException if an I/O error occurs during the
1028     * query.
1029     */
1030    public boolean canRemoveImage(int imageIndex) throws IOException {
1031        if (getOutput() == null) {
1032            throw new IllegalStateException("getOutput() == null!");
1033        }
1034        return false;
1035    }
1036
1037    /**
1038     * Removes an image from the stream.
1039     *
1040     * <p> If {@code canRemoveImage(imageIndex)} returns false,
1041     * an {@code UnsupportedOperationException} will be thrown.
1042     *
1043     * <p> The removal may or may not cause a reduction in the actual
1044     * file size.
1045     *
1046     * <p> The default implementation throws an
1047     * {@code IllegalStateException} if the output is
1048     * {@code null}, and otherwise throws an
1049     * {@code UnsupportedOperationException}.
1050     *
1051     * @param imageIndex the index of the image to be removed.
1052     *
1053     * @exception IllegalStateException if the output has not
1054     * been set.
1055     * @exception UnsupportedOperationException if
1056     * {@code canRemoveImage(imageIndex)} returns {@code false}.
1057     * @exception IndexOutOfBoundsException if {@code imageIndex}
1058     * is less than 0 or greater than the largest available index.
1059     * @exception IOException if an I/O error occurs during the
1060     * removal.
1061     */
1062    public void removeImage(int imageIndex) throws IOException {
1063        unsupported();
1064    }
1065
1066    // Empty images
1067
1068    /**
1069     * Returns {@code true} if the writer supports the writing of
1070     * a complete image stream consisting of a single image with
1071     * undefined pixel values and associated metadata and thumbnails
1072     * to the output.  The pixel values may be defined by future
1073     * calls to the {@code replacePixels} methods.  If the output
1074     * is an {@code ImageOutputStream}, its existing contents
1075     * prior to the current seek position are not affected, and need
1076     * not be readable or writable.
1077     *
1078     * <p> The default implementation throws an
1079     * {@code IllegalStateException} if the output is
1080     * {@code null}, and otherwise returns {@code false}.
1081     *
1082     * @return {@code true} if the writing of complete image
1083     * stream with contents to be defined later is supported.
1084     *
1085     * @exception IllegalStateException if the output has not been
1086     * set.
1087     * @exception IOException if an I/O error occurs during the
1088     * query.
1089     */
1090    public boolean canWriteEmpty() throws IOException {
1091        if (getOutput() == null) {
1092            throw new IllegalStateException("getOutput() == null!");
1093        }
1094        return false;
1095    }
1096
1097    /**
1098     * Begins the writing of a complete image stream, consisting of a
1099     * single image with undefined pixel values and associated
1100     * metadata and thumbnails, to the output.  The pixel values will
1101     * be defined by future calls to the {@code replacePixels}
1102     * methods.  If the output is an {@code ImageOutputStream},
1103     * its existing contents prior to the current seek position are
1104     * not affected, and need not be readable or writable.
1105     *
1106     * <p> The writing is not complete until a call to
1107     * {@code endWriteEmpty} occurs.  Calls to
1108     * {@code prepareReplacePixels}, {@code replacePixels},
1109     * and {@code endReplacePixels} may occur between calls to
1110     * {@code prepareWriteEmpty} and {@code endWriteEmpty}.
1111     * However, calls to {@code prepareWriteEmpty} cannot be
1112     * nested, and calls to {@code prepareWriteEmpty} and
1113     * {@code prepareInsertEmpty} may not be interspersed.
1114     *
1115     * <p> If {@code canWriteEmpty} returns {@code false},
1116     * an {@code UnsupportedOperationException} will be thrown.
1117     *
1118     * <p> An {@code ImageWriteParam} may optionally be supplied
1119     * to control the writing process.  If {@code param} is
1120     * {@code null}, a default write param will be used.
1121     *
1122     * <p> If the supplied {@code ImageWriteParam} contains
1123     * optional setting values not supported by this writer (<i>e.g.</i>
1124     * progressive encoding or any format-specific settings), they
1125     * will be ignored.
1126     *
1127     * <p> The default implementation throws an
1128     * {@code IllegalStateException} if the output is
1129     * {@code null}, and otherwise throws an
1130     * {@code UnsupportedOperationException}.
1131     *
1132     * @param streamMetadata an {@code IIOMetadata} object representing
1133     * stream metadata, or {@code null} to use default values.
1134     * @param imageType an {@code ImageTypeSpecifier} describing
1135     * the layout of the image.
1136     * @param width the width of the image.
1137     * @param height the height of the image.
1138     * @param imageMetadata an {@code IIOMetadata} object
1139     * representing image metadata, or {@code null}.
1140     * @param thumbnails a {@code List} of
1141     * {@code BufferedImage} thumbnails for this image, or
1142     * {@code null}.
1143     * @param param an {@code ImageWriteParam}, or
1144     * {@code null} to use a default
1145     * {@code ImageWriteParam}.
1146     *
1147     * @exception IllegalStateException if the output has not
1148     * been set.
1149     * @exception UnsupportedOperationException if
1150     * {@code canWriteEmpty} returns {@code false}.
1151     * @exception IllegalStateException if a previous call to
1152     * {@code prepareWriteEmpty} has been made without a
1153     * corresponding call to {@code endWriteEmpty}.
1154     * @exception IllegalStateException if a previous call to
1155     * {@code prepareInsertEmpty} has been made without a
1156     * corresponding call to {@code endInsertEmpty}.
1157     * @exception IllegalArgumentException if {@code imageType}
1158     * is {@code null} or {@code thumbnails} contains
1159     * {@code null} references or objects other than
1160     * {@code BufferedImage}s.
1161     * @exception IllegalArgumentException if width or height are less
1162     * than 1.
1163     * @exception IOException if an I/O error occurs during writing.
1164     */
1165    public void prepareWriteEmpty(IIOMetadata streamMetadata,
1166                                  ImageTypeSpecifier imageType,
1167                                  int width, int height,
1168                                  IIOMetadata imageMetadata,
1169                                  List<? extends BufferedImage> thumbnails,
1170                                  ImageWriteParam param) throws IOException {
1171        unsupported();
1172    }
1173
1174    /**
1175     * Completes the writing of a new image that was begun with a
1176     * prior call to {@code prepareWriteEmpty}.
1177     *
1178     * <p> If {@code canWriteEmpty()} returns {@code false},
1179     * an {@code UnsupportedOperationException} will be thrown.
1180     *
1181     * <p> The default implementation throws an
1182     * {@code IllegalStateException} if the output is
1183     * {@code null}, and otherwise throws an
1184     * {@code UnsupportedOperationException}.
1185     *
1186     * @exception IllegalStateException if the output has not
1187     * been set.
1188     * @exception UnsupportedOperationException if
1189     * {@code canWriteEmpty(imageIndex)} returns
1190     * {@code false}.
1191     * @exception IllegalStateException if a previous call to
1192     * {@code prepareWriteEmpty} without a corresponding call to
1193     * {@code endWriteEmpty} has not been made.
1194     * @exception IllegalStateException if a previous call to
1195     * {@code prepareInsertEmpty} without a corresponding call to
1196     * {@code endInsertEmpty} has been made.
1197     * @exception IllegalStateException if a call to
1198     * {@code prepareReiplacePixels} has been made without a
1199     * matching call to {@code endReplacePixels}.
1200     * @exception IOException if an I/O error occurs during writing.
1201     */
1202    public void endWriteEmpty() throws IOException {
1203        if (getOutput() == null) {
1204            throw new IllegalStateException("getOutput() == null!");
1205        }
1206        throw new IllegalStateException("No call to prepareWriteEmpty!");
1207    }
1208
1209    /**
1210     * Returns {@code true} if the writer supports the insertion
1211     * of a new, empty image at the given index.  The pixel values of
1212     * the image are undefined, and may be specified in pieces using
1213     * the {@code replacePixels} methods.  Existing images with
1214     * indices greater than or equal to the insertion index will have
1215     * their indices increased by 1.  A value for
1216     * {@code imageIndex} of {@code -1} may be used to
1217     * signify an index one larger than the current largest index.
1218     *
1219     * <p> A writer that does not support insertion of empty images
1220     * may return {@code false} without performing bounds
1221     * checking on the index.
1222     *
1223     * <p> The default implementation throws an
1224     * {@code IllegalStateException} if the output is
1225     * {@code null}, and otherwise returns {@code false}
1226     * without checking the value of {@code imageIndex}.
1227     *
1228     * @param imageIndex the index at which the image is to be
1229     * inserted.
1230     *
1231     * @return {@code true} if an empty image may be inserted at
1232     * the given index.
1233     *
1234     * @exception IllegalStateException if the output has not been
1235     * set.
1236     * @exception IndexOutOfBoundsException if the writer supports
1237     * empty image insertion in general, but {@code imageIndex}
1238     * is less than -1 or greater than the largest available index.
1239     * @exception IOException if an I/O error occurs during the
1240     * query.
1241     */
1242    public boolean canInsertEmpty(int imageIndex) throws IOException {
1243        if (getOutput() == null) {
1244            throw new IllegalStateException("getOutput() == null!");
1245        }
1246        return false;
1247    }
1248
1249    /**
1250     * Begins the insertion of a new image with undefined pixel values
1251     * into an existing image stream.  Existing images with an index
1252     * greater than {@code imageIndex} are preserved, and their
1253     * indices are each increased by 1.  A value for
1254     * {@code imageIndex} of -1 may be used to signify an index
1255     * one larger than the previous largest index; that is, it will
1256     * cause the image to be logically appended to the end of the
1257     * sequence.  If the output is an {@code ImageOutputStream},
1258     * the entirety of the stream must be both readable and writeable.
1259     *
1260     * <p> The image contents may be
1261     * supplied later using the {@code replacePixels} method.
1262     * The insertion is not complete until a call to
1263     * {@code endInsertEmpty} occurs.  Calls to
1264     * {@code prepareReplacePixels}, {@code replacePixels},
1265     * and {@code endReplacePixels} may occur between calls to
1266     * {@code prepareInsertEmpty} and
1267     * {@code endInsertEmpty}.  However, calls to
1268     * {@code prepareInsertEmpty} cannot be nested, and calls to
1269     * {@code prepareWriteEmpty} and
1270     * {@code prepareInsertEmpty} may not be interspersed.
1271     *
1272     * <p> If {@code canInsertEmpty(imageIndex)} returns
1273     * {@code false}, an
1274     * {@code UnsupportedOperationException} will be thrown.
1275     *
1276     * <p> An {@code ImageWriteParam} may optionally be supplied
1277     * to control the writing process.  If {@code param} is
1278     * {@code null}, a default write param will be used.
1279     *
1280     * <p> If the supplied {@code ImageWriteParam} contains
1281     * optional setting values not supported by this writer (<i>e.g.</i>
1282     * progressive encoding or any format-specific settings), they
1283     * will be ignored.
1284     *
1285     * <p> The default implementation throws an
1286     * {@code IllegalStateException} if the output is
1287     * {@code null}, and otherwise throws an
1288     * {@code UnsupportedOperationException}.
1289     *
1290     * @param imageIndex the index at which to write the image.
1291     * @param imageType an {@code ImageTypeSpecifier} describing
1292     * the layout of the image.
1293     * @param width the width of the image.
1294     * @param height the height of the image.
1295     * @param imageMetadata an {@code IIOMetadata} object
1296     * representing image metadata, or {@code null}.
1297     * @param thumbnails a {@code List} of
1298     * {@code BufferedImage} thumbnails for this image, or
1299     * {@code null}.
1300     * @param param an {@code ImageWriteParam}, or
1301     * {@code null} to use a default
1302     * {@code ImageWriteParam}.
1303     *
1304     * @exception IllegalStateException if the output has not
1305     * been set.
1306     * @exception UnsupportedOperationException if
1307     * {@code canInsertEmpty(imageIndex)} returns
1308     * {@code false}.
1309     * @exception IndexOutOfBoundsException if {@code imageIndex}
1310     * is less than -1 or greater than the largest available index.
1311     * @exception IllegalStateException if a previous call to
1312     * {@code prepareInsertEmpty} has been made without a
1313     * corresponding call to {@code endInsertEmpty}.
1314     * @exception IllegalStateException if a previous call to
1315     * {@code prepareWriteEmpty} has been made without a
1316     * corresponding call to {@code endWriteEmpty}.
1317     * @exception IllegalArgumentException if {@code imageType}
1318     * is {@code null} or {@code thumbnails} contains
1319     * {@code null} references or objects other than
1320     * {@code BufferedImage}s.
1321     * @exception IllegalArgumentException if width or height are less
1322     * than 1.
1323     * @exception IOException if an I/O error occurs during writing.
1324     */
1325    public void prepareInsertEmpty(int imageIndex,
1326                                   ImageTypeSpecifier imageType,
1327                                   int width, int height,
1328                                   IIOMetadata imageMetadata,
1329                                   List<? extends BufferedImage> thumbnails,
1330                                   ImageWriteParam param) throws IOException {
1331        unsupported();
1332    }
1333
1334    /**
1335     * Completes the insertion of a new image that was begun with a
1336     * prior call to {@code prepareInsertEmpty}.
1337     *
1338     * <p> The default implementation throws an
1339     * {@code IllegalStateException} if the output is
1340     * {@code null}, and otherwise throws an
1341     * {@code UnsupportedOperationException}.
1342     *
1343     * @exception IllegalStateException if the output has not
1344     * been set.
1345     * @exception UnsupportedOperationException if
1346     * {@code canInsertEmpty(imageIndex)} returns
1347     * {@code false}.
1348     * @exception IllegalStateException if a previous call to
1349     * {@code prepareInsertEmpty} without a corresponding call to
1350     * {@code endInsertEmpty} has not been made.
1351     * @exception IllegalStateException if a previous call to
1352     * {@code prepareWriteEmpty} without a corresponding call to
1353     * {@code endWriteEmpty} has been made.
1354     * @exception IllegalStateException if a call to
1355     * {@code prepareReplacePixels} has been made without a
1356     * matching call to {@code endReplacePixels}.
1357     * @exception IOException if an I/O error occurs during writing.
1358     */
1359    public void endInsertEmpty() throws IOException {
1360        unsupported();
1361    }
1362
1363    // Pixel replacement
1364
1365    /**
1366     * Returns {@code true} if the writer allows pixels of the
1367     * given image to be replaced using the {@code replacePixels}
1368     * methods.
1369     *
1370     * <p> A writer that does not support any pixel replacement may
1371     * return {@code false} without performing bounds checking on
1372     * the index.
1373     *
1374     * <p> The default implementation throws an
1375     * {@code IllegalStateException} if the output is
1376     * {@code null}, and otherwise returns {@code false}
1377     * without checking the value of {@code imageIndex}.
1378     *
1379     * @param imageIndex the index of the image whose pixels are to be
1380     * replaced.
1381     *
1382     * @return {@code true} if the pixels of the given
1383     * image can be replaced.
1384     *
1385     * @exception IllegalStateException if the output has not been
1386     * set.
1387     * @exception IndexOutOfBoundsException if the writer supports
1388     * pixel replacement in general, but {@code imageIndex} is
1389     * less than 0 or greater than the largest available index.
1390     * @exception IOException if an I/O error occurs during the query.
1391     */
1392    public boolean canReplacePixels(int imageIndex) throws IOException {
1393        if (getOutput() == null) {
1394            throw new IllegalStateException("getOutput() == null!");
1395        }
1396        return false;
1397    }
1398
1399    /**
1400     * Prepares the writer to handle a series of calls to the
1401     * {@code replacePixels} methods.  The affected pixel area
1402     * will be clipped against the supplied
1403     *
1404     * <p> If {@code canReplacePixels} returns
1405     * {@code false}, and
1406     * {@code UnsupportedOperationException} will be thrown.
1407     *
1408     * <p> The default implementation throws an
1409     * {@code IllegalStateException} if the output is
1410     * {@code null}, and otherwise throws an
1411     * {@code UnsupportedOperationException}.
1412     *
1413     * @param imageIndex the index of the image whose pixels are to be
1414     * replaced.
1415     * @param region a {@code Rectangle} that will be used to clip
1416     * future pixel regions.
1417     *
1418     * @exception IllegalStateException if the output has not
1419     * been set.
1420     * @exception UnsupportedOperationException if
1421     * {@code canReplacePixels(imageIndex)} returns
1422     * {@code false}.
1423     * @exception IndexOutOfBoundsException if {@code imageIndex}
1424     * is less than 0 or greater than the largest available index.
1425     * @exception IllegalStateException if there is a previous call to
1426     * {@code prepareReplacePixels} without a matching call to
1427     * {@code endReplacePixels} (<i>i.e.</i>, nesting is not
1428     * allowed).
1429     * @exception IllegalArgumentException if {@code region} is
1430     * {@code null} or has a width or height less than 1.
1431     * @exception IOException if an I/O error occurs during the
1432     * preparation.
1433     */
1434    public void prepareReplacePixels(int imageIndex,
1435                                     Rectangle region)  throws IOException {
1436        unsupported();
1437    }
1438
1439    /**
1440     * Replaces a portion of an image already present in the output
1441     * with a portion of the given image.  The image data must match,
1442     * or be convertible to, the image layout of the existing image.
1443     *
1444     * <p> The destination region is specified in the
1445     * {@code param} argument, and will be clipped to the image
1446     * boundaries and the region supplied to
1447     * {@code prepareReplacePixels}.  At least one pixel of the
1448     * source must not be clipped, or an exception is thrown.
1449     *
1450     * <p> An {@code ImageWriteParam} may optionally be supplied
1451     * to control the writing process.  If {@code param} is
1452     * {@code null}, a default write param will be used.
1453     *
1454     * <p> If the supplied {@code ImageWriteParam} contains
1455     * optional setting values not supported by this writer (<i>e.g.</i>
1456     * progressive encoding or any format-specific settings), they
1457     * will be ignored.
1458     *
1459     * <p> This method may only be called after a call to
1460     * {@code prepareReplacePixels}, or else an
1461     * {@code IllegalStateException} will be thrown.
1462     *
1463     * <p> The default implementation throws an
1464     * {@code IllegalStateException} if the output is
1465     * {@code null}, and otherwise throws an
1466     * {@code UnsupportedOperationException}.
1467     *
1468     * @param image a {@code RenderedImage} containing source
1469     * pixels.
1470     * @param param an {@code ImageWriteParam}, or
1471     * {@code null} to use a default
1472     * {@code ImageWriteParam}.
1473     *
1474     * @exception IllegalStateException if the output has not
1475     * been set.
1476     * @exception UnsupportedOperationException if
1477     * {@code canReplacePixels(imageIndex)} returns
1478     * {@code false}.
1479     * @exception IllegalStateException if there is no previous call to
1480     * {@code prepareReplacePixels} without a matching call to
1481     * {@code endReplacePixels}.
1482     * @exception IllegalArgumentException if any of the following are true:
1483     * <ul>
1484     * <li> {@code image} is {@code null}.
1485     * <li> the intersected region does not contain at least one pixel.
1486     * <li> the layout of {@code image} does not match, or this
1487     * writer cannot convert it to, the existing image layout.
1488     * </ul>
1489     * @exception IOException if an I/O error occurs during writing.
1490     */
1491    public void replacePixels(RenderedImage image, ImageWriteParam param)
1492        throws IOException {
1493        unsupported();
1494    }
1495
1496    /**
1497     * Replaces a portion of an image already present in the output
1498     * with a portion of the given {@code Raster}.  The image
1499     * data must match, or be convertible to, the image layout of the
1500     * existing image.
1501     *
1502     * <p> An {@code ImageWriteParam} may optionally be supplied
1503     * to control the writing process.  If {@code param} is
1504     * {@code null}, a default write param will be used.
1505     *
1506     * <p> The destination region is specified in the
1507     * {@code param} argument, and will be clipped to the image
1508     * boundaries and the region supplied to
1509     * {@code prepareReplacePixels}.  At least one pixel of the
1510     * source must not be clipped, or an exception is thrown.
1511     *
1512     * <p> If the supplied {@code ImageWriteParam} contains
1513     * optional setting values not supported by this writer (<i>e.g.</i>
1514     * progressive encoding or any format-specific settings), they
1515     * will be ignored.
1516     *
1517     * <p> This method may only be called after a call to
1518     * {@code prepareReplacePixels}, or else an
1519     * {@code IllegalStateException} will be thrown.
1520     *
1521     * <p> The default implementation throws an
1522     * {@code IllegalStateException} if the output is
1523     * {@code null}, and otherwise throws an
1524     * {@code UnsupportedOperationException}.
1525     *
1526     * @param raster a {@code Raster} containing source
1527     * pixels.
1528     * @param param an {@code ImageWriteParam}, or
1529     * {@code null} to use a default
1530     * {@code ImageWriteParam}.
1531     *
1532     * @exception IllegalStateException if the output has not
1533     * been set.
1534     * @exception UnsupportedOperationException if
1535     * {@code canReplacePixels(imageIndex)} returns
1536     * {@code false}.
1537     * @exception IllegalStateException if there is no previous call to
1538     * {@code prepareReplacePixels} without a matching call to
1539     * {@code endReplacePixels}.
1540     * @exception UnsupportedOperationException if
1541     * {@code canWriteRasters} returns {@code false}.
1542     * @exception IllegalArgumentException if any of the following are true:
1543     * <ul>
1544     * <li> {@code raster} is {@code null}.
1545     * <li> the intersected region does not contain at least one pixel.
1546     * <li> the layout of {@code raster} does not match, or this
1547     * writer cannot convert it to, the existing image layout.
1548     * </ul>
1549     * @exception IOException if an I/O error occurs during writing.
1550     */
1551    public void replacePixels(Raster raster, ImageWriteParam param)
1552        throws IOException {
1553        unsupported();
1554    }
1555
1556    /**
1557     * Terminates a sequence of calls to {@code replacePixels}.
1558     *
1559     * <p> If {@code canReplacePixels} returns
1560     * {@code false}, and
1561     * {@code UnsupportedOperationException} will be thrown.
1562     *
1563     * <p> The default implementation throws an
1564     * {@code IllegalStateException} if the output is
1565     * {@code null}, and otherwise throws an
1566     * {@code UnsupportedOperationException}.
1567     *
1568     * @exception IllegalStateException if the output has not
1569     * been set.
1570     * @exception UnsupportedOperationException if
1571     * {@code canReplacePixels(imageIndex)} returns
1572     * {@code false}.
1573     * @exception IllegalStateException if there is no previous call
1574     * to {@code prepareReplacePixels} without a matching call to
1575     * {@code endReplacePixels}.
1576     * @exception IOException if an I/O error occurs during writing.
1577     */
1578    public void endReplacePixels() throws IOException {
1579        unsupported();
1580    }
1581
1582    // Abort
1583
1584    /**
1585     * Requests that any current write operation be aborted.  The
1586     * contents of the output following the abort will be undefined.
1587     *
1588     * <p> Writers should call {@code clearAbortRequest} at the
1589     * beginning of each write operation, and poll the value of
1590     * {@code abortRequested} regularly during the write.
1591     */
1592    public synchronized void abort() {
1593        this.abortFlag = true;
1594    }
1595
1596    /**
1597     * Returns {@code true} if a request to abort the current
1598     * write operation has been made since the writer was instantiated or
1599     * {@code clearAbortRequest} was called.
1600     *
1601     * @return {@code true} if the current write operation should
1602     * be aborted.
1603     *
1604     * @see #abort
1605     * @see #clearAbortRequest
1606     */
1607    protected synchronized boolean abortRequested() {
1608        return this.abortFlag;
1609    }
1610
1611    /**
1612     * Clears any previous abort request.  After this method has been
1613     * called, {@code abortRequested} will return
1614     * {@code false}.
1615     *
1616     * @see #abort
1617     * @see #abortRequested
1618     */
1619    protected synchronized void clearAbortRequest() {
1620        this.abortFlag = false;
1621    }
1622
1623    // Listeners
1624
1625    /**
1626     * Adds an {@code IIOWriteWarningListener} to the list of
1627     * registered warning listeners.  If {@code listener} is
1628     * {@code null}, no exception will be thrown and no action
1629     * will be taken.  Messages sent to the given listener will be
1630     * localized, if possible, to match the current
1631     * {@code Locale}.  If no {@code Locale} has been set,
1632     * warning messages may be localized as the writer sees fit.
1633     *
1634     * @param listener an {@code IIOWriteWarningListener} to be
1635     * registered.
1636     *
1637     * @see #removeIIOWriteWarningListener
1638     */
1639    public void addIIOWriteWarningListener(IIOWriteWarningListener listener) {
1640        if (listener == null) {
1641            return;
1642        }
1643        warningListeners = ImageReader.addToList(warningListeners, listener);
1644        warningLocales = ImageReader.addToList(warningLocales, getLocale());
1645    }
1646
1647    /**
1648     * Removes an {@code IIOWriteWarningListener} from the list
1649     * of registered warning listeners.  If the listener was not
1650     * previously registered, or if {@code listener} is
1651     * {@code null}, no exception will be thrown and no action
1652     * will be taken.
1653     *
1654     * @param listener an {@code IIOWriteWarningListener} to be
1655     * deregistered.
1656     *
1657     * @see #addIIOWriteWarningListener
1658     */
1659    public
1660        void removeIIOWriteWarningListener(IIOWriteWarningListener listener) {
1661        if (listener == null || warningListeners == null) {
1662            return;
1663        }
1664        int index = warningListeners.indexOf(listener);
1665        if (index != -1) {
1666            warningListeners.remove(index);
1667            warningLocales.remove(index);
1668            if (warningListeners.size() == 0) {
1669                warningListeners = null;
1670                warningLocales = null;
1671            }
1672        }
1673    }
1674
1675    /**
1676     * Removes all currently registered
1677     * {@code IIOWriteWarningListener} objects.
1678     *
1679     * <p> The default implementation sets the
1680     * {@code warningListeners} and {@code warningLocales}
1681     * instance variables to {@code null}.
1682     */
1683    public void removeAllIIOWriteWarningListeners() {
1684        this.warningListeners = null;
1685        this.warningLocales = null;
1686    }
1687
1688    /**
1689     * Adds an {@code IIOWriteProgressListener} to the list of
1690     * registered progress listeners.  If {@code listener} is
1691     * {@code null}, no exception will be thrown and no action
1692     * will be taken.
1693     *
1694     * @param listener an {@code IIOWriteProgressListener} to be
1695     * registered.
1696     *
1697     * @see #removeIIOWriteProgressListener
1698     */
1699    public void
1700        addIIOWriteProgressListener(IIOWriteProgressListener listener) {
1701        if (listener == null) {
1702            return;
1703        }
1704        progressListeners = ImageReader.addToList(progressListeners, listener);
1705    }
1706
1707    /**
1708     * Removes an {@code IIOWriteProgressListener} from the list
1709     * of registered progress listeners.  If the listener was not
1710     * previously registered, or if {@code listener} is
1711     * {@code null}, no exception will be thrown and no action
1712     * will be taken.
1713     *
1714     * @param listener an {@code IIOWriteProgressListener} to be
1715     * deregistered.
1716     *
1717     * @see #addIIOWriteProgressListener
1718     */
1719    public void
1720        removeIIOWriteProgressListener(IIOWriteProgressListener listener) {
1721        if (listener == null || progressListeners == null) {
1722            return;
1723        }
1724        progressListeners =
1725            ImageReader.removeFromList(progressListeners, listener);
1726    }
1727
1728    /**
1729     * Removes all currently registered
1730     * {@code IIOWriteProgressListener} objects.
1731     *
1732     * <p> The default implementation sets the
1733     * {@code progressListeners} instance variable to
1734     * {@code null}.
1735     */
1736    public void removeAllIIOWriteProgressListeners() {
1737        this.progressListeners = null;
1738    }
1739
1740    /**
1741     * Broadcasts the start of an image write to all registered
1742     * {@code IIOWriteProgressListener}s by calling their
1743     * {@code imageStarted} method.  Subclasses may use this
1744     * method as a convenience.
1745     *
1746     * @param imageIndex the index of the image about to be written.
1747     */
1748    protected void processImageStarted(int imageIndex) {
1749        if (progressListeners == null) {
1750            return;
1751        }
1752        int numListeners = progressListeners.size();
1753        for (int i = 0; i < numListeners; i++) {
1754            IIOWriteProgressListener listener =
1755                progressListeners.get(i);
1756            listener.imageStarted(this, imageIndex);
1757        }
1758    }
1759
1760    /**
1761     * Broadcasts the current percentage of image completion to all
1762     * registered {@code IIOWriteProgressListener}s by calling
1763     * their {@code imageProgress} method.  Subclasses may use
1764     * this method as a convenience.
1765     *
1766     * @param percentageDone the current percentage of completion,
1767     * as a {@code float}.
1768     */
1769    protected void processImageProgress(float percentageDone) {
1770        if (progressListeners == null) {
1771            return;
1772        }
1773        int numListeners = progressListeners.size();
1774        for (int i = 0; i < numListeners; i++) {
1775            IIOWriteProgressListener listener =
1776                progressListeners.get(i);
1777            listener.imageProgress(this, percentageDone);
1778        }
1779    }
1780
1781    /**
1782     * Broadcasts the completion of an image write to all registered
1783     * {@code IIOWriteProgressListener}s by calling their
1784     * {@code imageComplete} method.  Subclasses may use this
1785     * method as a convenience.
1786     */
1787    protected void processImageComplete() {
1788        if (progressListeners == null) {
1789            return;
1790        }
1791        int numListeners = progressListeners.size();
1792        for (int i = 0; i < numListeners; i++) {
1793            IIOWriteProgressListener listener =
1794                progressListeners.get(i);
1795            listener.imageComplete(this);
1796        }
1797    }
1798
1799    /**
1800     * Broadcasts the start of a thumbnail write to all registered
1801     * {@code IIOWriteProgressListener}s by calling their
1802     * {@code thumbnailStarted} method.  Subclasses may use this
1803     * method as a convenience.
1804     *
1805     * @param imageIndex the index of the image associated with the
1806     * thumbnail.
1807     * @param thumbnailIndex the index of the thumbnail.
1808     */
1809    protected void processThumbnailStarted(int imageIndex,
1810                                           int thumbnailIndex) {
1811        if (progressListeners == null) {
1812            return;
1813        }
1814        int numListeners = progressListeners.size();
1815        for (int i = 0; i < numListeners; i++) {
1816            IIOWriteProgressListener listener =
1817                progressListeners.get(i);
1818            listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
1819        }
1820    }
1821
1822    /**
1823     * Broadcasts the current percentage of thumbnail completion to
1824     * all registered {@code IIOWriteProgressListener}s by calling
1825     * their {@code thumbnailProgress} method.  Subclasses may
1826     * use this method as a convenience.
1827     *
1828     * @param percentageDone the current percentage of completion,
1829     * as a {@code float}.
1830     */
1831    protected void processThumbnailProgress(float percentageDone) {
1832        if (progressListeners == null) {
1833            return;
1834        }
1835        int numListeners = progressListeners.size();
1836        for (int i = 0; i < numListeners; i++) {
1837            IIOWriteProgressListener listener =
1838                progressListeners.get(i);
1839            listener.thumbnailProgress(this, percentageDone);
1840        }
1841    }
1842
1843    /**
1844     * Broadcasts the completion of a thumbnail write to all registered
1845     * {@code IIOWriteProgressListener}s by calling their
1846     * {@code thumbnailComplete} method.  Subclasses may use this
1847     * method as a convenience.
1848     */
1849    protected void processThumbnailComplete() {
1850        if (progressListeners == null) {
1851            return;
1852        }
1853        int numListeners = progressListeners.size();
1854        for (int i = 0; i < numListeners; i++) {
1855            IIOWriteProgressListener listener =
1856                progressListeners.get(i);
1857            listener.thumbnailComplete(this);
1858        }
1859    }
1860
1861    /**
1862     * Broadcasts that the write has been aborted to all registered
1863     * {@code IIOWriteProgressListener}s by calling their
1864     * {@code writeAborted} method.  Subclasses may use this
1865     * method as a convenience.
1866     */
1867    protected void processWriteAborted() {
1868        if (progressListeners == null) {
1869            return;
1870        }
1871        int numListeners = progressListeners.size();
1872        for (int i = 0; i < numListeners; i++) {
1873            IIOWriteProgressListener listener =
1874                progressListeners.get(i);
1875            listener.writeAborted(this);
1876        }
1877    }
1878
1879    /**
1880     * Broadcasts a warning message to all registered
1881     * {@code IIOWriteWarningListener}s by calling their
1882     * {@code warningOccurred} method.  Subclasses may use this
1883     * method as a convenience.
1884     *
1885     * @param imageIndex the index of the image on which the warning
1886     * occurred.
1887     * @param warning the warning message.
1888     *
1889     * @exception IllegalArgumentException if {@code warning}
1890     * is {@code null}.
1891     */
1892    protected void processWarningOccurred(int imageIndex,
1893                                          String warning) {
1894        if (warningListeners == null) {
1895            return;
1896        }
1897        if (warning == null) {
1898            throw new IllegalArgumentException("warning == null!");
1899        }
1900        int numListeners = warningListeners.size();
1901        for (int i = 0; i < numListeners; i++) {
1902            IIOWriteWarningListener listener =
1903                warningListeners.get(i);
1904
1905            listener.warningOccurred(this, imageIndex, warning);
1906        }
1907    }
1908
1909    /**
1910     * Broadcasts a localized warning message to all registered
1911     * {@code IIOWriteWarningListener}s by calling their
1912     * {@code warningOccurred} method with a string taken
1913     * from a {@code ResourceBundle}.  Subclasses may use this
1914     * method as a convenience.
1915     *
1916     * @param imageIndex the index of the image on which the warning
1917     * occurred.
1918     * @param baseName the base name of a set of
1919     * {@code ResourceBundle}s containing localized warning
1920     * messages.
1921     * @param keyword the keyword used to index the warning message
1922     * within the set of {@code ResourceBundle}s.
1923     *
1924     * @exception IllegalArgumentException if {@code baseName}
1925     * is {@code null}.
1926     * @exception IllegalArgumentException if {@code keyword}
1927     * is {@code null}.
1928     * @exception IllegalArgumentException if no appropriate
1929     * {@code ResourceBundle} may be located.
1930     * @exception IllegalArgumentException if the named resource is
1931     * not found in the located {@code ResourceBundle}.
1932     * @exception IllegalArgumentException if the object retrieved
1933     * from the {@code ResourceBundle} is not a
1934     * {@code String}.
1935     */
1936    protected void processWarningOccurred(int imageIndex,
1937                                          String baseName,
1938                                          String keyword) {
1939        if (warningListeners == null) {
1940            return;
1941        }
1942        if (baseName == null) {
1943            throw new IllegalArgumentException("baseName == null!");
1944        }
1945        if (keyword == null) {
1946            throw new IllegalArgumentException("keyword == null!");
1947        }
1948        int numListeners = warningListeners.size();
1949        for (int i = 0; i < numListeners; i++) {
1950            IIOWriteWarningListener listener =
1951                warningListeners.get(i);
1952            Locale locale = warningLocales.get(i);
1953            if (locale == null) {
1954                locale = Locale.getDefault();
1955            }
1956
1957            /*
1958             * Only the plugin knows the messages that are provided, so we
1959             * can always locate the resource bundles from the same loader
1960             * as that for the plugin code itself.
1961             */
1962            ResourceBundle bundle = null;
1963            try {
1964                bundle = ResourceBundle.getBundle(baseName, locale, this.getClass().getModule());
1965            } catch (MissingResourceException mre) {
1966                throw new IllegalArgumentException("Bundle not found!", mre);
1967            }
1968
1969            String warning = null;
1970            try {
1971                warning = bundle.getString(keyword);
1972            } catch (ClassCastException cce) {
1973                throw new IllegalArgumentException("Resource is not a String!", cce);
1974            } catch (MissingResourceException mre) {
1975                throw new IllegalArgumentException("Resource is missing!", mre);
1976            }
1977
1978            listener.warningOccurred(this, imageIndex, warning);
1979        }
1980    }
1981
1982    // State management
1983
1984    /**
1985     * Restores the {@code ImageWriter} to its initial state.
1986     *
1987     * <p> The default implementation calls
1988     * {@code setOutput(null)}, {@code setLocale(null)},
1989     * {@code removeAllIIOWriteWarningListeners()},
1990     * {@code removeAllIIOWriteProgressListeners()}, and
1991     * {@code clearAbortRequest}.
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}) 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}.
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