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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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>
 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      */
 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      */
 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      */
 787     public IIOMetadata getStreamMetadata(String formatName,
 788                                          Set<String> nodeNames)
 789         throws IOException
 790     {
 791         return getMetadata(formatName, nodeNames, true, 0);
 792     }
 793 
 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      */
 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      */
 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      */
 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      */
 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      */
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>
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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.
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.
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      */
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      */
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      */
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      */
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
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      */
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
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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!");
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!");
2472             } catch (MissingResourceException mre) {
2473                 throw new IllegalArgumentException("Resource is missing!");
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      */
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      */
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      */
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      */
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      */
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
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 }