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