View Javadoc
1   /*
2    * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package javax.imageio;
27  
28  import java.awt.Point;
29  import java.awt.Rectangle;
30  import java.awt.image.BufferedImage;
31  import java.awt.image.Raster;
32  import java.awt.image.RenderedImage;
33  import java.io.IOException;
34  import java.util.ArrayList;
35  import java.util.Iterator;
36  import java.util.List;
37  import java.util.Locale;
38  import java.util.MissingResourceException;
39  import java.util.ResourceBundle;
40  import java.util.Set;
41  import javax.imageio.spi.ImageReaderSpi;
42  import javax.imageio.event.IIOReadWarningListener;
43  import javax.imageio.event.IIOReadProgressListener;
44  import javax.imageio.event.IIOReadUpdateListener;
45  import javax.imageio.metadata.IIOMetadata;
46  import javax.imageio.metadata.IIOMetadataFormatImpl;
47  import javax.imageio.stream.ImageInputStream;
48  
49  /**
50   * An abstract superclass for parsing and decoding of images.  This
51   * class must be subclassed by classes that read in images in the
52   * context of the Java Image I/O framework.
53   *
54   * <p> <code>ImageReader</code> objects are normally instantiated by
55   * the service provider interface (SPI) class for the specific format.
56   * Service provider classes (e.g., instances of
57   * <code>ImageReaderSpi</code>) are registered with the
58   * <code>IIORegistry</code>, which uses them for format recognition
59   * and presentation of available format readers and writers.
60   *
61   * <p> When an input source is set (using the <code>setInput</code>
62   * method), it may be marked as "seek forward only".  This setting
63   * means that images contained within the input source will only be
64   * read in order, possibly allowing the reader to avoid caching
65   * portions of the input containing data associated with images that
66   * have been read previously.
67   *
68   * @see ImageWriter
69   * @see javax.imageio.spi.IIORegistry
70   * @see javax.imageio.spi.ImageReaderSpi
71   *
72   */
73  public abstract class ImageReader {
74  
75      /**
76       * The <code>ImageReaderSpi</code> that instantiated this object,
77       * or <code>null</code> if its identity is not known or none
78       * exists.  By default it is initialized to <code>null</code>.
79       */
80      protected ImageReaderSpi originatingProvider;
81  
82      /**
83       * The <code>ImageInputStream</code> or other
84       * <code>Object</code> by <code>setInput</code> and retrieved
85       * by <code>getInput</code>.  By default it is initialized to
86       * <code>null</code>.
87       */
88      protected Object input = null;
89  
90      /**
91       * <code>true</code> if the current input source has been marked
92       * as allowing only forward seeking by <code>setInput</code>.  By
93       * default, the value is <code>false</code>.
94       *
95       * @see #minIndex
96       * @see #setInput
97       */
98      protected boolean seekForwardOnly = false;
99  
100     /**
101      * <code>true</code> if the current input source has been marked
102      * as allowing metadata to be ignored by <code>setInput</code>.
103      * By default, the value is <code>false</code>.
104      *
105      * @see #setInput
106      */
107     protected boolean ignoreMetadata = false;
108 
109     /**
110      * The smallest valid index for reading, initially 0.  When
111      * <code>seekForwardOnly</code> is <code>true</code>, various methods
112      * may throw an <code>IndexOutOfBoundsException</code> on an
113      * attempt to access data associate with an image having a lower
114      * index.
115      *
116      * @see #seekForwardOnly
117      * @see #setInput
118      */
119     protected int minIndex = 0;
120 
121     /**
122      * An array of <code>Locale</code>s which may be used to localize
123      * warning messages, or <code>null</code> if localization is not
124      * supported.
125      */
126     protected Locale[] availableLocales = null;
127 
128     /**
129      * The current <code>Locale</code> to be used for localization, or
130      * <code>null</code> if none has been set.
131      */
132     protected Locale locale = null;
133 
134     /**
135      * A <code>List</code> of currently registered
136      * <code>IIOReadWarningListener</code>s, initialized by default to
137      * <code>null</code>, which is synonymous with an empty
138      * <code>List</code>.
139      */
140     protected List<IIOReadWarningListener> warningListeners = null;
141 
142     /**
143      * A <code>List</code> of the <code>Locale</code>s associated with
144      * each currently registered <code>IIOReadWarningListener</code>,
145      * initialized by default to <code>null</code>, which is
146      * synonymous with an empty <code>List</code>.
147      */
148     protected List<Locale> warningLocales = null;
149 
150     /**
151      * A <code>List</code> of currently registered
152      * <code>IIOReadProgressListener</code>s, initialized by default
153      * to <code>null</code>, which is synonymous with an empty
154      * <code>List</code>.
155      */
156     protected List<IIOReadProgressListener> progressListeners = null;
157 
158     /**
159      * A <code>List</code> of currently registered
160      * <code>IIOReadUpdateListener</code>s, initialized by default to
161      * <code>null</code>, which is synonymous with an empty
162      * <code>List</code>.
163      */
164     protected List<IIOReadUpdateListener> updateListeners = null;
165 
166     /**
167      * If <code>true</code>, the current read operation should be
168      * aborted.
169      */
170     private boolean abortFlag = false;
171 
172     /**
173      * Constructs an <code>ImageReader</code> and sets its
174      * <code>originatingProvider</code> field to the supplied value.
175      *
176      * <p> Subclasses that make use of extensions should provide a
177      * constructor with signature <code>(ImageReaderSpi,
178      * Object)</code> in order to retrieve the extension object.  If
179      * the extension object is unsuitable, an
180      * <code>IllegalArgumentException</code> should be thrown.
181      *
182      * @param originatingProvider the <code>ImageReaderSpi</code> that is
183      * invoking this constructor, or <code>null</code>.
184      */
185     protected ImageReader(ImageReaderSpi originatingProvider) {
186         this.originatingProvider = originatingProvider;
187     }
188 
189     /**
190      * Returns a <code>String</code> identifying the format of the
191      * input source.
192      *
193      * <p> The default implementation returns
194      * <code>originatingProvider.getFormatNames()[0]</code>.
195      * Implementations that may not have an originating service
196      * provider, or which desire a different naming policy should
197      * override this method.
198      *
199      * @exception IOException if an error occurs reading the
200      * information from the input source.
201      *
202      * @return the format name, as a <code>String</code>.
203      */
204     public String getFormatName() throws IOException {
205         return originatingProvider.getFormatNames()[0];
206     }
207 
208     /**
209      * Returns the <code>ImageReaderSpi</code> that was passed in on
210      * the constructor.  Note that this value may be <code>null</code>.
211      *
212      * @return an <code>ImageReaderSpi</code>, or <code>null</code>.
213      *
214      * @see ImageReaderSpi
215      */
216     public ImageReaderSpi getOriginatingProvider() {
217         return originatingProvider;
218     }
219 
220     /**
221      * Sets the input source to use to the given
222      * <code>ImageInputStream</code> or other <code>Object</code>.
223      * The input source must be set before any of the query or read
224      * methods are used.  If <code>input</code> is <code>null</code>,
225      * any currently set input source will be removed.  In any case,
226      * the value of <code>minIndex</code> will be initialized to 0.
227      *
228      * <p> The <code>seekForwardOnly</code> parameter controls whether
229      * the value returned by <code>getMinIndex</code> will be
230      * increased as each image (or thumbnail, or image metadata) is
231      * read.  If <code>seekForwardOnly</code> is true, then a call to
232      * <code>read(index)</code> will throw an
233      * <code>IndexOutOfBoundsException</code> if {@code index < this.minIndex};
234      * otherwise, the value of
235      * <code>minIndex</code> will be set to <code>index</code>.  If
236      * <code>seekForwardOnly</code> is <code>false</code>, the value of
237      * <code>minIndex</code> will remain 0 regardless of any read
238      * operations.
239      *
240      * <p> The <code>ignoreMetadata</code> parameter, if set to
241      * <code>true</code>, allows the reader to disregard any metadata
242      * encountered during the read.  Subsequent calls to the
243      * <code>getStreamMetadata</code> and
244      * <code>getImageMetadata</code> methods may return
245      * <code>null</code>, and an <code>IIOImage</code> returned from
246      * <code>readAll</code> may return <code>null</code> from their
247      * <code>getMetadata</code> method.  Setting this parameter may
248      * allow the reader to work more efficiently.  The reader may
249      * choose to disregard this setting and return metadata normally.
250      *
251      * <p> Subclasses should take care to remove any cached
252      * information based on the previous stream, such as header
253      * information or partially decoded image data.
254      *
255      * <p> Use of a general <code>Object</code> other than an
256      * <code>ImageInputStream</code> is intended for readers that
257      * interact directly with a capture device or imaging protocol.
258      * The set of legal classes is advertised by the reader's service
259      * provider's <code>getInputTypes</code> method; most readers
260      * will return a single-element array containing only
261      * <code>ImageInputStream.class</code> to indicate that they
262      * accept only an <code>ImageInputStream</code>.
263      *
264      * <p> The default implementation checks the <code>input</code>
265      * argument against the list returned by
266      * <code>originatingProvider.getInputTypes()</code> and fails
267      * if the argument is not an instance of one of the classes
268      * in the list.  If the originating provider is set to
269      * <code>null</code>, the input is accepted only if it is an
270      * <code>ImageInputStream</code>.
271      *
272      * @param input the <code>ImageInputStream</code> or other
273      * <code>Object</code> to use for future decoding.
274      * @param seekForwardOnly if <code>true</code>, images and metadata
275      * may only be read in ascending order from this input source.
276      * @param ignoreMetadata if <code>true</code>, metadata
277      * may be ignored during reads.
278      *
279      * @exception IllegalArgumentException if <code>input</code> is
280      * not an instance of one of the classes returned by the
281      * originating service provider's <code>getInputTypes</code>
282      * method, or is not an <code>ImageInputStream</code>.
283      *
284      * @see ImageInputStream
285      * @see #getInput
286      * @see javax.imageio.spi.ImageReaderSpi#getInputTypes
287      */
288     public void setInput(Object input,
289                          boolean seekForwardOnly,
290                          boolean ignoreMetadata) {
291         if (input != null) {
292             boolean found = false;
293             if (originatingProvider != null) {
294                 Class[] classes = originatingProvider.getInputTypes();
295                 for (int i = 0; i < classes.length; i++) {
296                     if (classes[i].isInstance(input)) {
297                         found = true;
298                         break;
299                     }
300                 }
301             } else {
302                 if (input instanceof ImageInputStream) {
303                     found = true;
304                 }
305             }
306             if (!found) {
307                 throw new IllegalArgumentException("Incorrect input type!");
308             }
309 
310             this.seekForwardOnly = seekForwardOnly;
311             this.ignoreMetadata = ignoreMetadata;
312             this.minIndex = 0;
313         }
314 
315         this.input = input;
316     }
317 
318     /**
319      * Sets the input source to use to the given
320      * <code>ImageInputStream</code> or other <code>Object</code>.
321      * The input source must be set before any of the query or read
322      * methods are used.  If <code>input</code> is <code>null</code>,
323      * any currently set input source will be removed.  In any case,
324      * the value of <code>minIndex</code> will be initialized to 0.
325      *
326      * <p> The <code>seekForwardOnly</code> parameter controls whether
327      * the value returned by <code>getMinIndex</code> will be
328      * increased as each image (or thumbnail, or image metadata) is
329      * read.  If <code>seekForwardOnly</code> is true, then a call to
330      * <code>read(index)</code> will throw an
331      * <code>IndexOutOfBoundsException</code> if {@code index < this.minIndex};
332      * otherwise, the value of
333      * <code>minIndex</code> will be set to <code>index</code>.  If
334      * <code>seekForwardOnly</code> is <code>false</code>, the value of
335      * <code>minIndex</code> will remain 0 regardless of any read
336      * operations.
337      *
338      * <p> This method is equivalent to <code>setInput(input,
339      * seekForwardOnly, false)</code>.
340      *
341      * @param input the <code>ImageInputStream</code> or other
342      * <code>Object</code> to use for future decoding.
343      * @param seekForwardOnly if <code>true</code>, images and metadata
344      * may only be read in ascending order from this input source.
345      *
346      * @exception IllegalArgumentException if <code>input</code> is
347      * not an instance of one of the classes returned by the
348      * originating service provider's <code>getInputTypes</code>
349      * method, or is not an <code>ImageInputStream</code>.
350      *
351      * @see #getInput
352      */
353     public void setInput(Object input,
354                          boolean seekForwardOnly) {
355         setInput(input, seekForwardOnly, false);
356     }
357 
358     /**
359      * Sets the input source to use to the given
360      * <code>ImageInputStream</code> or other <code>Object</code>.
361      * The input source must be set before any of the query or read
362      * methods are used.  If <code>input</code> is <code>null</code>,
363      * any currently set input source will be removed.  In any case,
364      * the value of <code>minIndex</code> will be initialized to 0.
365      *
366      * <p> This method is equivalent to <code>setInput(input, false,
367      * false)</code>.
368      *
369      * @param input the <code>ImageInputStream</code> or other
370      * <code>Object</code> to use for future decoding.
371      *
372      * @exception IllegalArgumentException if <code>input</code> is
373      * not an instance of one of the classes returned by the
374      * originating service provider's <code>getInputTypes</code>
375      * method, or is not an <code>ImageInputStream</code>.
376      *
377      * @see #getInput
378      */
379     public void setInput(Object input) {
380         setInput(input, false, false);
381     }
382 
383     /**
384      * Returns the <code>ImageInputStream</code> or other
385      * <code>Object</code> previously set as the input source.  If the
386      * input source has not been set, <code>null</code> is returned.
387      *
388      * @return the <code>Object</code> that will be used for future
389      * decoding, or <code>null</code>.
390      *
391      * @see ImageInputStream
392      * @see #setInput
393      */
394     public Object getInput() {
395         return input;
396     }
397 
398     /**
399      * Returns <code>true</code> if the current input source has been
400      * marked as seek forward only by passing <code>true</code> as the
401      * <code>seekForwardOnly</code> argument to the
402      * <code>setInput</code> method.
403      *
404      * @return <code>true</code> if the input source is seek forward
405      * only.
406      *
407      * @see #setInput
408      */
409     public boolean isSeekForwardOnly() {
410         return seekForwardOnly;
411     }
412 
413     /**
414      * Returns <code>true</code> if the current input source has been
415      * marked as allowing metadata to be ignored by passing
416      * <code>true</code> as the <code>ignoreMetadata</code> argument
417      * to the <code>setInput</code> method.
418      *
419      * @return <code>true</code> if the metadata may be ignored.
420      *
421      * @see #setInput
422      */
423     public boolean isIgnoringMetadata() {
424         return ignoreMetadata;
425     }
426 
427     /**
428      * Returns the lowest valid index for reading an image, thumbnail,
429      * or image metadata.  If <code>seekForwardOnly()</code> is
430      * <code>false</code>, this value will typically remain 0,
431      * indicating that random access is possible.  Otherwise, it will
432      * contain the value of the most recently accessed index, and
433      * increase in a monotonic fashion.
434      *
435      * @return the minimum legal index for reading.
436      */
437     public int getMinIndex() {
438         return minIndex;
439     }
440 
441     // Localization
442 
443     /**
444      * Returns an array of <code>Locale</code>s that may be used to
445      * localize warning listeners and compression settings.  A return
446      * value of <code>null</code> indicates that localization is not
447      * supported.
448      *
449      * <p> The default implementation returns a clone of the
450      * <code>availableLocales</code> instance variable if it is
451      * non-<code>null</code>, or else returns <code>null</code>.
452      *
453      * @return an array of <code>Locale</code>s that may be used as
454      * arguments to <code>setLocale</code>, or <code>null</code>.
455      */
456     public Locale[] getAvailableLocales() {
457         if (availableLocales == null) {
458             return null;
459         } else {
460             return (Locale[])availableLocales.clone();
461         }
462     }
463 
464     /**
465      * Sets the current <code>Locale</code> of this
466      * <code>ImageReader</code> to the given value.  A value of
467      * <code>null</code> removes any previous setting, and indicates
468      * that the reader should localize as it sees fit.
469      *
470      * @param locale the desired <code>Locale</code>, or
471      * <code>null</code>.
472      *
473      * @exception IllegalArgumentException if <code>locale</code> is
474      * non-<code>null</code> but is not one of the values returned by
475      * <code>getAvailableLocales</code>.
476      *
477      * @see #getLocale
478      */
479     public void setLocale(Locale locale) {
480         if (locale != null) {
481             Locale[] locales = getAvailableLocales();
482             boolean found = false;
483             if (locales != null) {
484                 for (int i = 0; i < locales.length; i++) {
485                     if (locale.equals(locales[i])) {
486                         found = true;
487                         break;
488                     }
489                 }
490             }
491             if (!found) {
492                 throw new IllegalArgumentException("Invalid locale!");
493             }
494         }
495         this.locale = locale;
496     }
497 
498     /**
499      * Returns the currently set <code>Locale</code>, or
500      * <code>null</code> if none has been set.
501      *
502      * @return the current <code>Locale</code>, or <code>null</code>.
503      *
504      * @see #setLocale
505      */
506     public Locale getLocale() {
507         return locale;
508     }
509 
510     // Image queries
511 
512     /**
513      * Returns the number of images, not including thumbnails, available
514      * from the current input source.
515      *
516      * <p> Note that some image formats (such as animated GIF) do not
517      * specify how many images are present in the stream.  Thus
518      * determining the number of images will require the entire stream
519      * to be scanned and may require memory for buffering.  If images
520      * are to be processed in order, it may be more efficient to
521      * simply call <code>read</code> with increasing indices until an
522      * <code>IndexOutOfBoundsException</code> is thrown to indicate
523      * that no more images are available.  The
524      * <code>allowSearch</code> parameter may be set to
525      * <code>false</code> to indicate that an exhaustive search is not
526      * desired; the return value will be <code>-1</code> to indicate
527      * that a search is necessary.  If the input has been specified
528      * with <code>seekForwardOnly</code> set to <code>true</code>,
529      * this method throws an <code>IllegalStateException</code> if
530      * <code>allowSearch</code> is set to <code>true</code>.
531      *
532      * @param allowSearch if <code>true</code>, the true number of
533      * images will be returned even if a search is required.  If
534      * <code>false</code>, the reader may return <code>-1</code>
535      * without performing the search.
536      *
537      * @return the number of images, as an <code>int</code>, or
538      * <code>-1</code> if <code>allowSearch</code> is
539      * <code>false</code> and a search would be required.
540      *
541      * @exception IllegalStateException if the input source has not been set,
542      * or if the input has been specified with <code>seekForwardOnly</code>
543      * set to <code>true</code>.
544      * @exception IOException if an error occurs reading the
545      * information from the input source.
546      *
547      * @see #setInput
548      */
549     public abstract int getNumImages(boolean allowSearch) throws IOException;
550 
551     /**
552      * Returns the width in pixels of the given image within the input
553      * source.
554      *
555      * <p> If the image can be rendered to a user-specified size, then
556      * this method returns the default width.
557      *
558      * @param imageIndex the index of the image to be queried.
559      *
560      * @return the width of the image, as an <code>int</code>.
561      *
562      * @exception IllegalStateException if the input source has not been set.
563      * @exception IndexOutOfBoundsException if the supplied index is
564      * out of bounds.
565      * @exception IOException if an error occurs reading the width
566      * information from the input source.
567      */
568     public abstract int getWidth(int imageIndex) throws IOException;
569 
570     /**
571      * Returns the height in pixels of the given image within the
572      * input source.
573      *
574      * <p> If the image can be rendered to a user-specified size, then
575      * this method returns the default height.
576      *
577      * @param imageIndex the index of the image to be queried.
578      *
579      * @return the height of the image, as an <code>int</code>.
580      *
581      * @exception IllegalStateException if the input source has not been set.
582      * @exception IndexOutOfBoundsException if the supplied index is
583      * out of bounds.
584      * @exception IOException if an error occurs reading the height
585      * information from the input source.
586      */
587     public abstract int getHeight(int imageIndex) throws IOException;
588 
589     /**
590      * Returns <code>true</code> if the storage format of the given
591      * image places no inherent impediment on random access to pixels.
592      * For most compressed formats, such as JPEG, this method should
593      * return <code>false</code>, as a large section of the image in
594      * addition to the region of interest may need to be decoded.
595      *
596      * <p> This is merely a hint for programs that wish to be
597      * efficient; all readers must be able to read arbitrary regions
598      * as specified in an <code>ImageReadParam</code>.
599      *
600      * <p> Note that formats that return <code>false</code> from
601      * this method may nonetheless allow tiling (<i>e.g.</i> Restart
602      * Markers in JPEG), and random access will likely be reasonably
603      * efficient on tiles.  See {@link #isImageTiled isImageTiled}.
604      *
605      * <p> A reader for which all images are guaranteed to support
606      * easy random access, or are guaranteed not to support easy
607      * random access, may return <code>true</code> or
608      * <code>false</code> respectively without accessing any image
609      * data.  In such cases, it is not necessary to throw an exception
610      * even if no input source has been set or the image index is out
611      * of bounds.
612      *
613      * <p> The default implementation returns <code>false</code>.
614      *
615      * @param imageIndex the index of the image to be queried.
616      *
617      * @return <code>true</code> if reading a region of interest of
618      * the given image is likely to be efficient.
619      *
620      * @exception IllegalStateException if an input source is required
621      * to determine the return value, but none has been set.
622      * @exception IndexOutOfBoundsException if an image must be
623      * accessed to determine the return value, but the supplied index
624      * is out of bounds.
625      * @exception IOException if an error occurs during reading.
626      */
627     public boolean isRandomAccessEasy(int imageIndex) throws IOException {
628         return false;
629     }
630 
631     /**
632      * Returns the aspect ratio of the given image (that is, its width
633      * divided by its height) as a <code>float</code>.  For images
634      * that are inherently resizable, this method provides a way to
635      * determine the appropriate width given a desired height, or vice
636      * versa.  For non-resizable images, the true width and height
637      * are used.
638      *
639      * <p> The default implementation simply returns
640      * <code>(float)getWidth(imageIndex)/getHeight(imageIndex)</code>.
641      *
642      * @param imageIndex the index of the image to be queried.
643      *
644      * @return a <code>float</code> indicating the aspect ratio of the
645      * given image.
646      *
647      * @exception IllegalStateException if the input source has not been set.
648      * @exception IndexOutOfBoundsException if the supplied index is
649      * out of bounds.
650      * @exception IOException if an error occurs during reading.
651      */
652     public float getAspectRatio(int imageIndex) throws IOException {
653         return (float)getWidth(imageIndex)/getHeight(imageIndex);
654     }
655 
656     /**
657      * Returns an <code>ImageTypeSpecifier</code> indicating the
658      * <code>SampleModel</code> and <code>ColorModel</code> which most
659      * closely represents the "raw" internal format of the image.  For
660      * example, for a JPEG image the raw type might have a YCbCr color
661      * space even though the image would conventionally be transformed
662      * into an RGB color space prior to display.  The returned value
663      * should also be included in the list of values returned by
664      * <code>getImageTypes</code>.
665      *
666      * <p> The default implementation simply returns the first entry
667      * from the list provided by <code>getImageType</code>.
668      *
669      * @param imageIndex the index of the image to be queried.
670      *
671      * @return an <code>ImageTypeSpecifier</code>.
672      *
673      * @exception IllegalStateException if the input source has not been set.
674      * @exception IndexOutOfBoundsException if the supplied index is
675      * out of bounds.
676      * @exception IOException if an error occurs reading the format
677      * information from the input source.
678      */
679     public ImageTypeSpecifier getRawImageType(int imageIndex)
680         throws IOException {
681         return (ImageTypeSpecifier)getImageTypes(imageIndex).next();
682     }
683 
684     /**
685      * Returns an <code>Iterator</code> containing possible image
686      * types to which the given image may be decoded, in the form of
687      * <code>ImageTypeSpecifiers</code>s.  At least one legal image
688      * type will be returned.
689      *
690      * <p> The first element of the iterator should be the most
691      * "natural" type for decoding the image with as little loss as
692      * possible.  For example, for a JPEG image the first entry should
693      * be an RGB image, even though the image data is stored
694      * internally in a YCbCr color space.
695      *
696      * @param imageIndex the index of the image to be
697      * <code>retrieved</code>.
698      *
699      * @return an <code>Iterator</code> containing at least one
700      * <code>ImageTypeSpecifier</code> representing suggested image
701      * types for decoding the current given image.
702      *
703      * @exception IllegalStateException if the input source has not been set.
704      * @exception IndexOutOfBoundsException if the supplied index is
705      * out of bounds.
706      * @exception IOException if an error occurs reading the format
707      * information from the input source.
708      *
709      * @see ImageReadParam#setDestination(BufferedImage)
710      * @see ImageReadParam#setDestinationType(ImageTypeSpecifier)
711      */
712     public abstract Iterator<ImageTypeSpecifier>
713         getImageTypes(int imageIndex) throws IOException;
714 
715     /**
716      * Returns a default <code>ImageReadParam</code> object
717      * appropriate for this format.  All subclasses should define a
718      * set of default values for all parameters and return them with
719      * this call.  This method may be called before the input source
720      * is set.
721      *
722      * <p> The default implementation constructs and returns a new
723      * <code>ImageReadParam</code> object that does not allow source
724      * scaling (<i>i.e.</i>, it returns <code>new
725      * ImageReadParam()</code>.
726      *
727      * @return an <code>ImageReadParam</code> object which may be used
728      * to control the decoding process using a set of default settings.
729      */
730     public ImageReadParam getDefaultReadParam() {
731         return new ImageReadParam();
732     }
733 
734     /**
735      * Returns an <code>IIOMetadata</code> object representing the
736      * metadata associated with the input source as a whole (i.e., not
737      * associated with any particular image), or <code>null</code> if
738      * the reader does not support reading metadata, is set to ignore
739      * metadata, or if no metadata is available.
740      *
741      * @return an <code>IIOMetadata</code> object, or <code>null</code>.
742      *
743      * @exception IOException if an error occurs during reading.
744      */
745     public abstract IIOMetadata getStreamMetadata() throws IOException;
746 
747     /**
748      * Returns an <code>IIOMetadata</code> object representing the
749      * metadata associated with the input source as a whole (i.e.,
750      * not associated with any particular image).  If no such data
751      * exists, <code>null</code> is returned.
752      *
753      * <p> The resulting metadata object is only responsible for
754      * returning documents in the format named by
755      * <code>formatName</code>.  Within any documents that are
756      * returned, only nodes whose names are members of
757      * <code>nodeNames</code> are required to be returned.  In this
758      * way, the amount of metadata processing done by the reader may
759      * be kept to a minimum, based on what information is actually
760      * needed.
761      *
762      * <p> If <code>formatName</code> is not the name of a supported
763      * metadata format, <code>null</code> is returned.
764      *
765      * <p> In all cases, it is legal to return a more capable metadata
766      * object than strictly necessary.  The format name and node names
767      * are merely hints that may be used to reduce the reader's
768      * workload.
769      *
770      * <p> The default implementation simply returns the result of
771      * calling <code>getStreamMetadata()</code>, after checking that
772      * the format name is supported.  If it is not,
773      * <code>null</code> is returned.
774      *
775      * @param formatName a metadata format name that may be used to retrieve
776      * a document from the returned <code>IIOMetadata</code> object.
777      * @param nodeNames a <code>Set</code> containing the names of
778      * nodes that may be contained in a retrieved document.
779      *
780      * @return an <code>IIOMetadata</code> object, or <code>null</code>.
781      *
782      * @exception IllegalArgumentException if <code>formatName</code>
783      * is <code>null</code>.
784      * @exception IllegalArgumentException if <code>nodeNames</code>
785      * is <code>null</code>.
786      * @exception IOException if an error occurs during reading.
787      */
788     public IIOMetadata getStreamMetadata(String formatName,
789                                          Set<String> nodeNames)
790         throws IOException
791     {
792         return getMetadata(formatName, nodeNames, true, 0);
793     }
794 
795     private IIOMetadata getMetadata(String formatName,
796                                     Set nodeNames,
797                                     boolean wantStream,
798                                     int imageIndex) throws IOException {
799         if (formatName == null) {
800             throw new IllegalArgumentException("formatName == null!");
801         }
802         if (nodeNames == null) {
803             throw new IllegalArgumentException("nodeNames == null!");
804         }
805         IIOMetadata metadata =
806             wantStream
807             ? getStreamMetadata()
808             : getImageMetadata(imageIndex);
809         if (metadata != null) {
810             if (metadata.isStandardMetadataFormatSupported() &&
811                 formatName.equals
812                 (IIOMetadataFormatImpl.standardMetadataFormatName)) {
813                 return metadata;
814             }
815             String nativeName = metadata.getNativeMetadataFormatName();
816             if (nativeName != null && formatName.equals(nativeName)) {
817                 return metadata;
818             }
819             String[] extraNames = metadata.getExtraMetadataFormatNames();
820             if (extraNames != null) {
821                 for (int i = 0; i < extraNames.length; i++) {
822                     if (formatName.equals(extraNames[i])) {
823                         return metadata;
824                     }
825                 }
826             }
827         }
828         return null;
829     }
830 
831     /**
832      * Returns an <code>IIOMetadata</code> object containing metadata
833      * associated with the given image, or <code>null</code> if the
834      * reader does not support reading metadata, is set to ignore
835      * metadata, or if no metadata is available.
836      *
837      * @param imageIndex the index of the image whose metadata is to
838      * be retrieved.
839      *
840      * @return an <code>IIOMetadata</code> object, or
841      * <code>null</code>.
842      *
843      * @exception IllegalStateException if the input source has not been
844      * set.
845      * @exception IndexOutOfBoundsException if the supplied index is
846      * out of bounds.
847      * @exception IOException if an error occurs during reading.
848      */
849     public abstract IIOMetadata getImageMetadata(int imageIndex)
850         throws IOException;
851 
852     /**
853      * Returns an <code>IIOMetadata</code> object representing the
854      * metadata associated with the given image, or <code>null</code>
855      * if the reader does not support reading metadata or none
856      * is available.
857      *
858      * <p> The resulting metadata object is only responsible for
859      * returning documents in the format named by
860      * <code>formatName</code>.  Within any documents that are
861      * returned, only nodes whose names are members of
862      * <code>nodeNames</code> are required to be returned.  In this
863      * way, the amount of metadata processing done by the reader may
864      * be kept to a minimum, based on what information is actually
865      * needed.
866      *
867      * <p> If <code>formatName</code> is not the name of a supported
868      * metadata format, <code>null</code> may be returned.
869      *
870      * <p> In all cases, it is legal to return a more capable metadata
871      * object than strictly necessary.  The format name and node names
872      * are merely hints that may be used to reduce the reader's
873      * workload.
874      *
875      * <p> The default implementation simply returns the result of
876      * calling <code>getImageMetadata(imageIndex)</code>, after
877      * checking that the format name is supported.  If it is not,
878      * <code>null</code> is returned.
879      *
880      * @param imageIndex the index of the image whose metadata is to
881      * be retrieved.
882      * @param formatName a metadata format name that may be used to retrieve
883      * a document from the returned <code>IIOMetadata</code> object.
884      * @param nodeNames a <code>Set</code> containing the names of
885      * nodes that may be contained in a retrieved document.
886      *
887      * @return an <code>IIOMetadata</code> object, or <code>null</code>.
888      *
889      * @exception IllegalStateException if the input source has not been
890      * set.
891      * @exception IndexOutOfBoundsException if the supplied index is
892      * out of bounds.
893      * @exception IllegalArgumentException if <code>formatName</code>
894      * is <code>null</code>.
895      * @exception IllegalArgumentException if <code>nodeNames</code>
896      * is <code>null</code>.
897      * @exception IOException if an error occurs during reading.
898      */
899     public IIOMetadata getImageMetadata(int imageIndex,
900                                         String formatName,
901                                         Set<String> nodeNames)
902         throws IOException {
903         return getMetadata(formatName, nodeNames, false, imageIndex);
904     }
905 
906     /**
907      * Reads the image indexed by <code>imageIndex</code> and returns
908      * it as a complete <code>BufferedImage</code>, using a default
909      * <code>ImageReadParam</code>.  This is a convenience method
910      * that calls <code>read(imageIndex, null)</code>.
911      *
912      * <p> The image returned will be formatted according to the first
913      * <code>ImageTypeSpecifier</code> returned from
914      * <code>getImageTypes</code>.
915      *
916      * <p> Any registered <code>IIOReadProgressListener</code> objects
917      * will be notified by calling their <code>imageStarted</code>
918      * method, followed by calls to their <code>imageProgress</code>
919      * method as the read progresses.  Finally their
920      * <code>imageComplete</code> method will be called.
921      * <code>IIOReadUpdateListener</code> objects may be updated at
922      * other times during the read as pixels are decoded.  Finally,
923      * <code>IIOReadWarningListener</code> objects will receive
924      * notification of any non-fatal warnings that occur during
925      * decoding.
926      *
927      * @param imageIndex the index of the image to be retrieved.
928      *
929      * @return the desired portion of the image as a
930      * <code>BufferedImage</code>.
931      *
932      * @exception IllegalStateException if the input source has not been
933      * set.
934      * @exception IndexOutOfBoundsException if the supplied index is
935      * out of bounds.
936      * @exception IOException if an error occurs during reading.
937      */
938     public BufferedImage read(int imageIndex) throws IOException {
939         return read(imageIndex, null);
940     }
941 
942     /**
943      * Reads the image indexed by <code>imageIndex</code> and returns
944      * it as a complete <code>BufferedImage</code>, using a supplied
945      * <code>ImageReadParam</code>.
946      *
947      * <p> The actual <code>BufferedImage</code> returned will be
948      * chosen using the algorithm defined by the
949      * <code>getDestination</code> method.
950      *
951      * <p> Any registered <code>IIOReadProgressListener</code> objects
952      * will be notified by calling their <code>imageStarted</code>
953      * method, followed by calls to their <code>imageProgress</code>
954      * method as the read progresses.  Finally their
955      * <code>imageComplete</code> method will be called.
956      * <code>IIOReadUpdateListener</code> objects may be updated at
957      * other times during the read as pixels are decoded.  Finally,
958      * <code>IIOReadWarningListener</code> objects will receive
959      * notification of any non-fatal warnings that occur during
960      * decoding.
961      *
962      * <p> The set of source bands to be read and destination bands to
963      * be written is determined by calling <code>getSourceBands</code>
964      * and <code>getDestinationBands</code> on the supplied
965      * <code>ImageReadParam</code>.  If the lengths of the arrays
966      * returned by these methods differ, the set of source bands
967      * contains an index larger that the largest available source
968      * index, or the set of destination bands contains an index larger
969      * than the largest legal destination index, an
970      * <code>IllegalArgumentException</code> is thrown.
971      *
972      * <p> If the supplied <code>ImageReadParam</code> contains
973      * optional setting values not supported by this reader (<i>e.g.</i>
974      * source render size or any format-specific settings), they will
975      * be ignored.
976      *
977      * @param imageIndex the index of the image to be retrieved.
978      * @param param an <code>ImageReadParam</code> used to control
979      * the reading process, or <code>null</code>.
980      *
981      * @return the desired portion of the image as a
982      * <code>BufferedImage</code>.
983      *
984      * @exception IllegalStateException if the input source has not been
985      * set.
986      * @exception IndexOutOfBoundsException if the supplied index is
987      * out of bounds.
988      * @exception IllegalArgumentException if the set of source and
989      * destination bands specified by
990      * <code>param.getSourceBands</code> and
991      * <code>param.getDestinationBands</code> differ in length or
992      * include indices that are out of bounds.
993      * @exception IllegalArgumentException if the resulting image would
994      * have a width or height less than 1.
995      * @exception IOException if an error occurs during reading.
996      */
997     public abstract BufferedImage read(int imageIndex, ImageReadParam param)
998         throws IOException;
999 
1000     /**
1001      * Reads the image indexed by <code>imageIndex</code> and returns
1002      * an <code>IIOImage</code> containing the image, thumbnails, and
1003      * associated image metadata, using a supplied
1004      * <code>ImageReadParam</code>.
1005      *
1006      * <p> The actual <code>BufferedImage</code> referenced by the
1007      * returned <code>IIOImage</code> will be chosen using the
1008      * algorithm defined by the <code>getDestination</code> method.
1009      *
1010      * <p> Any registered <code>IIOReadProgressListener</code> objects
1011      * will be notified by calling their <code>imageStarted</code>
1012      * method, followed by calls to their <code>imageProgress</code>
1013      * method as the read progresses.  Finally their
1014      * <code>imageComplete</code> method will be called.
1015      * <code>IIOReadUpdateListener</code> objects may be updated at
1016      * other times during the read as pixels are decoded.  Finally,
1017      * <code>IIOReadWarningListener</code> objects will receive
1018      * notification of any non-fatal warnings that occur during
1019      * decoding.
1020      *
1021      * <p> The set of source bands to be read and destination bands to
1022      * be written is determined by calling <code>getSourceBands</code>
1023      * and <code>getDestinationBands</code> on the supplied
1024      * <code>ImageReadParam</code>.  If the lengths of the arrays
1025      * returned by these methods differ, the set of source bands
1026      * contains an index larger that the largest available source
1027      * index, or the set of destination bands contains an index larger
1028      * than the largest legal destination index, an
1029      * <code>IllegalArgumentException</code> is thrown.
1030      *
1031      * <p> Thumbnails will be returned in their entirety regardless of
1032      * the region settings.
1033      *
1034      * <p> If the supplied <code>ImageReadParam</code> contains
1035      * optional setting values not supported by this reader (<i>e.g.</i>
1036      * source render size or any format-specific settings), those
1037      * values will be ignored.
1038      *
1039      * @param imageIndex the index of the image to be retrieved.
1040      * @param param an <code>ImageReadParam</code> used to control
1041      * the reading process, or <code>null</code>.
1042      *
1043      * @return an <code>IIOImage</code> containing the desired portion
1044      * of the image, a set of thumbnails, and associated image
1045      * metadata.
1046      *
1047      * @exception IllegalStateException if the input source has not been
1048      * set.
1049      * @exception IndexOutOfBoundsException if the supplied index is
1050      * out of bounds.
1051      * @exception IllegalArgumentException if the set of source and
1052      * destination bands specified by
1053      * <code>param.getSourceBands</code> and
1054      * <code>param.getDestinationBands</code> differ in length or
1055      * include indices that are out of bounds.
1056      * @exception IllegalArgumentException if the resulting image
1057      * would have a width or height less than 1.
1058      * @exception IOException if an error occurs during reading.
1059      */
1060     public IIOImage readAll(int imageIndex, ImageReadParam param)
1061         throws IOException {
1062         if (imageIndex < getMinIndex()) {
1063             throw new IndexOutOfBoundsException("imageIndex < getMinIndex()!");
1064         }
1065 
1066         BufferedImage im = read(imageIndex, param);
1067 
1068         ArrayList thumbnails = null;
1069         int numThumbnails = getNumThumbnails(imageIndex);
1070         if (numThumbnails > 0) {
1071             thumbnails = new ArrayList();
1072             for (int j = 0; j < numThumbnails; j++) {
1073                 thumbnails.add(readThumbnail(imageIndex, j));
1074             }
1075         }
1076 
1077         IIOMetadata metadata = getImageMetadata(imageIndex);
1078         return new IIOImage(im, thumbnails, metadata);
1079     }
1080 
1081     /**
1082      * Returns an <code>Iterator</code> containing all the images,
1083      * thumbnails, and metadata, starting at the index given by
1084      * <code>getMinIndex</code>, from the input source in the form of
1085      * <code>IIOImage</code> objects.  An <code>Iterator</code>
1086      * containing <code>ImageReadParam</code> objects is supplied; one
1087      * element is consumed for each image read from the input source
1088      * until no more images are available.  If the read param
1089      * <code>Iterator</code> runs out of elements, but there are still
1090      * more images available from the input source, default read
1091      * params are used for the remaining images.
1092      *
1093      * <p> If <code>params</code> is <code>null</code>, a default read
1094      * param will be used for all images.
1095      *
1096      * <p> The actual <code>BufferedImage</code> referenced by the
1097      * returned <code>IIOImage</code> will be chosen using the
1098      * algorithm defined by the <code>getDestination</code> method.
1099      *
1100      * <p> Any registered <code>IIOReadProgressListener</code> objects
1101      * will be notified by calling their <code>sequenceStarted</code>
1102      * method once.  Then, for each image decoded, there will be a
1103      * call to <code>imageStarted</code>, followed by calls to
1104      * <code>imageProgress</code> as the read progresses, and finally
1105      * to <code>imageComplete</code>.  The
1106      * <code>sequenceComplete</code> method will be called after the
1107      * last image has been decoded.
1108      * <code>IIOReadUpdateListener</code> objects may be updated at
1109      * other times during the read as pixels are decoded.  Finally,
1110      * <code>IIOReadWarningListener</code> objects will receive
1111      * notification of any non-fatal warnings that occur during
1112      * decoding.
1113      *
1114      * <p> The set of source bands to be read and destination bands to
1115      * be written is determined by calling <code>getSourceBands</code>
1116      * and <code>getDestinationBands</code> on the supplied
1117      * <code>ImageReadParam</code>.  If the lengths of the arrays
1118      * returned by these methods differ, the set of source bands
1119      * contains an index larger that the largest available source
1120      * index, or the set of destination bands contains an index larger
1121      * than the largest legal destination index, an
1122      * <code>IllegalArgumentException</code> is thrown.
1123      *
1124      * <p> Thumbnails will be returned in their entirety regardless of the
1125      * region settings.
1126      *
1127      * <p> If any of the supplied <code>ImageReadParam</code>s contain
1128      * optional setting values not supported by this reader (<i>e.g.</i>
1129      * source render size or any format-specific settings), they will
1130      * be ignored.
1131      *
1132      * @param params an <code>Iterator</code> containing
1133      * <code>ImageReadParam</code> objects.
1134      *
1135      * @return an <code>Iterator</code> representing the
1136      * contents of the input source as <code>IIOImage</code>s.
1137      *
1138      * @exception IllegalStateException if the input source has not been
1139      * set.
1140      * @exception IllegalArgumentException if any
1141      * non-<code>null</code> element of <code>params</code> is not an
1142      * <code>ImageReadParam</code>.
1143      * @exception IllegalArgumentException if the set of source and
1144      * destination bands specified by
1145      * <code>param.getSourceBands</code> and
1146      * <code>param.getDestinationBands</code> differ in length or
1147      * include indices that are out of bounds.
1148      * @exception IllegalArgumentException if a resulting image would
1149      * have a width or height less than 1.
1150      * @exception IOException if an error occurs during reading.
1151      *
1152      * @see ImageReadParam
1153      * @see IIOImage
1154      */
1155     public Iterator<IIOImage>
1156         readAll(Iterator<? extends ImageReadParam> params)
1157         throws IOException
1158     {
1159         List output = new ArrayList();
1160 
1161         int imageIndex = getMinIndex();
1162 
1163         // Inform IIOReadProgressListeners we're starting a sequence
1164         processSequenceStarted(imageIndex);
1165 
1166         while (true) {
1167             // Inform IIOReadProgressListeners and IIOReadUpdateListeners
1168             // that we're starting a new image
1169 
1170             ImageReadParam param = null;
1171             if (params != null && params.hasNext()) {
1172                 Object o = params.next();
1173                 if (o != null) {
1174                     if (o instanceof ImageReadParam) {
1175                         param = (ImageReadParam)o;
1176                     } else {
1177                         throw new IllegalArgumentException
1178                             ("Non-ImageReadParam supplied as part of params!");
1179                     }
1180                 }
1181             }
1182 
1183             BufferedImage bi = null;
1184             try {
1185                 bi = read(imageIndex, param);
1186             } catch (IndexOutOfBoundsException e) {
1187                 break;
1188             }
1189 
1190             ArrayList thumbnails = null;
1191             int numThumbnails = getNumThumbnails(imageIndex);
1192             if (numThumbnails > 0) {
1193                 thumbnails = new ArrayList();
1194                 for (int j = 0; j < numThumbnails; j++) {
1195                     thumbnails.add(readThumbnail(imageIndex, j));
1196                 }
1197             }
1198 
1199             IIOMetadata metadata = getImageMetadata(imageIndex);
1200             IIOImage im = new IIOImage(bi, thumbnails, metadata);
1201             output.add(im);
1202 
1203             ++imageIndex;
1204         }
1205 
1206         // Inform IIOReadProgressListeners we're ending a sequence
1207         processSequenceComplete();
1208 
1209         return output.iterator();
1210     }
1211 
1212     /**
1213      * Returns <code>true</code> if this plug-in supports reading
1214      * just a {@link java.awt.image.Raster Raster} of pixel data.
1215      * If this method returns <code>false</code>, calls to
1216      * {@link #readRaster readRaster} or {@link #readTileRaster readTileRaster}
1217      * will throw an <code>UnsupportedOperationException</code>.
1218      *
1219      * <p> The default implementation returns <code>false</code>.
1220      *
1221      * @return <code>true</code> if this plug-in supports reading raw
1222      * <code>Raster</code>s.
1223      *
1224      * @see #readRaster
1225      * @see #readTileRaster
1226      */
1227     public boolean canReadRaster() {
1228         return false;
1229     }
1230 
1231     /**
1232      * Returns a new <code>Raster</code> object containing the raw pixel data
1233      * from the image stream, without any color conversion applied.  The
1234      * application must determine how to interpret the pixel data by other
1235      * means.  Any destination or image-type parameters in the supplied
1236      * <code>ImageReadParam</code> object are ignored, but all other
1237      * parameters are used exactly as in the {@link #read read}
1238      * method, except that any destination offset is used as a logical rather
1239      * than a physical offset.  The size of the returned <code>Raster</code>
1240      * will always be that of the source region clipped to the actual image.
1241      * Logical offsets in the stream itself are ignored.
1242      *
1243      * <p> This method allows formats that normally apply a color
1244      * conversion, such as JPEG, and formats that do not normally have an
1245      * associated colorspace, such as remote sensing or medical imaging data,
1246      * to provide access to raw pixel data.
1247      *
1248      * <p> Any registered <code>readUpdateListener</code>s are ignored, as
1249      * there is no <code>BufferedImage</code>, but all other listeners are
1250      * called exactly as they are for the {@link #read read} method.
1251      *
1252      * <p> If {@link #canReadRaster canReadRaster()} returns
1253      * <code>false</code>, this method throws an
1254      * <code>UnsupportedOperationException</code>.
1255      *
1256      * <p> If the supplied <code>ImageReadParam</code> contains
1257      * optional setting values not supported by this reader (<i>e.g.</i>
1258      * source render size or any format-specific settings), they will
1259      * be ignored.
1260      *
1261      * <p> The default implementation throws an
1262      * <code>UnsupportedOperationException</code>.
1263      *
1264      * @param imageIndex the index of the image to be read.
1265      * @param param an <code>ImageReadParam</code> used to control
1266      * the reading process, or <code>null</code>.
1267      *
1268      * @return the desired portion of the image as a
1269      * <code>Raster</code>.
1270      *
1271      * @exception UnsupportedOperationException if this plug-in does not
1272      * support reading raw <code>Raster</code>s.
1273      * @exception IllegalStateException if the input source has not been
1274      * set.
1275      * @exception IndexOutOfBoundsException if the supplied index is
1276      * out of bounds.
1277      * @exception IOException if an error occurs during reading.
1278      *
1279      * @see #canReadRaster
1280      * @see #read
1281      * @see java.awt.image.Raster
1282      */
1283     public Raster readRaster(int imageIndex, ImageReadParam param)
1284         throws IOException {
1285         throw new UnsupportedOperationException("readRaster not supported!");
1286     }
1287 
1288     /**
1289      * Returns <code>true</code> if the image is organized into
1290      * <i>tiles</i>, that is, equal-sized non-overlapping rectangles.
1291      *
1292      * <p> A reader plug-in may choose whether or not to expose tiling
1293      * that is present in the image as it is stored.  It may even
1294      * choose to advertise tiling when none is explicitly present.  In
1295      * general, tiling should only be advertised if there is some
1296      * advantage (in speed or space) to accessing individual tiles.
1297      * Regardless of whether the reader advertises tiling, it must be
1298      * capable of reading an arbitrary rectangular region specified in
1299      * an <code>ImageReadParam</code>.
1300      *
1301      * <p> A reader for which all images are guaranteed to be tiled,
1302      * or are guaranteed not to be tiled, may return <code>true</code>
1303      * or <code>false</code> respectively without accessing any image
1304      * data.  In such cases, it is not necessary to throw an exception
1305      * even if no input source has been set or the image index is out
1306      * of bounds.
1307      *
1308      * <p> The default implementation just returns <code>false</code>.
1309      *
1310      * @param imageIndex the index of the image to be queried.
1311      *
1312      * @return <code>true</code> if the image is tiled.
1313      *
1314      * @exception IllegalStateException if an input source is required
1315      * to determine the return value, but none has been set.
1316      * @exception IndexOutOfBoundsException if an image must be
1317      * accessed to determine the return value, but the supplied index
1318      * is out of bounds.
1319      * @exception IOException if an error occurs during reading.
1320      */
1321     public boolean isImageTiled(int imageIndex) throws IOException {
1322         return false;
1323     }
1324 
1325     /**
1326      * Returns the width of a tile in the given image.
1327      *
1328      * <p> The default implementation simply returns
1329      * <code>getWidth(imageIndex)</code>, which is correct for
1330      * non-tiled images.  Readers that support tiling should override
1331      * this method.
1332      *
1333      * @return the width of a tile.
1334      *
1335      * @param imageIndex the index of the image to be queried.
1336      *
1337      * @exception IllegalStateException if the input source has not been set.
1338      * @exception IndexOutOfBoundsException if the supplied index is
1339      * out of bounds.
1340      * @exception IOException if an error occurs during reading.
1341      */
1342     public int getTileWidth(int imageIndex) throws IOException {
1343         return getWidth(imageIndex);
1344     }
1345 
1346     /**
1347      * Returns the height of a tile in the given image.
1348      *
1349      * <p> The default implementation simply returns
1350      * <code>getHeight(imageIndex)</code>, which is correct for
1351      * non-tiled images.  Readers that support tiling should override
1352      * this method.
1353      *
1354      * @return the height of a tile.
1355      *
1356      * @param imageIndex the index of the image to be queried.
1357      *
1358      * @exception IllegalStateException if the input source has not been set.
1359      * @exception IndexOutOfBoundsException if the supplied index is
1360      * out of bounds.
1361      * @exception IOException if an error occurs during reading.
1362      */
1363     public int getTileHeight(int imageIndex) throws IOException {
1364         return getHeight(imageIndex);
1365     }
1366 
1367     /**
1368      * Returns the X coordinate of the upper-left corner of tile (0,
1369      * 0) in the given image.
1370      *
1371      * <p> A reader for which the tile grid X offset always has the
1372      * same value (usually 0), may return the value without accessing
1373      * any image data.  In such cases, it is not necessary to throw an
1374      * exception even if no input source has been set or the image
1375      * index is out of bounds.
1376      *
1377      * <p> The default implementation simply returns 0, which is
1378      * correct for non-tiled images and tiled images in most formats.
1379      * Readers that support tiling with non-(0, 0) offsets should
1380      * override this method.
1381      *
1382      * @return the X offset of the tile grid.
1383      *
1384      * @param imageIndex the index of the image to be queried.
1385      *
1386      * @exception IllegalStateException if an input source is required
1387      * to determine the return value, but none has been set.
1388      * @exception IndexOutOfBoundsException if an image must be
1389      * accessed to determine the return value, but the supplied index
1390      * is out of bounds.
1391      * @exception IOException if an error occurs during reading.
1392      */
1393     public int getTileGridXOffset(int imageIndex) throws IOException {
1394         return 0;
1395     }
1396 
1397     /**
1398      * Returns the Y coordinate of the upper-left corner of tile (0,
1399      * 0) in the given image.
1400      *
1401      * <p> A reader for which the tile grid Y offset always has the
1402      * same value (usually 0), may return the value without accessing
1403      * any image data.  In such cases, it is not necessary to throw an
1404      * exception even if no input source has been set or the image
1405      * index is out of bounds.
1406      *
1407      * <p> The default implementation simply returns 0, which is
1408      * correct for non-tiled images and tiled images in most formats.
1409      * Readers that support tiling with non-(0, 0) offsets should
1410      * override this method.
1411      *
1412      * @return the Y offset of the tile grid.
1413      *
1414      * @param imageIndex the index of the image to be queried.
1415      *
1416      * @exception IllegalStateException if an input source is required
1417      * to determine the return value, but none has been set.
1418      * @exception IndexOutOfBoundsException if an image must be
1419      * accessed to determine the return value, but the supplied index
1420      * is out of bounds.
1421      * @exception IOException if an error occurs during reading.
1422      */
1423     public int getTileGridYOffset(int imageIndex) throws IOException {
1424         return 0;
1425     }
1426 
1427     /**
1428      * Reads the tile indicated by the <code>tileX</code> and
1429      * <code>tileY</code> arguments, returning it as a
1430      * <code>BufferedImage</code>.  If the arguments are out of range,
1431      * an <code>IllegalArgumentException</code> is thrown.  If the
1432      * image is not tiled, the values 0, 0 will return the entire
1433      * image; any other values will cause an
1434      * <code>IllegalArgumentException</code> to be thrown.
1435      *
1436      * <p> This method is merely a convenience equivalent to calling
1437      * <code>read(int, ImageReadParam)</code> with a read param
1438      * specifying a source region having offsets of
1439      * <code>tileX*getTileWidth(imageIndex)</code>,
1440      * <code>tileY*getTileHeight(imageIndex)</code> and width and
1441      * height of <code>getTileWidth(imageIndex)</code>,
1442      * <code>getTileHeight(imageIndex)</code>; and subsampling
1443      * factors of 1 and offsets of 0.  To subsample a tile, call
1444      * <code>read</code> with a read param specifying this region
1445      * and different subsampling parameters.
1446      *
1447      * <p> The default implementation returns the entire image if
1448      * <code>tileX</code> and <code>tileY</code> are 0, or throws
1449      * an <code>IllegalArgumentException</code> otherwise.
1450      *
1451      * @param imageIndex the index of the image to be retrieved.
1452      * @param tileX the column index (starting with 0) of the tile
1453      * to be retrieved.
1454      * @param tileY the row index (starting with 0) of the tile
1455      * to be retrieved.
1456      *
1457      * @return the tile as a <code>BufferedImage</code>.
1458      *
1459      * @exception IllegalStateException if the input source has not been
1460      * set.
1461      * @exception IndexOutOfBoundsException if <code>imageIndex</code>
1462      * is out of bounds.
1463      * @exception IllegalArgumentException if the tile indices are
1464      * out of bounds.
1465      * @exception IOException if an error occurs during reading.
1466      */
1467     public BufferedImage readTile(int imageIndex,
1468                                   int tileX, int tileY) throws IOException {
1469         if ((tileX != 0) || (tileY != 0)) {
1470             throw new IllegalArgumentException("Invalid tile indices");
1471         }
1472         return read(imageIndex);
1473     }
1474 
1475     /**
1476      * Returns a new <code>Raster</code> object containing the raw
1477      * pixel data from the tile, without any color conversion applied.
1478      * The application must determine how to interpret the pixel data by other
1479      * means.
1480      *
1481      * <p> If {@link #canReadRaster canReadRaster()} returns
1482      * <code>false</code>, this method throws an
1483      * <code>UnsupportedOperationException</code>.
1484      *
1485      * <p> The default implementation checks if reading
1486      * <code>Raster</code>s is supported, and if so calls {@link
1487      * #readRaster readRaster(imageIndex, null)} if
1488      * <code>tileX</code> and <code>tileY</code> are 0, or throws an
1489      * <code>IllegalArgumentException</code> otherwise.
1490      *
1491      * @param imageIndex the index of the image to be retrieved.
1492      * @param tileX the column index (starting with 0) of the tile
1493      * to be retrieved.
1494      * @param tileY the row index (starting with 0) of the tile
1495      * to be retrieved.
1496      *
1497      * @return the tile as a <code>Raster</code>.
1498      *
1499      * @exception UnsupportedOperationException if this plug-in does not
1500      * support reading raw <code>Raster</code>s.
1501      * @exception IllegalArgumentException if the tile indices are
1502      * out of bounds.
1503      * @exception IllegalStateException if the input source has not been
1504      * set.
1505      * @exception IndexOutOfBoundsException if <code>imageIndex</code>
1506      * is out of bounds.
1507      * @exception IOException if an error occurs during reading.
1508      *
1509      * @see #readTile
1510      * @see #readRaster
1511      * @see java.awt.image.Raster
1512      */
1513     public Raster readTileRaster(int imageIndex,
1514                                  int tileX, int tileY) throws IOException {
1515         if (!canReadRaster()) {
1516             throw new UnsupportedOperationException
1517                 ("readTileRaster not supported!");
1518         }
1519         if ((tileX != 0) || (tileY != 0)) {
1520             throw new IllegalArgumentException("Invalid tile indices");
1521         }
1522         return readRaster(imageIndex, null);
1523     }
1524 
1525     // RenderedImages
1526 
1527     /**
1528      * Returns a <code>RenderedImage</code> object that contains the
1529      * contents of the image indexed by <code>imageIndex</code>.  By
1530      * default, the returned image is simply the
1531      * <code>BufferedImage</code> returned by <code>read(imageIndex,
1532      * param)</code>.
1533      *
1534      * <p> The semantics of this method may differ from those of the
1535      * other <code>read</code> methods in several ways.  First, any
1536      * destination image and/or image type set in the
1537      * <code>ImageReadParam</code> may be ignored.  Second, the usual
1538      * listener calls are not guaranteed to be made, or to be
1539      * meaningful if they are.  This is because the returned image may
1540      * not be fully populated with pixel data at the time it is
1541      * returned, or indeed at any time.
1542      *
1543      * <p> If the supplied <code>ImageReadParam</code> contains
1544      * optional setting values not supported by this reader (<i>e.g.</i>
1545      * source render size or any format-specific settings), they will
1546      * be ignored.
1547      *
1548      * <p> The default implementation just calls
1549      * {@link #read read(imageIndex, param)}.
1550      *
1551      * @param imageIndex the index of the image to be retrieved.
1552      * @param param an <code>ImageReadParam</code> used to control
1553      * the reading process, or <code>null</code>.
1554      *
1555      * @return a <code>RenderedImage</code> object providing a view of
1556      * the image.
1557      *
1558      * @exception IllegalStateException if the input source has not been
1559      * set.
1560      * @exception IndexOutOfBoundsException if the supplied index is
1561      * out of bounds.
1562      * @exception IllegalArgumentException if the set of source and
1563      * destination bands specified by
1564      * <code>param.getSourceBands</code> and
1565      * <code>param.getDestinationBands</code> differ in length or
1566      * include indices that are out of bounds.
1567      * @exception IllegalArgumentException if the resulting image
1568      * would have a width or height less than 1.
1569      * @exception IOException if an error occurs during reading.
1570      */
1571     public RenderedImage readAsRenderedImage(int imageIndex,
1572                                              ImageReadParam param)
1573         throws IOException {
1574         return read(imageIndex, param);
1575     }
1576 
1577     // Thumbnails
1578 
1579     /**
1580      * Returns <code>true</code> if the image format understood by
1581      * this reader supports thumbnail preview images associated with
1582      * it.  The default implementation returns <code>false</code>.
1583      *
1584      * <p> If this method returns <code>false</code>,
1585      * <code>hasThumbnails</code> and <code>getNumThumbnails</code>
1586      * will return <code>false</code> and <code>0</code>,
1587      * respectively, and <code>readThumbnail</code> will throw an
1588      * <code>UnsupportedOperationException</code>, regardless of their
1589      * arguments.
1590      *
1591      * <p> A reader that does not support thumbnails need not
1592      * implement any of the thumbnail-related methods.
1593      *
1594      * @return <code>true</code> if thumbnails are supported.
1595      */
1596     public boolean readerSupportsThumbnails() {
1597         return false;
1598     }
1599 
1600     /**
1601      * Returns <code>true</code> if the given image has thumbnail
1602      * preview images associated with it.  If the format does not
1603      * support thumbnails (<code>readerSupportsThumbnails</code>
1604      * returns <code>false</code>), <code>false</code> will be
1605      * returned regardless of whether an input source has been set or
1606      * whether <code>imageIndex</code> is in bounds.
1607      *
1608      * <p> The default implementation returns <code>true</code> if
1609      * <code>getNumThumbnails</code> returns a value greater than 0.
1610      *
1611      * @param imageIndex the index of the image being queried.
1612      *
1613      * @return <code>true</code> if the given image has thumbnails.
1614      *
1615      * @exception IllegalStateException if the reader supports
1616      * thumbnails but the input source has not been set.
1617      * @exception IndexOutOfBoundsException if the reader supports
1618      * thumbnails but <code>imageIndex</code> is out of bounds.
1619      * @exception IOException if an error occurs during reading.
1620      */
1621     public boolean hasThumbnails(int imageIndex) throws IOException {
1622         return getNumThumbnails(imageIndex) > 0;
1623     }
1624 
1625     /**
1626      * Returns the number of thumbnail preview images associated with
1627      * the given image.  If the format does not support thumbnails,
1628      * (<code>readerSupportsThumbnails</code> returns
1629      * <code>false</code>), <code>0</code> will be returned regardless
1630      * of whether an input source has been set or whether
1631      * <code>imageIndex</code> is in bounds.
1632      *
1633      * <p> The default implementation returns 0 without checking its
1634      * argument.
1635      *
1636      * @param imageIndex the index of the image being queried.
1637      *
1638      * @return the number of thumbnails associated with the given
1639      * image.
1640      *
1641      * @exception IllegalStateException if the reader supports
1642      * thumbnails but the input source has not been set.
1643      * @exception IndexOutOfBoundsException if the reader supports
1644      * thumbnails but <code>imageIndex</code> is out of bounds.
1645      * @exception IOException if an error occurs during reading.
1646      */
1647     public int getNumThumbnails(int imageIndex)
1648         throws IOException {
1649         return 0;
1650     }
1651 
1652     /**
1653      * Returns the width of the thumbnail preview image indexed by
1654      * <code>thumbnailIndex</code>, associated with the image indexed
1655      * by <code>ImageIndex</code>.
1656      *
1657      * <p> If the reader does not support thumbnails,
1658      * (<code>readerSupportsThumbnails</code> returns
1659      * <code>false</code>), an <code>UnsupportedOperationException</code>
1660      * will be thrown.
1661      *
1662      * <p> The default implementation simply returns
1663      * <code>readThumbnail(imageindex,
1664      * thumbnailIndex).getWidth()</code>.  Subclasses should therefore
1665      * override this method if possible in order to avoid forcing the
1666      * thumbnail to be read.
1667      *
1668      * @param imageIndex the index of the image to be retrieved.
1669      * @param thumbnailIndex the index of the thumbnail to be retrieved.
1670      *
1671      * @return the width of the desired thumbnail as an <code>int</code>.
1672      *
1673      * @exception UnsupportedOperationException if thumbnails are not
1674      * supported.
1675      * @exception IllegalStateException if the input source has not been set.
1676      * @exception IndexOutOfBoundsException if either of the supplied
1677      * indices are out of bounds.
1678      * @exception IOException if an error occurs during reading.
1679      */
1680     public int getThumbnailWidth(int imageIndex, int thumbnailIndex)
1681         throws IOException {
1682         return readThumbnail(imageIndex, thumbnailIndex).getWidth();
1683     }
1684 
1685     /**
1686      * Returns the height of the thumbnail preview image indexed by
1687      * <code>thumbnailIndex</code>, associated with the image indexed
1688      * by <code>ImageIndex</code>.
1689      *
1690      * <p> If the reader does not support thumbnails,
1691      * (<code>readerSupportsThumbnails</code> returns
1692      * <code>false</code>), an <code>UnsupportedOperationException</code>
1693      * will be thrown.
1694      *
1695      * <p> The default implementation simply returns
1696      * <code>readThumbnail(imageindex,
1697      * thumbnailIndex).getHeight()</code>.  Subclasses should
1698      * therefore override this method if possible in order to avoid
1699      * forcing the thumbnail to be read.
1700      *
1701      * @param imageIndex the index of the image to be retrieved.
1702      * @param thumbnailIndex the index of the thumbnail to be retrieved.
1703      *
1704      * @return the height of the desired thumbnail as an <code>int</code>.
1705      *
1706      * @exception UnsupportedOperationException if thumbnails are not
1707      * supported.
1708      * @exception IllegalStateException if the input source has not been set.
1709      * @exception IndexOutOfBoundsException if either of the supplied
1710      * indices are out of bounds.
1711      * @exception IOException if an error occurs during reading.
1712      */
1713     public int getThumbnailHeight(int imageIndex, int thumbnailIndex)
1714         throws IOException {
1715         return readThumbnail(imageIndex, thumbnailIndex).getHeight();
1716     }
1717 
1718     /**
1719      * Returns the thumbnail preview image indexed by
1720      * <code>thumbnailIndex</code>, associated with the image indexed
1721      * by <code>ImageIndex</code> as a <code>BufferedImage</code>.
1722      *
1723      * <p> Any registered <code>IIOReadProgressListener</code> objects
1724      * will be notified by calling their
1725      * <code>thumbnailStarted</code>, <code>thumbnailProgress</code>,
1726      * and <code>thumbnailComplete</code> methods.
1727      *
1728      * <p> If the reader does not support thumbnails,
1729      * (<code>readerSupportsThumbnails</code> returns
1730      * <code>false</code>), an <code>UnsupportedOperationException</code>
1731      * will be thrown regardless of whether an input source has been
1732      * set or whether the indices are in bounds.
1733      *
1734      * <p> The default implementation throws an
1735      * <code>UnsupportedOperationException</code>.
1736      *
1737      * @param imageIndex the index of the image to be retrieved.
1738      * @param thumbnailIndex the index of the thumbnail to be retrieved.
1739      *
1740      * @return the desired thumbnail as a <code>BufferedImage</code>.
1741      *
1742      * @exception UnsupportedOperationException if thumbnails are not
1743      * supported.
1744      * @exception IllegalStateException if the input source has not been set.
1745      * @exception IndexOutOfBoundsException if either of the supplied
1746      * indices are out of bounds.
1747      * @exception IOException if an error occurs during reading.
1748      */
1749     public BufferedImage readThumbnail(int imageIndex,
1750                                        int thumbnailIndex)
1751         throws IOException {
1752         throw new UnsupportedOperationException("Thumbnails not supported!");
1753     }
1754 
1755     // Abort
1756 
1757     /**
1758      * Requests that any current read operation be aborted.  The
1759      * contents of the image following the abort will be undefined.
1760      *
1761      * <p> Readers should call <code>clearAbortRequest</code> at the
1762      * beginning of each read operation, and poll the value of
1763      * <code>abortRequested</code> regularly during the read.
1764      */
1765     public synchronized void abort() {
1766         this.abortFlag = true;
1767     }
1768 
1769     /**
1770      * Returns <code>true</code> if a request to abort the current
1771      * read operation has been made since the reader was instantiated or
1772      * <code>clearAbortRequest</code> was called.
1773      *
1774      * @return <code>true</code> if the current read operation should
1775      * be aborted.
1776      *
1777      * @see #abort
1778      * @see #clearAbortRequest
1779      */
1780     protected synchronized boolean abortRequested() {
1781         return this.abortFlag;
1782     }
1783 
1784     /**
1785      * Clears any previous abort request.  After this method has been
1786      * called, <code>abortRequested</code> will return
1787      * <code>false</code>.
1788      *
1789      * @see #abort
1790      * @see #abortRequested
1791      */
1792     protected synchronized void clearAbortRequest() {
1793         this.abortFlag = false;
1794     }
1795 
1796     // Listeners
1797 
1798     // Add an element to a list, creating a new list if the
1799     // existing list is null, and return the list.
1800     static List addToList(List l, Object elt) {
1801         if (l == null) {
1802             l = new ArrayList();
1803         }
1804         l.add(elt);
1805         return l;
1806     }
1807 
1808 
1809     // Remove an element from a list, discarding the list if the
1810     // resulting list is empty, and return the list or null.
1811     static List removeFromList(List l, Object elt) {
1812         if (l == null) {
1813             return l;
1814         }
1815         l.remove(elt);
1816         if (l.size() == 0) {
1817             l = null;
1818         }
1819         return l;
1820     }
1821 
1822     /**
1823      * Adds an <code>IIOReadWarningListener</code> to the list of
1824      * registered warning listeners.  If <code>listener</code> is
1825      * <code>null</code>, no exception will be thrown and no action
1826      * will be taken.  Messages sent to the given listener will be
1827      * localized, if possible, to match the current
1828      * <code>Locale</code>.  If no <code>Locale</code> has been set,
1829      * warning messages may be localized as the reader sees fit.
1830      *
1831      * @param listener an <code>IIOReadWarningListener</code> to be registered.
1832      *
1833      * @see #removeIIOReadWarningListener
1834      */
1835     public void addIIOReadWarningListener(IIOReadWarningListener listener) {
1836         if (listener == null) {
1837             return;
1838         }
1839         warningListeners = addToList(warningListeners, listener);
1840         warningLocales = addToList(warningLocales, getLocale());
1841     }
1842 
1843     /**
1844      * Removes an <code>IIOReadWarningListener</code> from the list of
1845      * registered error listeners.  If the listener was not previously
1846      * registered, or if <code>listener</code> is <code>null</code>,
1847      * no exception will be thrown and no action will be taken.
1848      *
1849      * @param listener an IIOReadWarningListener to be unregistered.
1850      *
1851      * @see #addIIOReadWarningListener
1852      */
1853     public void removeIIOReadWarningListener(IIOReadWarningListener listener) {
1854         if (listener == null || warningListeners == null) {
1855             return;
1856         }
1857         int index = warningListeners.indexOf(listener);
1858         if (index != -1) {
1859             warningListeners.remove(index);
1860             warningLocales.remove(index);
1861             if (warningListeners.size() == 0) {
1862                 warningListeners = null;
1863                 warningLocales = null;
1864             }
1865         }
1866     }
1867 
1868     /**
1869      * Removes all currently registered
1870      * <code>IIOReadWarningListener</code> objects.
1871      *
1872      * <p> The default implementation sets the
1873      * <code>warningListeners</code> and <code>warningLocales</code>
1874      * instance variables to <code>null</code>.
1875      */
1876     public void removeAllIIOReadWarningListeners() {
1877         warningListeners = null;
1878         warningLocales = null;
1879     }
1880 
1881     /**
1882      * Adds an <code>IIOReadProgressListener</code> to the list of
1883      * registered progress listeners.  If <code>listener</code> is
1884      * <code>null</code>, no exception will be thrown and no action
1885      * will be taken.
1886      *
1887      * @param listener an IIOReadProgressListener to be registered.
1888      *
1889      * @see #removeIIOReadProgressListener
1890      */
1891     public void addIIOReadProgressListener(IIOReadProgressListener listener) {
1892         if (listener == null) {
1893             return;
1894         }
1895         progressListeners = addToList(progressListeners, listener);
1896     }
1897 
1898     /**
1899      * Removes an <code>IIOReadProgressListener</code> from the list
1900      * of registered progress listeners.  If the listener was not
1901      * previously registered, or if <code>listener</code> is
1902      * <code>null</code>, no exception will be thrown and no action
1903      * will be taken.
1904      *
1905      * @param listener an IIOReadProgressListener to be unregistered.
1906      *
1907      * @see #addIIOReadProgressListener
1908      */
1909     public void
1910         removeIIOReadProgressListener (IIOReadProgressListener listener) {
1911         if (listener == null || progressListeners == null) {
1912             return;
1913         }
1914         progressListeners = removeFromList(progressListeners, listener);
1915     }
1916 
1917     /**
1918      * Removes all currently registered
1919      * <code>IIOReadProgressListener</code> objects.
1920      *
1921      * <p> The default implementation sets the
1922      * <code>progressListeners</code> instance variable to
1923      * <code>null</code>.
1924      */
1925     public void removeAllIIOReadProgressListeners() {
1926         progressListeners = null;
1927     }
1928 
1929     /**
1930      * Adds an <code>IIOReadUpdateListener</code> to the list of
1931      * registered update listeners.  If <code>listener</code> is
1932      * <code>null</code>, no exception will be thrown and no action
1933      * will be taken.  The listener will receive notification of pixel
1934      * updates as images and thumbnails are decoded, including the
1935      * starts and ends of progressive passes.
1936      *
1937      * <p> If no update listeners are present, the reader may choose
1938      * to perform fewer updates to the pixels of the destination
1939      * images and/or thumbnails, which may result in more efficient
1940      * decoding.
1941      *
1942      * <p> For example, in progressive JPEG decoding each pass
1943      * contains updates to a set of coefficients, which would have to
1944      * be transformed into pixel values and converted to an RGB color
1945      * space for each pass if listeners are present.  If no listeners
1946      * are present, the coefficients may simply be accumulated and the
1947      * final results transformed and color converted one time only.
1948      *
1949      * <p> The final results of decoding will be the same whether or
1950      * not intermediate updates are performed.  Thus if only the final
1951      * image is desired it may be preferable not to register any
1952      * <code>IIOReadUpdateListener</code>s.  In general, progressive
1953      * updating is most effective when fetching images over a network
1954      * connection that is very slow compared to local CPU processing;
1955      * over a fast connection, progressive updates may actually slow
1956      * down the presentation of the image.
1957      *
1958      * @param listener an IIOReadUpdateListener to be registered.
1959      *
1960      * @see #removeIIOReadUpdateListener
1961      */
1962     public void
1963         addIIOReadUpdateListener(IIOReadUpdateListener listener) {
1964         if (listener == null) {
1965             return;
1966         }
1967         updateListeners = addToList(updateListeners, listener);
1968     }
1969 
1970     /**
1971      * Removes an <code>IIOReadUpdateListener</code> from the list of
1972      * registered update listeners.  If the listener was not
1973      * previously registered, or if <code>listener</code> is
1974      * <code>null</code>, no exception will be thrown and no action
1975      * will be taken.
1976      *
1977      * @param listener an IIOReadUpdateListener to be unregistered.
1978      *
1979      * @see #addIIOReadUpdateListener
1980      */
1981     public void removeIIOReadUpdateListener(IIOReadUpdateListener listener) {
1982         if (listener == null || updateListeners == null) {
1983             return;
1984         }
1985         updateListeners = removeFromList(updateListeners, listener);
1986     }
1987 
1988     /**
1989      * Removes all currently registered
1990      * <code>IIOReadUpdateListener</code> objects.
1991      *
1992      * <p> The default implementation sets the
1993      * <code>updateListeners</code> instance variable to
1994      * <code>null</code>.
1995      */
1996     public void removeAllIIOReadUpdateListeners() {
1997         updateListeners = null;
1998     }
1999 
2000     /**
2001      * Broadcasts the start of an sequence of image reads to all
2002      * registered <code>IIOReadProgressListener</code>s by calling
2003      * their <code>sequenceStarted</code> method.  Subclasses may use
2004      * this method as a convenience.
2005      *
2006      * @param minIndex the lowest index being read.
2007      */
2008     protected void processSequenceStarted(int minIndex) {
2009         if (progressListeners == null) {
2010             return;
2011         }
2012         int numListeners = progressListeners.size();
2013         for (int i = 0; i < numListeners; i++) {
2014             IIOReadProgressListener listener =
2015                 (IIOReadProgressListener)progressListeners.get(i);
2016             listener.sequenceStarted(this, minIndex);
2017         }
2018     }
2019 
2020     /**
2021      * Broadcasts the completion of an sequence of image reads to all
2022      * registered <code>IIOReadProgressListener</code>s by calling
2023      * their <code>sequenceComplete</code> method.  Subclasses may use
2024      * this method as a convenience.
2025      */
2026     protected void processSequenceComplete() {
2027         if (progressListeners == null) {
2028             return;
2029         }
2030         int numListeners = progressListeners.size();
2031         for (int i = 0; i < numListeners; i++) {
2032             IIOReadProgressListener listener =
2033                 (IIOReadProgressListener)progressListeners.get(i);
2034             listener.sequenceComplete(this);
2035         }
2036     }
2037 
2038     /**
2039      * Broadcasts the start of an image read to all registered
2040      * <code>IIOReadProgressListener</code>s by calling their
2041      * <code>imageStarted</code> method.  Subclasses may use this
2042      * method as a convenience.
2043      *
2044      * @param imageIndex the index of the image about to be read.
2045      */
2046     protected void processImageStarted(int imageIndex) {
2047         if (progressListeners == null) {
2048             return;
2049         }
2050         int numListeners = progressListeners.size();
2051         for (int i = 0; i < numListeners; i++) {
2052             IIOReadProgressListener listener =
2053                 (IIOReadProgressListener)progressListeners.get(i);
2054             listener.imageStarted(this, imageIndex);
2055         }
2056     }
2057 
2058     /**
2059      * Broadcasts the current percentage of image completion to all
2060      * registered <code>IIOReadProgressListener</code>s by calling
2061      * their <code>imageProgress</code> method.  Subclasses may use
2062      * this method as a convenience.
2063      *
2064      * @param percentageDone the current percentage of completion,
2065      * as a <code>float</code>.
2066      */
2067     protected void processImageProgress(float percentageDone) {
2068         if (progressListeners == null) {
2069             return;
2070         }
2071         int numListeners = progressListeners.size();
2072         for (int i = 0; i < numListeners; i++) {
2073             IIOReadProgressListener listener =
2074                 (IIOReadProgressListener)progressListeners.get(i);
2075             listener.imageProgress(this, percentageDone);
2076         }
2077     }
2078 
2079     /**
2080      * Broadcasts the completion of an image read to all registered
2081      * <code>IIOReadProgressListener</code>s by calling their
2082      * <code>imageComplete</code> method.  Subclasses may use this
2083      * method as a convenience.
2084      */
2085     protected void processImageComplete() {
2086         if (progressListeners == null) {
2087             return;
2088         }
2089         int numListeners = progressListeners.size();
2090         for (int i = 0; i < numListeners; i++) {
2091             IIOReadProgressListener listener =
2092                 (IIOReadProgressListener)progressListeners.get(i);
2093             listener.imageComplete(this);
2094         }
2095     }
2096 
2097     /**
2098      * Broadcasts the start of a thumbnail read to all registered
2099      * <code>IIOReadProgressListener</code>s by calling their
2100      * <code>thumbnailStarted</code> method.  Subclasses may use this
2101      * method as a convenience.
2102      *
2103      * @param imageIndex the index of the image associated with the
2104      * thumbnail.
2105      * @param thumbnailIndex the index of the thumbnail.
2106      */
2107     protected void processThumbnailStarted(int imageIndex,
2108                                            int thumbnailIndex) {
2109         if (progressListeners == null) {
2110             return;
2111         }
2112         int numListeners = progressListeners.size();
2113         for (int i = 0; i < numListeners; i++) {
2114             IIOReadProgressListener listener =
2115                 (IIOReadProgressListener)progressListeners.get(i);
2116             listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
2117         }
2118     }
2119 
2120     /**
2121      * Broadcasts the current percentage of thumbnail completion to
2122      * all registered <code>IIOReadProgressListener</code>s by calling
2123      * their <code>thumbnailProgress</code> method.  Subclasses may
2124      * use this method as a convenience.
2125      *
2126      * @param percentageDone the current percentage of completion,
2127      * as a <code>float</code>.
2128      */
2129     protected void processThumbnailProgress(float percentageDone) {
2130         if (progressListeners == null) {
2131             return;
2132         }
2133         int numListeners = progressListeners.size();
2134         for (int i = 0; i < numListeners; i++) {
2135             IIOReadProgressListener listener =
2136                 (IIOReadProgressListener)progressListeners.get(i);
2137             listener.thumbnailProgress(this, percentageDone);
2138         }
2139     }
2140 
2141     /**
2142      * Broadcasts the completion of a thumbnail read to all registered
2143      * <code>IIOReadProgressListener</code>s by calling their
2144      * <code>thumbnailComplete</code> method.  Subclasses may use this
2145      * method as a convenience.
2146      */
2147     protected void processThumbnailComplete() {
2148         if (progressListeners == null) {
2149             return;
2150         }
2151         int numListeners = progressListeners.size();
2152         for (int i = 0; i < numListeners; i++) {
2153             IIOReadProgressListener listener =
2154                 (IIOReadProgressListener)progressListeners.get(i);
2155             listener.thumbnailComplete(this);
2156         }
2157     }
2158 
2159     /**
2160      * Broadcasts that the read has been aborted to all registered
2161      * <code>IIOReadProgressListener</code>s by calling their
2162      * <code>readAborted</code> method.  Subclasses may use this
2163      * method as a convenience.
2164      */
2165     protected void processReadAborted() {
2166         if (progressListeners == null) {
2167             return;
2168         }
2169         int numListeners = progressListeners.size();
2170         for (int i = 0; i < numListeners; i++) {
2171             IIOReadProgressListener listener =
2172                 (IIOReadProgressListener)progressListeners.get(i);
2173             listener.readAborted(this);
2174         }
2175     }
2176 
2177     /**
2178      * Broadcasts the beginning of a progressive pass to all
2179      * registered <code>IIOReadUpdateListener</code>s by calling their
2180      * <code>passStarted</code> method.  Subclasses may use this
2181      * method as a convenience.
2182      *
2183      * @param theImage the <code>BufferedImage</code> being updated.
2184      * @param pass the index of the current pass, starting with 0.
2185      * @param minPass the index of the first pass that will be decoded.
2186      * @param maxPass the index of the last pass that will be decoded.
2187      * @param minX the X coordinate of the upper-left pixel included
2188      * in the pass.
2189      * @param minY the X coordinate of the upper-left pixel included
2190      * in the pass.
2191      * @param periodX the horizontal separation between pixels.
2192      * @param periodY the vertical separation between pixels.
2193      * @param bands an array of <code>int</code>s indicating the
2194      * set of affected bands of the destination.
2195      */
2196     protected void processPassStarted(BufferedImage theImage,
2197                                       int pass,
2198                                       int minPass, int maxPass,
2199                                       int minX, int minY,
2200                                       int periodX, int periodY,
2201                                       int[] bands) {
2202         if (updateListeners == null) {
2203             return;
2204         }
2205         int numListeners = updateListeners.size();
2206         for (int i = 0; i < numListeners; i++) {
2207             IIOReadUpdateListener listener =
2208                 (IIOReadUpdateListener)updateListeners.get(i);
2209             listener.passStarted(this, theImage, pass,
2210                                  minPass,
2211                                  maxPass,
2212                                  minX, minY,
2213                                  periodX, periodY,
2214                                  bands);
2215         }
2216     }
2217 
2218     /**
2219      * Broadcasts the update of a set of samples to all registered
2220      * <code>IIOReadUpdateListener</code>s by calling their
2221      * <code>imageUpdate</code> method.  Subclasses may use this
2222      * method as a convenience.
2223      *
2224      * @param theImage the <code>BufferedImage</code> being updated.
2225      * @param minX the X coordinate of the upper-left pixel included
2226      * in the pass.
2227      * @param minY the X coordinate of the upper-left pixel included
2228      * in the pass.
2229      * @param width the total width of the area being updated, including
2230      * pixels being skipped if <code>periodX &gt; 1</code>.
2231      * @param height the total height of the area being updated,
2232      * including pixels being skipped if <code>periodY &gt; 1</code>.
2233      * @param periodX the horizontal separation between pixels.
2234      * @param periodY the vertical separation between pixels.
2235      * @param bands an array of <code>int</code>s indicating the
2236      * set of affected bands of the destination.
2237      */
2238     protected void processImageUpdate(BufferedImage theImage,
2239                                       int minX, int minY,
2240                                       int width, int height,
2241                                       int periodX, int periodY,
2242                                       int[] bands) {
2243         if (updateListeners == null) {
2244             return;
2245         }
2246         int numListeners = updateListeners.size();
2247         for (int i = 0; i < numListeners; i++) {
2248             IIOReadUpdateListener listener =
2249                 (IIOReadUpdateListener)updateListeners.get(i);
2250             listener.imageUpdate(this,
2251                                  theImage,
2252                                  minX, minY,
2253                                  width, height,
2254                                  periodX, periodY,
2255                                  bands);
2256         }
2257     }
2258 
2259     /**
2260      * Broadcasts the end of a progressive pass to all
2261      * registered <code>IIOReadUpdateListener</code>s by calling their
2262      * <code>passComplete</code> method.  Subclasses may use this
2263      * method as a convenience.
2264      *
2265      * @param theImage the <code>BufferedImage</code> being updated.
2266      */
2267     protected void processPassComplete(BufferedImage theImage) {
2268         if (updateListeners == null) {
2269             return;
2270         }
2271         int numListeners = updateListeners.size();
2272         for (int i = 0; i < numListeners; i++) {
2273             IIOReadUpdateListener listener =
2274                 (IIOReadUpdateListener)updateListeners.get(i);
2275             listener.passComplete(this, theImage);
2276         }
2277     }
2278 
2279     /**
2280      * Broadcasts the beginning of a thumbnail progressive pass to all
2281      * registered <code>IIOReadUpdateListener</code>s by calling their
2282      * <code>thumbnailPassStarted</code> method.  Subclasses may use this
2283      * method as a convenience.
2284      *
2285      * @param theThumbnail the <code>BufferedImage</code> thumbnail
2286      * being updated.
2287      * @param pass the index of the current pass, starting with 0.
2288      * @param minPass the index of the first pass that will be decoded.
2289      * @param maxPass the index of the last pass that will be decoded.
2290      * @param minX the X coordinate of the upper-left pixel included
2291      * in the pass.
2292      * @param minY the X coordinate of the upper-left pixel included
2293      * in the pass.
2294      * @param periodX the horizontal separation between pixels.
2295      * @param periodY the vertical separation between pixels.
2296      * @param bands an array of <code>int</code>s indicating the
2297      * set of affected bands of the destination.
2298      */
2299     protected void processThumbnailPassStarted(BufferedImage theThumbnail,
2300                                                int pass,
2301                                                int minPass, int maxPass,
2302                                                int minX, int minY,
2303                                                int periodX, int periodY,
2304                                                int[] bands) {
2305         if (updateListeners == null) {
2306             return;
2307         }
2308         int numListeners = updateListeners.size();
2309         for (int i = 0; i < numListeners; i++) {
2310             IIOReadUpdateListener listener =
2311                 (IIOReadUpdateListener)updateListeners.get(i);
2312             listener.thumbnailPassStarted(this, theThumbnail, pass,
2313                                           minPass,
2314                                           maxPass,
2315                                           minX, minY,
2316                                           periodX, periodY,
2317                                           bands);
2318         }
2319     }
2320 
2321     /**
2322      * Broadcasts the update of a set of samples in a thumbnail image
2323      * to all registered <code>IIOReadUpdateListener</code>s by
2324      * calling their <code>thumbnailUpdate</code> method.  Subclasses may
2325      * use this method as a convenience.
2326      *
2327      * @param theThumbnail the <code>BufferedImage</code> thumbnail
2328      * being updated.
2329      * @param minX the X coordinate of the upper-left pixel included
2330      * in the pass.
2331      * @param minY the X coordinate of the upper-left pixel included
2332      * in the pass.
2333      * @param width the total width of the area being updated, including
2334      * pixels being skipped if <code>periodX &gt; 1</code>.
2335      * @param height the total height of the area being updated,
2336      * including pixels being skipped if <code>periodY &gt; 1</code>.
2337      * @param periodX the horizontal separation between pixels.
2338      * @param periodY the vertical separation between pixels.
2339      * @param bands an array of <code>int</code>s indicating the
2340      * set of affected bands of the destination.
2341      */
2342     protected void processThumbnailUpdate(BufferedImage theThumbnail,
2343                                           int minX, int minY,
2344                                           int width, int height,
2345                                           int periodX, int periodY,
2346                                           int[] bands) {
2347         if (updateListeners == null) {
2348             return;
2349         }
2350         int numListeners = updateListeners.size();
2351         for (int i = 0; i < numListeners; i++) {
2352             IIOReadUpdateListener listener =
2353                 (IIOReadUpdateListener)updateListeners.get(i);
2354             listener.thumbnailUpdate(this,
2355                                      theThumbnail,
2356                                      minX, minY,
2357                                      width, height,
2358                                      periodX, periodY,
2359                                      bands);
2360         }
2361     }
2362 
2363     /**
2364      * Broadcasts the end of a thumbnail progressive pass to all
2365      * registered <code>IIOReadUpdateListener</code>s by calling their
2366      * <code>thumbnailPassComplete</code> method.  Subclasses may use this
2367      * method as a convenience.
2368      *
2369      * @param theThumbnail the <code>BufferedImage</code> thumbnail
2370      * being updated.
2371      */
2372     protected void processThumbnailPassComplete(BufferedImage theThumbnail) {
2373         if (updateListeners == null) {
2374             return;
2375         }
2376         int numListeners = updateListeners.size();
2377         for (int i = 0; i < numListeners; i++) {
2378             IIOReadUpdateListener listener =
2379                 (IIOReadUpdateListener)updateListeners.get(i);
2380             listener.thumbnailPassComplete(this, theThumbnail);
2381         }
2382     }
2383 
2384     /**
2385      * Broadcasts a warning message to all registered
2386      * <code>IIOReadWarningListener</code>s by calling their
2387      * <code>warningOccurred</code> method.  Subclasses may use this
2388      * method as a convenience.
2389      *
2390      * @param warning the warning message to send.
2391      *
2392      * @exception IllegalArgumentException if <code>warning</code>
2393      * is <code>null</code>.
2394      */
2395     protected void processWarningOccurred(String warning) {
2396         if (warningListeners == null) {
2397             return;
2398         }
2399         if (warning == null) {
2400             throw new IllegalArgumentException("warning == null!");
2401         }
2402         int numListeners = warningListeners.size();
2403         for (int i = 0; i < numListeners; i++) {
2404             IIOReadWarningListener listener =
2405                 (IIOReadWarningListener)warningListeners.get(i);
2406 
2407             listener.warningOccurred(this, warning);
2408         }
2409     }
2410 
2411     /**
2412      * Broadcasts a localized warning message to all registered
2413      * <code>IIOReadWarningListener</code>s by calling their
2414      * <code>warningOccurred</code> method with a string taken
2415      * from a <code>ResourceBundle</code>.  Subclasses may use this
2416      * method as a convenience.
2417      *
2418      * @param baseName the base name of a set of
2419      * <code>ResourceBundle</code>s containing localized warning
2420      * messages.
2421      * @param keyword the keyword used to index the warning message
2422      * within the set of <code>ResourceBundle</code>s.
2423      *
2424      * @exception IllegalArgumentException if <code>baseName</code>
2425      * is <code>null</code>.
2426      * @exception IllegalArgumentException if <code>keyword</code>
2427      * is <code>null</code>.
2428      * @exception IllegalArgumentException if no appropriate
2429      * <code>ResourceBundle</code> may be located.
2430      * @exception IllegalArgumentException if the named resource is
2431      * not found in the located <code>ResourceBundle</code>.
2432      * @exception IllegalArgumentException if the object retrieved
2433      * from the <code>ResourceBundle</code> is not a
2434      * <code>String</code>.
2435      */
2436     protected void processWarningOccurred(String baseName,
2437                                           String keyword) {
2438         if (warningListeners == null) {
2439             return;
2440         }
2441         if (baseName == null) {
2442             throw new IllegalArgumentException("baseName == null!");
2443         }
2444         if (keyword == null) {
2445             throw new IllegalArgumentException("keyword == null!");
2446         }
2447         int numListeners = warningListeners.size();
2448         for (int i = 0; i < numListeners; i++) {
2449             IIOReadWarningListener listener =
2450                 (IIOReadWarningListener)warningListeners.get(i);
2451             Locale locale = (Locale)warningLocales.get(i);
2452             if (locale == null) {
2453                 locale = Locale.getDefault();
2454             }
2455 
2456             /**
2457              * If an applet supplies an implementation of ImageReader and
2458              * resource bundles, then the resource bundle will need to be
2459              * accessed via the applet class loader. So first try the context
2460              * class loader to locate the resource bundle.
2461              * If that throws MissingResourceException, then try the
2462              * system class loader.
2463              */
2464             ClassLoader loader = (ClassLoader)
2465                 java.security.AccessController.doPrivileged(
2466                    new java.security.PrivilegedAction() {
2467                       public Object run() {
2468                         return Thread.currentThread().getContextClassLoader();
2469                       }
2470                 });
2471 
2472             ResourceBundle bundle = null;
2473             try {
2474                 bundle = ResourceBundle.getBundle(baseName, locale, loader);
2475             } catch (MissingResourceException mre) {
2476                 try {
2477                     bundle = ResourceBundle.getBundle(baseName, locale);
2478                 } catch (MissingResourceException mre1) {
2479                     throw new IllegalArgumentException("Bundle not found!");
2480                 }
2481             }
2482 
2483             String warning = null;
2484             try {
2485                 warning = bundle.getString(keyword);
2486             } catch (ClassCastException cce) {
2487                 throw new IllegalArgumentException("Resource is not a String!");
2488             } catch (MissingResourceException mre) {
2489                 throw new IllegalArgumentException("Resource is missing!");
2490             }
2491 
2492             listener.warningOccurred(this, warning);
2493         }
2494     }
2495 
2496     // State management
2497 
2498     /**
2499      * Restores the <code>ImageReader</code> to its initial state.
2500      *
2501      * <p> The default implementation calls <code>setInput(null,
2502      * false)</code>, <code>setLocale(null)</code>,
2503      * <code>removeAllIIOReadUpdateListeners()</code>,
2504      * <code>removeAllIIOReadWarningListeners()</code>,
2505      * <code>removeAllIIOReadProgressListeners()</code>, and
2506      * <code>clearAbortRequest</code>.
2507      */
2508     public void reset() {
2509         setInput(null, false, false);
2510         setLocale(null);
2511         removeAllIIOReadUpdateListeners();
2512         removeAllIIOReadProgressListeners();
2513         removeAllIIOReadWarningListeners();
2514         clearAbortRequest();
2515     }
2516 
2517     /**
2518      * Allows any resources held by this object to be released.  The
2519      * result of calling any other method (other than
2520      * <code>finalize</code>) subsequent to a call to this method
2521      * is undefined.
2522      *
2523      * <p>It is important for applications to call this method when they
2524      * know they will no longer be using this <code>ImageReader</code>.
2525      * Otherwise, the reader may continue to hold on to resources
2526      * indefinitely.
2527      *
2528      * <p>The default implementation of this method in the superclass does
2529      * nothing.  Subclass implementations should ensure that all resources,
2530      * especially native resources, are released.
2531      */
2532     public void dispose() {
2533     }
2534 
2535     // Utility methods
2536 
2537     /**
2538      * A utility method that may be used by readers to compute the
2539      * region of the source image that should be read, taking into
2540      * account any source region and subsampling offset settings in
2541      * the supplied <code>ImageReadParam</code>.  The actual
2542      * subsampling factors, destination size, and destination offset
2543      * are <em>not</em> taken into consideration, thus further
2544      * clipping must take place.  The {@link #computeRegions computeRegions}
2545      * method performs all necessary clipping.
2546      *
2547      * @param param the <code>ImageReadParam</code> being used, or
2548      * <code>null</code>.
2549      * @param srcWidth the width of the source image.
2550      * @param srcHeight the height of the source image.
2551      *
2552      * @return the source region as a <code>Rectangle</code>.
2553      */
2554     protected static Rectangle getSourceRegion(ImageReadParam param,
2555                                                int srcWidth,
2556                                                int srcHeight) {
2557         Rectangle sourceRegion = new Rectangle(0, 0, srcWidth, srcHeight);
2558         if (param != null) {
2559             Rectangle region = param.getSourceRegion();
2560             if (region != null) {
2561                 sourceRegion = sourceRegion.intersection(region);
2562             }
2563 
2564             int subsampleXOffset = param.getSubsamplingXOffset();
2565             int subsampleYOffset = param.getSubsamplingYOffset();
2566             sourceRegion.x += subsampleXOffset;
2567             sourceRegion.y += subsampleYOffset;
2568             sourceRegion.width -= subsampleXOffset;
2569             sourceRegion.height -= subsampleYOffset;
2570         }
2571 
2572         return sourceRegion;
2573     }
2574 
2575     /**
2576      * Computes the source region of interest and the destination
2577      * region of interest, taking the width and height of the source
2578      * image, an optional destination image, and an optional
2579      * <code>ImageReadParam</code> into account.  The source region
2580      * begins with the entire source image.  Then that is clipped to
2581      * the source region specified in the <code>ImageReadParam</code>,
2582      * if one is specified.
2583      *
2584      * <p> If either of the destination offsets are negative, the
2585      * source region is clipped so that its top left will coincide
2586      * with the top left of the destination image, taking subsampling
2587      * into account.  Then the result is clipped to the destination
2588      * image on the right and bottom, if one is specified, taking
2589      * subsampling and destination offsets into account.
2590      *
2591      * <p> Similarly, the destination region begins with the source
2592      * image, is translated to the destination offset given in the
2593      * <code>ImageReadParam</code> if there is one, and finally is
2594      * clipped to the destination image, if there is one.
2595      *
2596      * <p> If either the source or destination regions end up having a
2597      * width or height of 0, an <code>IllegalArgumentException</code>
2598      * is thrown.
2599      *
2600      * <p> The {@link #getSourceRegion getSourceRegion>}
2601      * method may be used if only source clipping is desired.
2602      *
2603      * @param param an <code>ImageReadParam</code>, or <code>null</code>.
2604      * @param srcWidth the width of the source image.
2605      * @param srcHeight the height of the source image.
2606      * @param image a <code>BufferedImage</code> that will be the
2607      * destination image, or <code>null</code>.
2608      * @param srcRegion a <code>Rectangle</code> that will be filled with
2609      * the source region of interest.
2610      * @param destRegion a <code>Rectangle</code> that will be filled with
2611      * the destination region of interest.
2612      * @exception IllegalArgumentException if <code>srcRegion</code>
2613      * is <code>null</code>.
2614      * @exception IllegalArgumentException if <code>dstRegion</code>
2615      * is <code>null</code>.
2616      * @exception IllegalArgumentException if the resulting source or
2617      * destination region is empty.
2618      */
2619     protected static void computeRegions(ImageReadParam param,
2620                                          int srcWidth,
2621                                          int srcHeight,
2622                                          BufferedImage image,
2623                                          Rectangle srcRegion,
2624                                          Rectangle destRegion) {
2625         if (srcRegion == null) {
2626             throw new IllegalArgumentException("srcRegion == null!");
2627         }
2628         if (destRegion == null) {
2629             throw new IllegalArgumentException("destRegion == null!");
2630         }
2631 
2632         // Start with the entire source image
2633         srcRegion.setBounds(0, 0, srcWidth, srcHeight);
2634 
2635         // Destination also starts with source image, as that is the
2636         // maximum extent if there is no subsampling
2637         destRegion.setBounds(0, 0, srcWidth, srcHeight);
2638 
2639         // Clip that to the param region, if there is one
2640         int periodX = 1;
2641         int periodY = 1;
2642         int gridX = 0;
2643         int gridY = 0;
2644         if (param != null) {
2645             Rectangle paramSrcRegion = param.getSourceRegion();
2646             if (paramSrcRegion != null) {
2647                 srcRegion.setBounds(srcRegion.intersection(paramSrcRegion));
2648             }
2649             periodX = param.getSourceXSubsampling();
2650             periodY = param.getSourceYSubsampling();
2651             gridX = param.getSubsamplingXOffset();
2652             gridY = param.getSubsamplingYOffset();
2653             srcRegion.translate(gridX, gridY);
2654             srcRegion.width -= gridX;
2655             srcRegion.height -= gridY;
2656             destRegion.setLocation(param.getDestinationOffset());
2657         }
2658 
2659         // Now clip any negative destination offsets, i.e. clip
2660         // to the top and left of the destination image
2661         if (destRegion.x < 0) {
2662             int delta = -destRegion.x*periodX;
2663             srcRegion.x += delta;
2664             srcRegion.width -= delta;
2665             destRegion.x = 0;
2666         }
2667         if (destRegion.y < 0) {
2668             int delta = -destRegion.y*periodY;
2669             srcRegion.y += delta;
2670             srcRegion.height -= delta;
2671             destRegion.y = 0;
2672         }
2673 
2674         // Now clip the destination Region to the subsampled width and height
2675         int subsampledWidth = (srcRegion.width + periodX - 1)/periodX;
2676         int subsampledHeight = (srcRegion.height + periodY - 1)/periodY;
2677         destRegion.width = subsampledWidth;
2678         destRegion.height = subsampledHeight;
2679 
2680         // Now clip that to right and bottom of the destination image,
2681         // if there is one, taking subsampling into account
2682         if (image != null) {
2683             Rectangle destImageRect = new Rectangle(0, 0,
2684                                                     image.getWidth(),
2685                                                     image.getHeight());
2686             destRegion.setBounds(destRegion.intersection(destImageRect));
2687             if (destRegion.isEmpty()) {
2688                 throw new IllegalArgumentException
2689                     ("Empty destination region!");
2690             }
2691 
2692             int deltaX = destRegion.x + subsampledWidth - image.getWidth();
2693             if (deltaX > 0) {
2694                 srcRegion.width -= deltaX*periodX;
2695             }
2696             int deltaY =  destRegion.y + subsampledHeight - image.getHeight();
2697             if (deltaY > 0) {
2698                 srcRegion.height -= deltaY*periodY;
2699             }
2700         }
2701         if (srcRegion.isEmpty() || destRegion.isEmpty()) {
2702             throw new IllegalArgumentException("Empty region!");
2703         }
2704     }
2705 
2706     /**
2707      * A utility method that may be used by readers to test the
2708      * validity of the source and destination band settings of an
2709      * <code>ImageReadParam</code>.  This method may be called as soon
2710      * as the reader knows both the number of bands of the source
2711      * image as it exists in the input stream, and the number of bands
2712      * of the destination image that being written.
2713      *
2714      * <p> The method retrieves the source and destination band
2715      * setting arrays from param using the <code>getSourceBands</code>
2716      * and <code>getDestinationBands</code>methods (or considers them
2717      * to be <code>null</code> if <code>param</code> is
2718      * <code>null</code>).  If the source band setting array is
2719      * <code>null</code>, it is considered to be equal to the array
2720      * <code>{ 0, 1, ..., numSrcBands - 1 }</code>, and similarly for
2721      * the destination band setting array.
2722      *
2723      * <p> The method then tests that both arrays are equal in length,
2724      * and that neither array contains a value larger than the largest
2725      * available band index.
2726      *
2727      * <p> Any failure results in an
2728      * <code>IllegalArgumentException</code> being thrown; success
2729      * results in the method returning silently.
2730      *
2731      * @param param the <code>ImageReadParam</code> being used to read
2732      * the image.
2733      * @param numSrcBands the number of bands of the image as it exists
2734      * int the input source.
2735      * @param numDstBands the number of bands in the destination image
2736      * being written.
2737      *
2738      * @exception IllegalArgumentException if <code>param</code>
2739      * contains an invalid specification of a source and/or
2740      * destination band subset.
2741      */
2742     protected static void checkReadParamBandSettings(ImageReadParam param,
2743                                                      int numSrcBands,
2744                                                      int numDstBands) {
2745         // A null param is equivalent to srcBands == dstBands == null.
2746         int[] srcBands = null;
2747         int[] dstBands = null;
2748         if (param != null) {
2749             srcBands = param.getSourceBands();
2750             dstBands = param.getDestinationBands();
2751         }
2752 
2753         int paramSrcBandLength =
2754             (srcBands == null) ? numSrcBands : srcBands.length;
2755         int paramDstBandLength =
2756             (dstBands == null) ? numDstBands : dstBands.length;
2757 
2758         if (paramSrcBandLength != paramDstBandLength) {
2759             throw new IllegalArgumentException("ImageReadParam num source & dest bands differ!");
2760         }
2761 
2762         if (srcBands != null) {
2763             for (int i = 0; i < srcBands.length; i++) {
2764                 if (srcBands[i] >= numSrcBands) {
2765                     throw new IllegalArgumentException("ImageReadParam source bands contains a value >= the number of source bands!");
2766                 }
2767             }
2768         }
2769 
2770         if (dstBands != null) {
2771             for (int i = 0; i < dstBands.length; i++) {
2772                 if (dstBands[i] >= numDstBands) {
2773                     throw new IllegalArgumentException("ImageReadParam dest bands contains a value >= the number of dest bands!");
2774                 }
2775             }
2776         }
2777     }
2778 
2779     /**
2780      * Returns the <code>BufferedImage</code> to which decoded pixel
2781      * data should be written.  The image is determined by inspecting
2782      * the supplied <code>ImageReadParam</code> if it is
2783      * non-<code>null</code>; if its <code>getDestination</code>
2784      * method returns a non-<code>null</code> value, that image is
2785      * simply returned.  Otherwise,
2786      * <code>param.getDestinationType</code> method is called to
2787      * determine if a particular image type has been specified.  If
2788      * so, the returned <code>ImageTypeSpecifier</code> is used after
2789      * checking that it is equal to one of those included in
2790      * <code>imageTypes</code>.
2791      *
2792      * <p> If <code>param</code> is <code>null</code> or the above
2793      * steps have not yielded an image or an
2794      * <code>ImageTypeSpecifier</code>, the first value obtained from
2795      * the <code>imageTypes</code> parameter is used.  Typically, the
2796      * caller will set <code>imageTypes</code> to the value of
2797      * <code>getImageTypes(imageIndex)</code>.
2798      *
2799      * <p> Next, the dimensions of the image are determined by a call
2800      * to <code>computeRegions</code>.  The actual width and height of
2801      * the image being decoded are passed in as the <code>width</code>
2802      * and <code>height</code> parameters.
2803      *
2804      * @param param an <code>ImageReadParam</code> to be used to get
2805      * the destination image or image type, or <code>null</code>.
2806      * @param imageTypes an <code>Iterator</code> of
2807      * <code>ImageTypeSpecifier</code>s indicating the legal image
2808      * types, with the default first.
2809      * @param width the true width of the image or tile begin decoded.
2810      * @param height the true width of the image or tile being decoded.
2811      *
2812      * @return the <code>BufferedImage</code> to which decoded pixel
2813      * data should be written.
2814      *
2815      * @exception IIOException if the <code>ImageTypeSpecifier</code>
2816      * specified by <code>param</code> does not match any of the legal
2817      * ones from <code>imageTypes</code>.
2818      * @exception IllegalArgumentException if <code>imageTypes</code>
2819      * is <code>null</code> or empty, or if an object not of type
2820      * <code>ImageTypeSpecifier</code> is retrieved from it.
2821      * @exception IllegalArgumentException if the resulting image would
2822      * have a width or height less than 1.
2823      * @exception IllegalArgumentException if the product of
2824      * <code>width</code> and <code>height</code> is greater than
2825      * <code>Integer.MAX_VALUE</code>.
2826      */
2827     protected static BufferedImage
2828         getDestination(ImageReadParam param,
2829                        Iterator<ImageTypeSpecifier> imageTypes,
2830                        int width, int height)
2831         throws IIOException {
2832         if (imageTypes == null || !imageTypes.hasNext()) {
2833             throw new IllegalArgumentException("imageTypes null or empty!");
2834         }
2835         if ((long)width*height > Integer.MAX_VALUE) {
2836             throw new IllegalArgumentException
2837                 ("width*height > Integer.MAX_VALUE!");
2838         }
2839 
2840         BufferedImage dest = null;
2841         ImageTypeSpecifier imageType = null;
2842 
2843         // If param is non-null, use it
2844         if (param != null) {
2845             // Try to get the image itself
2846             dest = param.getDestination();
2847             if (dest != null) {
2848                 return dest;
2849             }
2850 
2851             // No image, get the image type
2852             imageType = param.getDestinationType();
2853         }
2854 
2855         // No info from param, use fallback image type
2856         if (imageType == null) {
2857             Object o = imageTypes.next();
2858             if (!(o instanceof ImageTypeSpecifier)) {
2859                 throw new IllegalArgumentException
2860                     ("Non-ImageTypeSpecifier retrieved from imageTypes!");
2861             }
2862             imageType = (ImageTypeSpecifier)o;
2863         } else {
2864             boolean foundIt = false;
2865             while (imageTypes.hasNext()) {
2866                 ImageTypeSpecifier type =
2867                     (ImageTypeSpecifier)imageTypes.next();
2868                 if (type.equals(imageType)) {
2869                     foundIt = true;
2870                     break;
2871                 }
2872             }
2873 
2874             if (!foundIt) {
2875                 throw new IIOException
2876                     ("Destination type from ImageReadParam does not match!");
2877             }
2878         }
2879 
2880         Rectangle srcRegion = new Rectangle(0,0,0,0);
2881         Rectangle destRegion = new Rectangle(0,0,0,0);
2882         computeRegions(param,
2883                        width,
2884                        height,
2885                        null,
2886                        srcRegion,
2887                        destRegion);
2888 
2889         int destWidth = destRegion.x + destRegion.width;
2890         int destHeight = destRegion.y + destRegion.height;
2891         // Create a new image based on the type specifier
2892         return imageType.createBufferedImage(destWidth, destHeight);
2893     }
2894 }