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