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