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