Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/imageio/ImageReader.java
38829 views
/*1* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.imageio;2627import java.awt.Point;28import java.awt.Rectangle;29import java.awt.image.BufferedImage;30import java.awt.image.Raster;31import java.awt.image.RenderedImage;32import java.io.IOException;33import java.util.ArrayList;34import java.util.Iterator;35import java.util.List;36import java.util.Locale;37import java.util.MissingResourceException;38import java.util.ResourceBundle;39import java.util.Set;40import javax.imageio.spi.ImageReaderSpi;41import javax.imageio.event.IIOReadWarningListener;42import javax.imageio.event.IIOReadProgressListener;43import javax.imageio.event.IIOReadUpdateListener;44import javax.imageio.metadata.IIOMetadata;45import javax.imageio.metadata.IIOMetadataFormatImpl;46import javax.imageio.stream.ImageInputStream;4748/**49* An abstract superclass for parsing and decoding of images. This50* class must be subclassed by classes that read in images in the51* context of the Java Image I/O framework.52*53* <p> <code>ImageReader</code> objects are normally instantiated by54* the service provider interface (SPI) class for the specific format.55* Service provider classes (e.g., instances of56* <code>ImageReaderSpi</code>) are registered with the57* <code>IIORegistry</code>, which uses them for format recognition58* and presentation of available format readers and writers.59*60* <p> When an input source is set (using the <code>setInput</code>61* method), it may be marked as "seek forward only". This setting62* means that images contained within the input source will only be63* read in order, possibly allowing the reader to avoid caching64* portions of the input containing data associated with images that65* have been read previously.66*67* @see ImageWriter68* @see javax.imageio.spi.IIORegistry69* @see javax.imageio.spi.ImageReaderSpi70*71*/72public abstract class ImageReader {7374/**75* The <code>ImageReaderSpi</code> that instantiated this object,76* or <code>null</code> if its identity is not known or none77* exists. By default it is initialized to <code>null</code>.78*/79protected ImageReaderSpi originatingProvider;8081/**82* The <code>ImageInputStream</code> or other83* <code>Object</code> by <code>setInput</code> and retrieved84* by <code>getInput</code>. By default it is initialized to85* <code>null</code>.86*/87protected Object input = null;8889/**90* <code>true</code> if the current input source has been marked91* as allowing only forward seeking by <code>setInput</code>. By92* default, the value is <code>false</code>.93*94* @see #minIndex95* @see #setInput96*/97protected boolean seekForwardOnly = false;9899/**100* <code>true</code> if the current input source has been marked101* as allowing metadata to be ignored by <code>setInput</code>.102* By default, the value is <code>false</code>.103*104* @see #setInput105*/106protected boolean ignoreMetadata = false;107108/**109* The smallest valid index for reading, initially 0. When110* <code>seekForwardOnly</code> is <code>true</code>, various methods111* may throw an <code>IndexOutOfBoundsException</code> on an112* attempt to access data associate with an image having a lower113* index.114*115* @see #seekForwardOnly116* @see #setInput117*/118protected int minIndex = 0;119120/**121* An array of <code>Locale</code>s which may be used to localize122* warning messages, or <code>null</code> if localization is not123* supported.124*/125protected Locale[] availableLocales = null;126127/**128* The current <code>Locale</code> to be used for localization, or129* <code>null</code> if none has been set.130*/131protected Locale locale = null;132133/**134* A <code>List</code> of currently registered135* <code>IIOReadWarningListener</code>s, initialized by default to136* <code>null</code>, which is synonymous with an empty137* <code>List</code>.138*/139protected List<IIOReadWarningListener> warningListeners = null;140141/**142* A <code>List</code> of the <code>Locale</code>s associated with143* each currently registered <code>IIOReadWarningListener</code>,144* initialized by default to <code>null</code>, which is145* synonymous with an empty <code>List</code>.146*/147protected List<Locale> warningLocales = null;148149/**150* A <code>List</code> of currently registered151* <code>IIOReadProgressListener</code>s, initialized by default152* to <code>null</code>, which is synonymous with an empty153* <code>List</code>.154*/155protected List<IIOReadProgressListener> progressListeners = null;156157/**158* A <code>List</code> of currently registered159* <code>IIOReadUpdateListener</code>s, initialized by default to160* <code>null</code>, which is synonymous with an empty161* <code>List</code>.162*/163protected List<IIOReadUpdateListener> updateListeners = null;164165/**166* If <code>true</code>, the current read operation should be167* aborted.168*/169private boolean abortFlag = false;170171/**172* Constructs an <code>ImageReader</code> and sets its173* <code>originatingProvider</code> field to the supplied value.174*175* <p> Subclasses that make use of extensions should provide a176* constructor with signature <code>(ImageReaderSpi,177* Object)</code> in order to retrieve the extension object. If178* the extension object is unsuitable, an179* <code>IllegalArgumentException</code> should be thrown.180*181* @param originatingProvider the <code>ImageReaderSpi</code> that is182* invoking this constructor, or <code>null</code>.183*/184protected ImageReader(ImageReaderSpi originatingProvider) {185this.originatingProvider = originatingProvider;186}187188/**189* Returns a <code>String</code> identifying the format of the190* input source.191*192* <p> The default implementation returns193* <code>originatingProvider.getFormatNames()[0]</code>.194* Implementations that may not have an originating service195* provider, or which desire a different naming policy should196* override this method.197*198* @exception IOException if an error occurs reading the199* information from the input source.200*201* @return the format name, as a <code>String</code>.202*/203public String getFormatName() throws IOException {204return originatingProvider.getFormatNames()[0];205}206207/**208* Returns the <code>ImageReaderSpi</code> that was passed in on209* the constructor. Note that this value may be <code>null</code>.210*211* @return an <code>ImageReaderSpi</code>, or <code>null</code>.212*213* @see ImageReaderSpi214*/215public ImageReaderSpi getOriginatingProvider() {216return originatingProvider;217}218219/**220* Sets the input source to use to the given221* <code>ImageInputStream</code> or other <code>Object</code>.222* The input source must be set before any of the query or read223* methods are used. If <code>input</code> is <code>null</code>,224* any currently set input source will be removed. In any case,225* the value of <code>minIndex</code> will be initialized to 0.226*227* <p> The <code>seekForwardOnly</code> parameter controls whether228* the value returned by <code>getMinIndex</code> will be229* increased as each image (or thumbnail, or image metadata) is230* read. If <code>seekForwardOnly</code> is true, then a call to231* <code>read(index)</code> will throw an232* <code>IndexOutOfBoundsException</code> if {@code index < this.minIndex};233* otherwise, the value of234* <code>minIndex</code> will be set to <code>index</code>. If235* <code>seekForwardOnly</code> is <code>false</code>, the value of236* <code>minIndex</code> will remain 0 regardless of any read237* operations.238*239* <p> The <code>ignoreMetadata</code> parameter, if set to240* <code>true</code>, allows the reader to disregard any metadata241* encountered during the read. Subsequent calls to the242* <code>getStreamMetadata</code> and243* <code>getImageMetadata</code> methods may return244* <code>null</code>, and an <code>IIOImage</code> returned from245* <code>readAll</code> may return <code>null</code> from their246* <code>getMetadata</code> method. Setting this parameter may247* allow the reader to work more efficiently. The reader may248* choose to disregard this setting and return metadata normally.249*250* <p> Subclasses should take care to remove any cached251* information based on the previous stream, such as header252* information or partially decoded image data.253*254* <p> Use of a general <code>Object</code> other than an255* <code>ImageInputStream</code> is intended for readers that256* interact directly with a capture device or imaging protocol.257* The set of legal classes is advertised by the reader's service258* provider's <code>getInputTypes</code> method; most readers259* will return a single-element array containing only260* <code>ImageInputStream.class</code> to indicate that they261* accept only an <code>ImageInputStream</code>.262*263* <p> The default implementation checks the <code>input</code>264* argument against the list returned by265* <code>originatingProvider.getInputTypes()</code> and fails266* if the argument is not an instance of one of the classes267* in the list. If the originating provider is set to268* <code>null</code>, the input is accepted only if it is an269* <code>ImageInputStream</code>.270*271* @param input the <code>ImageInputStream</code> or other272* <code>Object</code> to use for future decoding.273* @param seekForwardOnly if <code>true</code>, images and metadata274* may only be read in ascending order from this input source.275* @param ignoreMetadata if <code>true</code>, metadata276* may be ignored during reads.277*278* @exception IllegalArgumentException if <code>input</code> is279* not an instance of one of the classes returned by the280* originating service provider's <code>getInputTypes</code>281* method, or is not an <code>ImageInputStream</code>.282*283* @see ImageInputStream284* @see #getInput285* @see javax.imageio.spi.ImageReaderSpi#getInputTypes286*/287public void setInput(Object input,288boolean seekForwardOnly,289boolean ignoreMetadata) {290if (input != null) {291boolean found = false;292if (originatingProvider != null) {293Class[] classes = originatingProvider.getInputTypes();294for (int i = 0; i < classes.length; i++) {295if (classes[i].isInstance(input)) {296found = true;297break;298}299}300} else {301if (input instanceof ImageInputStream) {302found = true;303}304}305if (!found) {306throw new IllegalArgumentException("Incorrect input type!");307}308309this.seekForwardOnly = seekForwardOnly;310this.ignoreMetadata = ignoreMetadata;311this.minIndex = 0;312}313314this.input = input;315}316317/**318* Sets the input source to use to the given319* <code>ImageInputStream</code> or other <code>Object</code>.320* The input source must be set before any of the query or read321* methods are used. If <code>input</code> is <code>null</code>,322* any currently set input source will be removed. In any case,323* the value of <code>minIndex</code> will be initialized to 0.324*325* <p> The <code>seekForwardOnly</code> parameter controls whether326* the value returned by <code>getMinIndex</code> will be327* increased as each image (or thumbnail, or image metadata) is328* read. If <code>seekForwardOnly</code> is true, then a call to329* <code>read(index)</code> will throw an330* <code>IndexOutOfBoundsException</code> if {@code index < this.minIndex};331* otherwise, the value of332* <code>minIndex</code> will be set to <code>index</code>. If333* <code>seekForwardOnly</code> is <code>false</code>, the value of334* <code>minIndex</code> will remain 0 regardless of any read335* operations.336*337* <p> This method is equivalent to <code>setInput(input,338* seekForwardOnly, false)</code>.339*340* @param input the <code>ImageInputStream</code> or other341* <code>Object</code> to use for future decoding.342* @param seekForwardOnly if <code>true</code>, images and metadata343* may only be read in ascending order from this input source.344*345* @exception IllegalArgumentException if <code>input</code> is346* not an instance of one of the classes returned by the347* originating service provider's <code>getInputTypes</code>348* method, or is not an <code>ImageInputStream</code>.349*350* @see #getInput351*/352public void setInput(Object input,353boolean seekForwardOnly) {354setInput(input, seekForwardOnly, false);355}356357/**358* Sets the input source to use to the given359* <code>ImageInputStream</code> or other <code>Object</code>.360* The input source must be set before any of the query or read361* methods are used. If <code>input</code> is <code>null</code>,362* any currently set input source will be removed. In any case,363* the value of <code>minIndex</code> will be initialized to 0.364*365* <p> This method is equivalent to <code>setInput(input, false,366* false)</code>.367*368* @param input the <code>ImageInputStream</code> or other369* <code>Object</code> to use for future decoding.370*371* @exception IllegalArgumentException if <code>input</code> is372* not an instance of one of the classes returned by the373* originating service provider's <code>getInputTypes</code>374* method, or is not an <code>ImageInputStream</code>.375*376* @see #getInput377*/378public void setInput(Object input) {379setInput(input, false, false);380}381382/**383* Returns the <code>ImageInputStream</code> or other384* <code>Object</code> previously set as the input source. If the385* input source has not been set, <code>null</code> is returned.386*387* @return the <code>Object</code> that will be used for future388* decoding, or <code>null</code>.389*390* @see ImageInputStream391* @see #setInput392*/393public Object getInput() {394return input;395}396397/**398* Returns <code>true</code> if the current input source has been399* marked as seek forward only by passing <code>true</code> as the400* <code>seekForwardOnly</code> argument to the401* <code>setInput</code> method.402*403* @return <code>true</code> if the input source is seek forward404* only.405*406* @see #setInput407*/408public boolean isSeekForwardOnly() {409return seekForwardOnly;410}411412/**413* Returns <code>true</code> if the current input source has been414* marked as allowing metadata to be ignored by passing415* <code>true</code> as the <code>ignoreMetadata</code> argument416* to the <code>setInput</code> method.417*418* @return <code>true</code> if the metadata may be ignored.419*420* @see #setInput421*/422public boolean isIgnoringMetadata() {423return ignoreMetadata;424}425426/**427* Returns the lowest valid index for reading an image, thumbnail,428* or image metadata. If <code>seekForwardOnly()</code> is429* <code>false</code>, this value will typically remain 0,430* indicating that random access is possible. Otherwise, it will431* contain the value of the most recently accessed index, and432* increase in a monotonic fashion.433*434* @return the minimum legal index for reading.435*/436public int getMinIndex() {437return minIndex;438}439440// Localization441442/**443* Returns an array of <code>Locale</code>s that may be used to444* localize warning listeners and compression settings. A return445* value of <code>null</code> indicates that localization is not446* supported.447*448* <p> The default implementation returns a clone of the449* <code>availableLocales</code> instance variable if it is450* non-<code>null</code>, or else returns <code>null</code>.451*452* @return an array of <code>Locale</code>s that may be used as453* arguments to <code>setLocale</code>, or <code>null</code>.454*/455public Locale[] getAvailableLocales() {456if (availableLocales == null) {457return null;458} else {459return (Locale[])availableLocales.clone();460}461}462463/**464* Sets the current <code>Locale</code> of this465* <code>ImageReader</code> to the given value. A value of466* <code>null</code> removes any previous setting, and indicates467* that the reader should localize as it sees fit.468*469* @param locale the desired <code>Locale</code>, or470* <code>null</code>.471*472* @exception IllegalArgumentException if <code>locale</code> is473* non-<code>null</code> but is not one of the values returned by474* <code>getAvailableLocales</code>.475*476* @see #getLocale477*/478public void setLocale(Locale locale) {479if (locale != null) {480Locale[] locales = getAvailableLocales();481boolean found = false;482if (locales != null) {483for (int i = 0; i < locales.length; i++) {484if (locale.equals(locales[i])) {485found = true;486break;487}488}489}490if (!found) {491throw new IllegalArgumentException("Invalid locale!");492}493}494this.locale = locale;495}496497/**498* Returns the currently set <code>Locale</code>, or499* <code>null</code> if none has been set.500*501* @return the current <code>Locale</code>, or <code>null</code>.502*503* @see #setLocale504*/505public Locale getLocale() {506return locale;507}508509// Image queries510511/**512* Returns the number of images, not including thumbnails, available513* from the current input source.514*515* <p> Note that some image formats (such as animated GIF) do not516* specify how many images are present in the stream. Thus517* determining the number of images will require the entire stream518* to be scanned and may require memory for buffering. If images519* are to be processed in order, it may be more efficient to520* simply call <code>read</code> with increasing indices until an521* <code>IndexOutOfBoundsException</code> is thrown to indicate522* that no more images are available. The523* <code>allowSearch</code> parameter may be set to524* <code>false</code> to indicate that an exhaustive search is not525* desired; the return value will be <code>-1</code> to indicate526* that a search is necessary. If the input has been specified527* with <code>seekForwardOnly</code> set to <code>true</code>,528* this method throws an <code>IllegalStateException</code> if529* <code>allowSearch</code> is set to <code>true</code>.530*531* @param allowSearch if <code>true</code>, the true number of532* images will be returned even if a search is required. If533* <code>false</code>, the reader may return <code>-1</code>534* without performing the search.535*536* @return the number of images, as an <code>int</code>, or537* <code>-1</code> if <code>allowSearch</code> is538* <code>false</code> and a search would be required.539*540* @exception IllegalStateException if the input source has not been set,541* or if the input has been specified with <code>seekForwardOnly</code>542* set to <code>true</code>.543* @exception IOException if an error occurs reading the544* information from the input source.545*546* @see #setInput547*/548public abstract int getNumImages(boolean allowSearch) throws IOException;549550/**551* Returns the width in pixels of the given image within the input552* source.553*554* <p> If the image can be rendered to a user-specified size, then555* this method returns the default width.556*557* @param imageIndex the index of the image to be queried.558*559* @return the width of the image, as an <code>int</code>.560*561* @exception IllegalStateException if the input source has not been set.562* @exception IndexOutOfBoundsException if the supplied index is563* out of bounds.564* @exception IOException if an error occurs reading the width565* information from the input source.566*/567public abstract int getWidth(int imageIndex) throws IOException;568569/**570* Returns the height in pixels of the given image within the571* input source.572*573* <p> If the image can be rendered to a user-specified size, then574* this method returns the default height.575*576* @param imageIndex the index of the image to be queried.577*578* @return the height of the image, as an <code>int</code>.579*580* @exception IllegalStateException if the input source has not been set.581* @exception IndexOutOfBoundsException if the supplied index is582* out of bounds.583* @exception IOException if an error occurs reading the height584* information from the input source.585*/586public abstract int getHeight(int imageIndex) throws IOException;587588/**589* Returns <code>true</code> if the storage format of the given590* image places no inherent impediment on random access to pixels.591* For most compressed formats, such as JPEG, this method should592* return <code>false</code>, as a large section of the image in593* addition to the region of interest may need to be decoded.594*595* <p> This is merely a hint for programs that wish to be596* efficient; all readers must be able to read arbitrary regions597* as specified in an <code>ImageReadParam</code>.598*599* <p> Note that formats that return <code>false</code> from600* this method may nonetheless allow tiling (<i>e.g.</i> Restart601* Markers in JPEG), and random access will likely be reasonably602* efficient on tiles. See {@link #isImageTiled isImageTiled}.603*604* <p> A reader for which all images are guaranteed to support605* easy random access, or are guaranteed not to support easy606* random access, may return <code>true</code> or607* <code>false</code> respectively without accessing any image608* data. In such cases, it is not necessary to throw an exception609* even if no input source has been set or the image index is out610* of bounds.611*612* <p> The default implementation returns <code>false</code>.613*614* @param imageIndex the index of the image to be queried.615*616* @return <code>true</code> if reading a region of interest of617* the given image is likely to be efficient.618*619* @exception IllegalStateException if an input source is required620* to determine the return value, but none has been set.621* @exception IndexOutOfBoundsException if an image must be622* accessed to determine the return value, but the supplied index623* is out of bounds.624* @exception IOException if an error occurs during reading.625*/626public boolean isRandomAccessEasy(int imageIndex) throws IOException {627return false;628}629630/**631* Returns the aspect ratio of the given image (that is, its width632* divided by its height) as a <code>float</code>. For images633* that are inherently resizable, this method provides a way to634* determine the appropriate width given a desired height, or vice635* versa. For non-resizable images, the true width and height636* are used.637*638* <p> The default implementation simply returns639* <code>(float)getWidth(imageIndex)/getHeight(imageIndex)</code>.640*641* @param imageIndex the index of the image to be queried.642*643* @return a <code>float</code> indicating the aspect ratio of the644* given image.645*646* @exception IllegalStateException if the input source has not been set.647* @exception IndexOutOfBoundsException if the supplied index is648* out of bounds.649* @exception IOException if an error occurs during reading.650*/651public float getAspectRatio(int imageIndex) throws IOException {652return (float)getWidth(imageIndex)/getHeight(imageIndex);653}654655/**656* Returns an <code>ImageTypeSpecifier</code> indicating the657* <code>SampleModel</code> and <code>ColorModel</code> which most658* closely represents the "raw" internal format of the image. For659* example, for a JPEG image the raw type might have a YCbCr color660* space even though the image would conventionally be transformed661* into an RGB color space prior to display. The returned value662* should also be included in the list of values returned by663* <code>getImageTypes</code>.664*665* <p> The default implementation simply returns the first entry666* from the list provided by <code>getImageType</code>.667*668* @param imageIndex the index of the image to be queried.669*670* @return an <code>ImageTypeSpecifier</code>.671*672* @exception IllegalStateException if the input source has not been set.673* @exception IndexOutOfBoundsException if the supplied index is674* out of bounds.675* @exception IOException if an error occurs reading the format676* information from the input source.677*/678public ImageTypeSpecifier getRawImageType(int imageIndex)679throws IOException {680return (ImageTypeSpecifier)getImageTypes(imageIndex).next();681}682683/**684* Returns an <code>Iterator</code> containing possible image685* types to which the given image may be decoded, in the form of686* <code>ImageTypeSpecifiers</code>s. At least one legal image687* type will be returned.688*689* <p> The first element of the iterator should be the most690* "natural" type for decoding the image with as little loss as691* possible. For example, for a JPEG image the first entry should692* be an RGB image, even though the image data is stored693* internally in a YCbCr color space.694*695* @param imageIndex the index of the image to be696* <code>retrieved</code>.697*698* @return an <code>Iterator</code> containing at least one699* <code>ImageTypeSpecifier</code> representing suggested image700* types for decoding the current given image.701*702* @exception IllegalStateException if the input source has not been set.703* @exception IndexOutOfBoundsException if the supplied index is704* out of bounds.705* @exception IOException if an error occurs reading the format706* information from the input source.707*708* @see ImageReadParam#setDestination(BufferedImage)709* @see ImageReadParam#setDestinationType(ImageTypeSpecifier)710*/711public abstract Iterator<ImageTypeSpecifier>712getImageTypes(int imageIndex) throws IOException;713714/**715* Returns a default <code>ImageReadParam</code> object716* appropriate for this format. All subclasses should define a717* set of default values for all parameters and return them with718* this call. This method may be called before the input source719* is set.720*721* <p> The default implementation constructs and returns a new722* <code>ImageReadParam</code> object that does not allow source723* scaling (<i>i.e.</i>, it returns <code>new724* ImageReadParam()</code>.725*726* @return an <code>ImageReadParam</code> object which may be used727* to control the decoding process using a set of default settings.728*/729public ImageReadParam getDefaultReadParam() {730return new ImageReadParam();731}732733/**734* Returns an <code>IIOMetadata</code> object representing the735* metadata associated with the input source as a whole (i.e., not736* associated with any particular image), or <code>null</code> if737* the reader does not support reading metadata, is set to ignore738* metadata, or if no metadata is available.739*740* @return an <code>IIOMetadata</code> object, or <code>null</code>.741*742* @exception IOException if an error occurs during reading.743*/744public abstract IIOMetadata getStreamMetadata() throws IOException;745746/**747* Returns an <code>IIOMetadata</code> object representing the748* metadata associated with the input source as a whole (i.e.,749* not associated with any particular image). If no such data750* exists, <code>null</code> is returned.751*752* <p> The resulting metadata object is only responsible for753* returning documents in the format named by754* <code>formatName</code>. Within any documents that are755* returned, only nodes whose names are members of756* <code>nodeNames</code> are required to be returned. In this757* way, the amount of metadata processing done by the reader may758* be kept to a minimum, based on what information is actually759* needed.760*761* <p> If <code>formatName</code> is not the name of a supported762* metadata format, <code>null</code> is returned.763*764* <p> In all cases, it is legal to return a more capable metadata765* object than strictly necessary. The format name and node names766* are merely hints that may be used to reduce the reader's767* workload.768*769* <p> The default implementation simply returns the result of770* calling <code>getStreamMetadata()</code>, after checking that771* the format name is supported. If it is not,772* <code>null</code> is returned.773*774* @param formatName a metadata format name that may be used to retrieve775* a document from the returned <code>IIOMetadata</code> object.776* @param nodeNames a <code>Set</code> containing the names of777* nodes that may be contained in a retrieved document.778*779* @return an <code>IIOMetadata</code> object, or <code>null</code>.780*781* @exception IllegalArgumentException if <code>formatName</code>782* is <code>null</code>.783* @exception IllegalArgumentException if <code>nodeNames</code>784* is <code>null</code>.785* @exception IOException if an error occurs during reading.786*/787public IIOMetadata getStreamMetadata(String formatName,788Set<String> nodeNames)789throws IOException790{791return getMetadata(formatName, nodeNames, true, 0);792}793794private IIOMetadata getMetadata(String formatName,795Set nodeNames,796boolean wantStream,797int imageIndex) throws IOException {798if (formatName == null) {799throw new IllegalArgumentException("formatName == null!");800}801if (nodeNames == null) {802throw new IllegalArgumentException("nodeNames == null!");803}804IIOMetadata metadata =805wantStream806? getStreamMetadata()807: getImageMetadata(imageIndex);808if (metadata != null) {809if (metadata.isStandardMetadataFormatSupported() &&810formatName.equals811(IIOMetadataFormatImpl.standardMetadataFormatName)) {812return metadata;813}814String nativeName = metadata.getNativeMetadataFormatName();815if (nativeName != null && formatName.equals(nativeName)) {816return metadata;817}818String[] extraNames = metadata.getExtraMetadataFormatNames();819if (extraNames != null) {820for (int i = 0; i < extraNames.length; i++) {821if (formatName.equals(extraNames[i])) {822return metadata;823}824}825}826}827return null;828}829830/**831* Returns an <code>IIOMetadata</code> object containing metadata832* associated with the given image, or <code>null</code> if the833* reader does not support reading metadata, is set to ignore834* metadata, or if no metadata is available.835*836* @param imageIndex the index of the image whose metadata is to837* be retrieved.838*839* @return an <code>IIOMetadata</code> object, or840* <code>null</code>.841*842* @exception IllegalStateException if the input source has not been843* set.844* @exception IndexOutOfBoundsException if the supplied index is845* out of bounds.846* @exception IOException if an error occurs during reading.847*/848public abstract IIOMetadata getImageMetadata(int imageIndex)849throws IOException;850851/**852* Returns an <code>IIOMetadata</code> object representing the853* metadata associated with the given image, or <code>null</code>854* if the reader does not support reading metadata or none855* is available.856*857* <p> The resulting metadata object is only responsible for858* returning documents in the format named by859* <code>formatName</code>. Within any documents that are860* returned, only nodes whose names are members of861* <code>nodeNames</code> are required to be returned. In this862* way, the amount of metadata processing done by the reader may863* be kept to a minimum, based on what information is actually864* needed.865*866* <p> If <code>formatName</code> is not the name of a supported867* metadata format, <code>null</code> may be returned.868*869* <p> In all cases, it is legal to return a more capable metadata870* object than strictly necessary. The format name and node names871* are merely hints that may be used to reduce the reader's872* workload.873*874* <p> The default implementation simply returns the result of875* calling <code>getImageMetadata(imageIndex)</code>, after876* checking that the format name is supported. If it is not,877* <code>null</code> is returned.878*879* @param imageIndex the index of the image whose metadata is to880* be retrieved.881* @param formatName a metadata format name that may be used to retrieve882* a document from the returned <code>IIOMetadata</code> object.883* @param nodeNames a <code>Set</code> containing the names of884* nodes that may be contained in a retrieved document.885*886* @return an <code>IIOMetadata</code> object, or <code>null</code>.887*888* @exception IllegalStateException if the input source has not been889* set.890* @exception IndexOutOfBoundsException if the supplied index is891* out of bounds.892* @exception IllegalArgumentException if <code>formatName</code>893* is <code>null</code>.894* @exception IllegalArgumentException if <code>nodeNames</code>895* is <code>null</code>.896* @exception IOException if an error occurs during reading.897*/898public IIOMetadata getImageMetadata(int imageIndex,899String formatName,900Set<String> nodeNames)901throws IOException {902return getMetadata(formatName, nodeNames, false, imageIndex);903}904905/**906* Reads the image indexed by <code>imageIndex</code> and returns907* it as a complete <code>BufferedImage</code>, using a default908* <code>ImageReadParam</code>. This is a convenience method909* that calls <code>read(imageIndex, null)</code>.910*911* <p> The image returned will be formatted according to the first912* <code>ImageTypeSpecifier</code> returned from913* <code>getImageTypes</code>.914*915* <p> Any registered <code>IIOReadProgressListener</code> objects916* will be notified by calling their <code>imageStarted</code>917* method, followed by calls to their <code>imageProgress</code>918* method as the read progresses. Finally their919* <code>imageComplete</code> method will be called.920* <code>IIOReadUpdateListener</code> objects may be updated at921* other times during the read as pixels are decoded. Finally,922* <code>IIOReadWarningListener</code> objects will receive923* notification of any non-fatal warnings that occur during924* decoding.925*926* @param imageIndex the index of the image to be retrieved.927*928* @return the desired portion of the image as a929* <code>BufferedImage</code>.930*931* @exception IllegalStateException if the input source has not been932* set.933* @exception IndexOutOfBoundsException if the supplied index is934* out of bounds.935* @exception IOException if an error occurs during reading.936*/937public BufferedImage read(int imageIndex) throws IOException {938return read(imageIndex, null);939}940941/**942* Reads the image indexed by <code>imageIndex</code> and returns943* it as a complete <code>BufferedImage</code>, using a supplied944* <code>ImageReadParam</code>.945*946* <p> The actual <code>BufferedImage</code> returned will be947* chosen using the algorithm defined by the948* <code>getDestination</code> method.949*950* <p> Any registered <code>IIOReadProgressListener</code> objects951* will be notified by calling their <code>imageStarted</code>952* method, followed by calls to their <code>imageProgress</code>953* method as the read progresses. Finally their954* <code>imageComplete</code> method will be called.955* <code>IIOReadUpdateListener</code> objects may be updated at956* other times during the read as pixels are decoded. Finally,957* <code>IIOReadWarningListener</code> objects will receive958* notification of any non-fatal warnings that occur during959* decoding.960*961* <p> The set of source bands to be read and destination bands to962* be written is determined by calling <code>getSourceBands</code>963* and <code>getDestinationBands</code> on the supplied964* <code>ImageReadParam</code>. If the lengths of the arrays965* returned by these methods differ, the set of source bands966* contains an index larger that the largest available source967* index, or the set of destination bands contains an index larger968* than the largest legal destination index, an969* <code>IllegalArgumentException</code> is thrown.970*971* <p> If the supplied <code>ImageReadParam</code> contains972* optional setting values not supported by this reader (<i>e.g.</i>973* source render size or any format-specific settings), they will974* be ignored.975*976* @param imageIndex the index of the image to be retrieved.977* @param param an <code>ImageReadParam</code> used to control978* the reading process, or <code>null</code>.979*980* @return the desired portion of the image as a981* <code>BufferedImage</code>.982*983* @exception IllegalStateException if the input source has not been984* set.985* @exception IndexOutOfBoundsException if the supplied index is986* out of bounds.987* @exception IllegalArgumentException if the set of source and988* destination bands specified by989* <code>param.getSourceBands</code> and990* <code>param.getDestinationBands</code> differ in length or991* include indices that are out of bounds.992* @exception IllegalArgumentException if the resulting image would993* have a width or height less than 1.994* @exception IOException if an error occurs during reading.995*/996public abstract BufferedImage read(int imageIndex, ImageReadParam param)997throws IOException;998999/**1000* Reads the image indexed by <code>imageIndex</code> and returns1001* an <code>IIOImage</code> containing the image, thumbnails, and1002* associated image metadata, using a supplied1003* <code>ImageReadParam</code>.1004*1005* <p> The actual <code>BufferedImage</code> referenced by the1006* returned <code>IIOImage</code> will be chosen using the1007* algorithm defined by the <code>getDestination</code> method.1008*1009* <p> Any registered <code>IIOReadProgressListener</code> objects1010* will be notified by calling their <code>imageStarted</code>1011* method, followed by calls to their <code>imageProgress</code>1012* method as the read progresses. Finally their1013* <code>imageComplete</code> method will be called.1014* <code>IIOReadUpdateListener</code> objects may be updated at1015* other times during the read as pixels are decoded. Finally,1016* <code>IIOReadWarningListener</code> objects will receive1017* notification of any non-fatal warnings that occur during1018* decoding.1019*1020* <p> The set of source bands to be read and destination bands to1021* be written is determined by calling <code>getSourceBands</code>1022* and <code>getDestinationBands</code> on the supplied1023* <code>ImageReadParam</code>. If the lengths of the arrays1024* returned by these methods differ, the set of source bands1025* contains an index larger that the largest available source1026* index, or the set of destination bands contains an index larger1027* than the largest legal destination index, an1028* <code>IllegalArgumentException</code> is thrown.1029*1030* <p> Thumbnails will be returned in their entirety regardless of1031* the region settings.1032*1033* <p> If the supplied <code>ImageReadParam</code> contains1034* optional setting values not supported by this reader (<i>e.g.</i>1035* source render size or any format-specific settings), those1036* values will be ignored.1037*1038* @param imageIndex the index of the image to be retrieved.1039* @param param an <code>ImageReadParam</code> used to control1040* the reading process, or <code>null</code>.1041*1042* @return an <code>IIOImage</code> containing the desired portion1043* of the image, a set of thumbnails, and associated image1044* metadata.1045*1046* @exception IllegalStateException if the input source has not been1047* set.1048* @exception IndexOutOfBoundsException if the supplied index is1049* out of bounds.1050* @exception IllegalArgumentException if the set of source and1051* destination bands specified by1052* <code>param.getSourceBands</code> and1053* <code>param.getDestinationBands</code> differ in length or1054* include indices that are out of bounds.1055* @exception IllegalArgumentException if the resulting image1056* would have a width or height less than 1.1057* @exception IOException if an error occurs during reading.1058*/1059public IIOImage readAll(int imageIndex, ImageReadParam param)1060throws IOException {1061if (imageIndex < getMinIndex()) {1062throw new IndexOutOfBoundsException("imageIndex < getMinIndex()!");1063}10641065BufferedImage im = read(imageIndex, param);10661067ArrayList thumbnails = null;1068int numThumbnails = getNumThumbnails(imageIndex);1069if (numThumbnails > 0) {1070thumbnails = new ArrayList();1071for (int j = 0; j < numThumbnails; j++) {1072thumbnails.add(readThumbnail(imageIndex, j));1073}1074}10751076IIOMetadata metadata = getImageMetadata(imageIndex);1077return new IIOImage(im, thumbnails, metadata);1078}10791080/**1081* Returns an <code>Iterator</code> containing all the images,1082* thumbnails, and metadata, starting at the index given by1083* <code>getMinIndex</code>, from the input source in the form of1084* <code>IIOImage</code> objects. An <code>Iterator</code>1085* containing <code>ImageReadParam</code> objects is supplied; one1086* element is consumed for each image read from the input source1087* until no more images are available. If the read param1088* <code>Iterator</code> runs out of elements, but there are still1089* more images available from the input source, default read1090* params are used for the remaining images.1091*1092* <p> If <code>params</code> is <code>null</code>, a default read1093* param will be used for all images.1094*1095* <p> The actual <code>BufferedImage</code> referenced by the1096* returned <code>IIOImage</code> will be chosen using the1097* algorithm defined by the <code>getDestination</code> method.1098*1099* <p> Any registered <code>IIOReadProgressListener</code> objects1100* will be notified by calling their <code>sequenceStarted</code>1101* method once. Then, for each image decoded, there will be a1102* call to <code>imageStarted</code>, followed by calls to1103* <code>imageProgress</code> as the read progresses, and finally1104* to <code>imageComplete</code>. The1105* <code>sequenceComplete</code> method will be called after the1106* last image has been decoded.1107* <code>IIOReadUpdateListener</code> objects may be updated at1108* other times during the read as pixels are decoded. Finally,1109* <code>IIOReadWarningListener</code> objects will receive1110* notification of any non-fatal warnings that occur during1111* decoding.1112*1113* <p> The set of source bands to be read and destination bands to1114* be written is determined by calling <code>getSourceBands</code>1115* and <code>getDestinationBands</code> on the supplied1116* <code>ImageReadParam</code>. If the lengths of the arrays1117* returned by these methods differ, the set of source bands1118* contains an index larger that the largest available source1119* index, or the set of destination bands contains an index larger1120* than the largest legal destination index, an1121* <code>IllegalArgumentException</code> is thrown.1122*1123* <p> Thumbnails will be returned in their entirety regardless of the1124* region settings.1125*1126* <p> If any of the supplied <code>ImageReadParam</code>s contain1127* optional setting values not supported by this reader (<i>e.g.</i>1128* source render size or any format-specific settings), they will1129* be ignored.1130*1131* @param params an <code>Iterator</code> containing1132* <code>ImageReadParam</code> objects.1133*1134* @return an <code>Iterator</code> representing the1135* contents of the input source as <code>IIOImage</code>s.1136*1137* @exception IllegalStateException if the input source has not been1138* set.1139* @exception IllegalArgumentException if any1140* non-<code>null</code> element of <code>params</code> is not an1141* <code>ImageReadParam</code>.1142* @exception IllegalArgumentException if the set of source and1143* destination bands specified by1144* <code>param.getSourceBands</code> and1145* <code>param.getDestinationBands</code> differ in length or1146* include indices that are out of bounds.1147* @exception IllegalArgumentException if a resulting image would1148* have a width or height less than 1.1149* @exception IOException if an error occurs during reading.1150*1151* @see ImageReadParam1152* @see IIOImage1153*/1154public Iterator<IIOImage>1155readAll(Iterator<? extends ImageReadParam> params)1156throws IOException1157{1158List output = new ArrayList();11591160int imageIndex = getMinIndex();11611162// Inform IIOReadProgressListeners we're starting a sequence1163processSequenceStarted(imageIndex);11641165while (true) {1166// Inform IIOReadProgressListeners and IIOReadUpdateListeners1167// that we're starting a new image11681169ImageReadParam param = null;1170if (params != null && params.hasNext()) {1171Object o = params.next();1172if (o != null) {1173if (o instanceof ImageReadParam) {1174param = (ImageReadParam)o;1175} else {1176throw new IllegalArgumentException1177("Non-ImageReadParam supplied as part of params!");1178}1179}1180}11811182BufferedImage bi = null;1183try {1184bi = read(imageIndex, param);1185} catch (IndexOutOfBoundsException e) {1186break;1187}11881189ArrayList thumbnails = null;1190int numThumbnails = getNumThumbnails(imageIndex);1191if (numThumbnails > 0) {1192thumbnails = new ArrayList();1193for (int j = 0; j < numThumbnails; j++) {1194thumbnails.add(readThumbnail(imageIndex, j));1195}1196}11971198IIOMetadata metadata = getImageMetadata(imageIndex);1199IIOImage im = new IIOImage(bi, thumbnails, metadata);1200output.add(im);12011202++imageIndex;1203}12041205// Inform IIOReadProgressListeners we're ending a sequence1206processSequenceComplete();12071208return output.iterator();1209}12101211/**1212* Returns <code>true</code> if this plug-in supports reading1213* just a {@link java.awt.image.Raster Raster} of pixel data.1214* If this method returns <code>false</code>, calls to1215* {@link #readRaster readRaster} or {@link #readTileRaster readTileRaster}1216* will throw an <code>UnsupportedOperationException</code>.1217*1218* <p> The default implementation returns <code>false</code>.1219*1220* @return <code>true</code> if this plug-in supports reading raw1221* <code>Raster</code>s.1222*1223* @see #readRaster1224* @see #readTileRaster1225*/1226public boolean canReadRaster() {1227return false;1228}12291230/**1231* Returns a new <code>Raster</code> object containing the raw pixel data1232* from the image stream, without any color conversion applied. The1233* application must determine how to interpret the pixel data by other1234* means. Any destination or image-type parameters in the supplied1235* <code>ImageReadParam</code> object are ignored, but all other1236* parameters are used exactly as in the {@link #read read}1237* method, except that any destination offset is used as a logical rather1238* than a physical offset. The size of the returned <code>Raster</code>1239* will always be that of the source region clipped to the actual image.1240* Logical offsets in the stream itself are ignored.1241*1242* <p> This method allows formats that normally apply a color1243* conversion, such as JPEG, and formats that do not normally have an1244* associated colorspace, such as remote sensing or medical imaging data,1245* to provide access to raw pixel data.1246*1247* <p> Any registered <code>readUpdateListener</code>s are ignored, as1248* there is no <code>BufferedImage</code>, but all other listeners are1249* called exactly as they are for the {@link #read read} method.1250*1251* <p> If {@link #canReadRaster canReadRaster()} returns1252* <code>false</code>, this method throws an1253* <code>UnsupportedOperationException</code>.1254*1255* <p> If the supplied <code>ImageReadParam</code> contains1256* optional setting values not supported by this reader (<i>e.g.</i>1257* source render size or any format-specific settings), they will1258* be ignored.1259*1260* <p> The default implementation throws an1261* <code>UnsupportedOperationException</code>.1262*1263* @param imageIndex the index of the image to be read.1264* @param param an <code>ImageReadParam</code> used to control1265* the reading process, or <code>null</code>.1266*1267* @return the desired portion of the image as a1268* <code>Raster</code>.1269*1270* @exception UnsupportedOperationException if this plug-in does not1271* support reading raw <code>Raster</code>s.1272* @exception IllegalStateException if the input source has not been1273* set.1274* @exception IndexOutOfBoundsException if the supplied index is1275* out of bounds.1276* @exception IOException if an error occurs during reading.1277*1278* @see #canReadRaster1279* @see #read1280* @see java.awt.image.Raster1281*/1282public Raster readRaster(int imageIndex, ImageReadParam param)1283throws IOException {1284throw new UnsupportedOperationException("readRaster not supported!");1285}12861287/**1288* Returns <code>true</code> if the image is organized into1289* <i>tiles</i>, that is, equal-sized non-overlapping rectangles.1290*1291* <p> A reader plug-in may choose whether or not to expose tiling1292* that is present in the image as it is stored. It may even1293* choose to advertise tiling when none is explicitly present. In1294* general, tiling should only be advertised if there is some1295* advantage (in speed or space) to accessing individual tiles.1296* Regardless of whether the reader advertises tiling, it must be1297* capable of reading an arbitrary rectangular region specified in1298* an <code>ImageReadParam</code>.1299*1300* <p> A reader for which all images are guaranteed to be tiled,1301* or are guaranteed not to be tiled, may return <code>true</code>1302* or <code>false</code> respectively without accessing any image1303* data. In such cases, it is not necessary to throw an exception1304* even if no input source has been set or the image index is out1305* of bounds.1306*1307* <p> The default implementation just returns <code>false</code>.1308*1309* @param imageIndex the index of the image to be queried.1310*1311* @return <code>true</code> if the image is tiled.1312*1313* @exception IllegalStateException if an input source is required1314* to determine the return value, but none has been set.1315* @exception IndexOutOfBoundsException if an image must be1316* accessed to determine the return value, but the supplied index1317* is out of bounds.1318* @exception IOException if an error occurs during reading.1319*/1320public boolean isImageTiled(int imageIndex) throws IOException {1321return false;1322}13231324/**1325* Returns the width of a tile in the given image.1326*1327* <p> The default implementation simply returns1328* <code>getWidth(imageIndex)</code>, which is correct for1329* non-tiled images. Readers that support tiling should override1330* this method.1331*1332* @return the width of a tile.1333*1334* @param imageIndex the index of the image to be queried.1335*1336* @exception IllegalStateException if the input source has not been set.1337* @exception IndexOutOfBoundsException if the supplied index is1338* out of bounds.1339* @exception IOException if an error occurs during reading.1340*/1341public int getTileWidth(int imageIndex) throws IOException {1342return getWidth(imageIndex);1343}13441345/**1346* Returns the height of a tile in the given image.1347*1348* <p> The default implementation simply returns1349* <code>getHeight(imageIndex)</code>, which is correct for1350* non-tiled images. Readers that support tiling should override1351* this method.1352*1353* @return the height of a tile.1354*1355* @param imageIndex the index of the image to be queried.1356*1357* @exception IllegalStateException if the input source has not been set.1358* @exception IndexOutOfBoundsException if the supplied index is1359* out of bounds.1360* @exception IOException if an error occurs during reading.1361*/1362public int getTileHeight(int imageIndex) throws IOException {1363return getHeight(imageIndex);1364}13651366/**1367* Returns the X coordinate of the upper-left corner of tile (0,1368* 0) in the given image.1369*1370* <p> A reader for which the tile grid X offset always has the1371* same value (usually 0), may return the value without accessing1372* any image data. In such cases, it is not necessary to throw an1373* exception even if no input source has been set or the image1374* index is out of bounds.1375*1376* <p> The default implementation simply returns 0, which is1377* correct for non-tiled images and tiled images in most formats.1378* Readers that support tiling with non-(0, 0) offsets should1379* override this method.1380*1381* @return the X offset of the tile grid.1382*1383* @param imageIndex the index of the image to be queried.1384*1385* @exception IllegalStateException if an input source is required1386* to determine the return value, but none has been set.1387* @exception IndexOutOfBoundsException if an image must be1388* accessed to determine the return value, but the supplied index1389* is out of bounds.1390* @exception IOException if an error occurs during reading.1391*/1392public int getTileGridXOffset(int imageIndex) throws IOException {1393return 0;1394}13951396/**1397* Returns the Y coordinate of the upper-left corner of tile (0,1398* 0) in the given image.1399*1400* <p> A reader for which the tile grid Y offset always has the1401* same value (usually 0), may return the value without accessing1402* any image data. In such cases, it is not necessary to throw an1403* exception even if no input source has been set or the image1404* index is out of bounds.1405*1406* <p> The default implementation simply returns 0, which is1407* correct for non-tiled images and tiled images in most formats.1408* Readers that support tiling with non-(0, 0) offsets should1409* override this method.1410*1411* @return the Y offset of the tile grid.1412*1413* @param imageIndex the index of the image to be queried.1414*1415* @exception IllegalStateException if an input source is required1416* to determine the return value, but none has been set.1417* @exception IndexOutOfBoundsException if an image must be1418* accessed to determine the return value, but the supplied index1419* is out of bounds.1420* @exception IOException if an error occurs during reading.1421*/1422public int getTileGridYOffset(int imageIndex) throws IOException {1423return 0;1424}14251426/**1427* Reads the tile indicated by the <code>tileX</code> and1428* <code>tileY</code> arguments, returning it as a1429* <code>BufferedImage</code>. If the arguments are out of range,1430* an <code>IllegalArgumentException</code> is thrown. If the1431* image is not tiled, the values 0, 0 will return the entire1432* image; any other values will cause an1433* <code>IllegalArgumentException</code> to be thrown.1434*1435* <p> This method is merely a convenience equivalent to calling1436* <code>read(int, ImageReadParam)</code> with a read param1437* specifying a source region having offsets of1438* <code>tileX*getTileWidth(imageIndex)</code>,1439* <code>tileY*getTileHeight(imageIndex)</code> and width and1440* height of <code>getTileWidth(imageIndex)</code>,1441* <code>getTileHeight(imageIndex)</code>; and subsampling1442* factors of 1 and offsets of 0. To subsample a tile, call1443* <code>read</code> with a read param specifying this region1444* and different subsampling parameters.1445*1446* <p> The default implementation returns the entire image if1447* <code>tileX</code> and <code>tileY</code> are 0, or throws1448* an <code>IllegalArgumentException</code> otherwise.1449*1450* @param imageIndex the index of the image to be retrieved.1451* @param tileX the column index (starting with 0) of the tile1452* to be retrieved.1453* @param tileY the row index (starting with 0) of the tile1454* to be retrieved.1455*1456* @return the tile as a <code>BufferedImage</code>.1457*1458* @exception IllegalStateException if the input source has not been1459* set.1460* @exception IndexOutOfBoundsException if <code>imageIndex</code>1461* is out of bounds.1462* @exception IllegalArgumentException if the tile indices are1463* out of bounds.1464* @exception IOException if an error occurs during reading.1465*/1466public BufferedImage readTile(int imageIndex,1467int tileX, int tileY) throws IOException {1468if ((tileX != 0) || (tileY != 0)) {1469throw new IllegalArgumentException("Invalid tile indices");1470}1471return read(imageIndex);1472}14731474/**1475* Returns a new <code>Raster</code> object containing the raw1476* pixel data from the tile, without any color conversion applied.1477* The application must determine how to interpret the pixel data by other1478* means.1479*1480* <p> If {@link #canReadRaster canReadRaster()} returns1481* <code>false</code>, this method throws an1482* <code>UnsupportedOperationException</code>.1483*1484* <p> The default implementation checks if reading1485* <code>Raster</code>s is supported, and if so calls {@link1486* #readRaster readRaster(imageIndex, null)} if1487* <code>tileX</code> and <code>tileY</code> are 0, or throws an1488* <code>IllegalArgumentException</code> otherwise.1489*1490* @param imageIndex the index of the image to be retrieved.1491* @param tileX the column index (starting with 0) of the tile1492* to be retrieved.1493* @param tileY the row index (starting with 0) of the tile1494* to be retrieved.1495*1496* @return the tile as a <code>Raster</code>.1497*1498* @exception UnsupportedOperationException if this plug-in does not1499* support reading raw <code>Raster</code>s.1500* @exception IllegalArgumentException if the tile indices are1501* out of bounds.1502* @exception IllegalStateException if the input source has not been1503* set.1504* @exception IndexOutOfBoundsException if <code>imageIndex</code>1505* is out of bounds.1506* @exception IOException if an error occurs during reading.1507*1508* @see #readTile1509* @see #readRaster1510* @see java.awt.image.Raster1511*/1512public Raster readTileRaster(int imageIndex,1513int tileX, int tileY) throws IOException {1514if (!canReadRaster()) {1515throw new UnsupportedOperationException1516("readTileRaster not supported!");1517}1518if ((tileX != 0) || (tileY != 0)) {1519throw new IllegalArgumentException("Invalid tile indices");1520}1521return readRaster(imageIndex, null);1522}15231524// RenderedImages15251526/**1527* Returns a <code>RenderedImage</code> object that contains the1528* contents of the image indexed by <code>imageIndex</code>. By1529* default, the returned image is simply the1530* <code>BufferedImage</code> returned by <code>read(imageIndex,1531* param)</code>.1532*1533* <p> The semantics of this method may differ from those of the1534* other <code>read</code> methods in several ways. First, any1535* destination image and/or image type set in the1536* <code>ImageReadParam</code> may be ignored. Second, the usual1537* listener calls are not guaranteed to be made, or to be1538* meaningful if they are. This is because the returned image may1539* not be fully populated with pixel data at the time it is1540* returned, or indeed at any time.1541*1542* <p> If the supplied <code>ImageReadParam</code> contains1543* optional setting values not supported by this reader (<i>e.g.</i>1544* source render size or any format-specific settings), they will1545* be ignored.1546*1547* <p> The default implementation just calls1548* {@link #read read(imageIndex, param)}.1549*1550* @param imageIndex the index of the image to be retrieved.1551* @param param an <code>ImageReadParam</code> used to control1552* the reading process, or <code>null</code>.1553*1554* @return a <code>RenderedImage</code> object providing a view of1555* the image.1556*1557* @exception IllegalStateException if the input source has not been1558* set.1559* @exception IndexOutOfBoundsException if the supplied index is1560* out of bounds.1561* @exception IllegalArgumentException if the set of source and1562* destination bands specified by1563* <code>param.getSourceBands</code> and1564* <code>param.getDestinationBands</code> differ in length or1565* include indices that are out of bounds.1566* @exception IllegalArgumentException if the resulting image1567* would have a width or height less than 1.1568* @exception IOException if an error occurs during reading.1569*/1570public RenderedImage readAsRenderedImage(int imageIndex,1571ImageReadParam param)1572throws IOException {1573return read(imageIndex, param);1574}15751576// Thumbnails15771578/**1579* Returns <code>true</code> if the image format understood by1580* this reader supports thumbnail preview images associated with1581* it. The default implementation returns <code>false</code>.1582*1583* <p> If this method returns <code>false</code>,1584* <code>hasThumbnails</code> and <code>getNumThumbnails</code>1585* will return <code>false</code> and <code>0</code>,1586* respectively, and <code>readThumbnail</code> will throw an1587* <code>UnsupportedOperationException</code>, regardless of their1588* arguments.1589*1590* <p> A reader that does not support thumbnails need not1591* implement any of the thumbnail-related methods.1592*1593* @return <code>true</code> if thumbnails are supported.1594*/1595public boolean readerSupportsThumbnails() {1596return false;1597}15981599/**1600* Returns <code>true</code> if the given image has thumbnail1601* preview images associated with it. If the format does not1602* support thumbnails (<code>readerSupportsThumbnails</code>1603* returns <code>false</code>), <code>false</code> will be1604* returned regardless of whether an input source has been set or1605* whether <code>imageIndex</code> is in bounds.1606*1607* <p> The default implementation returns <code>true</code> if1608* <code>getNumThumbnails</code> returns a value greater than 0.1609*1610* @param imageIndex the index of the image being queried.1611*1612* @return <code>true</code> if the given image has thumbnails.1613*1614* @exception IllegalStateException if the reader supports1615* thumbnails but the input source has not been set.1616* @exception IndexOutOfBoundsException if the reader supports1617* thumbnails but <code>imageIndex</code> is out of bounds.1618* @exception IOException if an error occurs during reading.1619*/1620public boolean hasThumbnails(int imageIndex) throws IOException {1621return getNumThumbnails(imageIndex) > 0;1622}16231624/**1625* Returns the number of thumbnail preview images associated with1626* the given image. If the format does not support thumbnails,1627* (<code>readerSupportsThumbnails</code> returns1628* <code>false</code>), <code>0</code> will be returned regardless1629* of whether an input source has been set or whether1630* <code>imageIndex</code> is in bounds.1631*1632* <p> The default implementation returns 0 without checking its1633* argument.1634*1635* @param imageIndex the index of the image being queried.1636*1637* @return the number of thumbnails associated with the given1638* image.1639*1640* @exception IllegalStateException if the reader supports1641* thumbnails but the input source has not been set.1642* @exception IndexOutOfBoundsException if the reader supports1643* thumbnails but <code>imageIndex</code> is out of bounds.1644* @exception IOException if an error occurs during reading.1645*/1646public int getNumThumbnails(int imageIndex)1647throws IOException {1648return 0;1649}16501651/**1652* Returns the width of the thumbnail preview image indexed by1653* <code>thumbnailIndex</code>, associated with the image indexed1654* by <code>ImageIndex</code>.1655*1656* <p> If the reader does not support thumbnails,1657* (<code>readerSupportsThumbnails</code> returns1658* <code>false</code>), an <code>UnsupportedOperationException</code>1659* will be thrown.1660*1661* <p> The default implementation simply returns1662* <code>readThumbnail(imageindex,1663* thumbnailIndex).getWidth()</code>. Subclasses should therefore1664* override this method if possible in order to avoid forcing the1665* thumbnail to be read.1666*1667* @param imageIndex the index of the image to be retrieved.1668* @param thumbnailIndex the index of the thumbnail to be retrieved.1669*1670* @return the width of the desired thumbnail as an <code>int</code>.1671*1672* @exception UnsupportedOperationException if thumbnails are not1673* supported.1674* @exception IllegalStateException if the input source has not been set.1675* @exception IndexOutOfBoundsException if either of the supplied1676* indices are out of bounds.1677* @exception IOException if an error occurs during reading.1678*/1679public int getThumbnailWidth(int imageIndex, int thumbnailIndex)1680throws IOException {1681return readThumbnail(imageIndex, thumbnailIndex).getWidth();1682}16831684/**1685* Returns the height of the thumbnail preview image indexed by1686* <code>thumbnailIndex</code>, associated with the image indexed1687* by <code>ImageIndex</code>.1688*1689* <p> If the reader does not support thumbnails,1690* (<code>readerSupportsThumbnails</code> returns1691* <code>false</code>), an <code>UnsupportedOperationException</code>1692* will be thrown.1693*1694* <p> The default implementation simply returns1695* <code>readThumbnail(imageindex,1696* thumbnailIndex).getHeight()</code>. Subclasses should1697* therefore override this method if possible in order to avoid1698* forcing the thumbnail to be read.1699*1700* @param imageIndex the index of the image to be retrieved.1701* @param thumbnailIndex the index of the thumbnail to be retrieved.1702*1703* @return the height of the desired thumbnail as an <code>int</code>.1704*1705* @exception UnsupportedOperationException if thumbnails are not1706* supported.1707* @exception IllegalStateException if the input source has not been set.1708* @exception IndexOutOfBoundsException if either of the supplied1709* indices are out of bounds.1710* @exception IOException if an error occurs during reading.1711*/1712public int getThumbnailHeight(int imageIndex, int thumbnailIndex)1713throws IOException {1714return readThumbnail(imageIndex, thumbnailIndex).getHeight();1715}17161717/**1718* Returns the thumbnail preview image indexed by1719* <code>thumbnailIndex</code>, associated with the image indexed1720* by <code>ImageIndex</code> as a <code>BufferedImage</code>.1721*1722* <p> Any registered <code>IIOReadProgressListener</code> objects1723* will be notified by calling their1724* <code>thumbnailStarted</code>, <code>thumbnailProgress</code>,1725* and <code>thumbnailComplete</code> methods.1726*1727* <p> If the reader does not support thumbnails,1728* (<code>readerSupportsThumbnails</code> returns1729* <code>false</code>), an <code>UnsupportedOperationException</code>1730* will be thrown regardless of whether an input source has been1731* set or whether the indices are in bounds.1732*1733* <p> The default implementation throws an1734* <code>UnsupportedOperationException</code>.1735*1736* @param imageIndex the index of the image to be retrieved.1737* @param thumbnailIndex the index of the thumbnail to be retrieved.1738*1739* @return the desired thumbnail as a <code>BufferedImage</code>.1740*1741* @exception UnsupportedOperationException if thumbnails are not1742* supported.1743* @exception IllegalStateException if the input source has not been set.1744* @exception IndexOutOfBoundsException if either of the supplied1745* indices are out of bounds.1746* @exception IOException if an error occurs during reading.1747*/1748public BufferedImage readThumbnail(int imageIndex,1749int thumbnailIndex)1750throws IOException {1751throw new UnsupportedOperationException("Thumbnails not supported!");1752}17531754// Abort17551756/**1757* Requests that any current read operation be aborted. The1758* contents of the image following the abort will be undefined.1759*1760* <p> Readers should call <code>clearAbortRequest</code> at the1761* beginning of each read operation, and poll the value of1762* <code>abortRequested</code> regularly during the read.1763*/1764public synchronized void abort() {1765this.abortFlag = true;1766}17671768/**1769* Returns <code>true</code> if a request to abort the current1770* read operation has been made since the reader was instantiated or1771* <code>clearAbortRequest</code> was called.1772*1773* @return <code>true</code> if the current read operation should1774* be aborted.1775*1776* @see #abort1777* @see #clearAbortRequest1778*/1779protected synchronized boolean abortRequested() {1780return this.abortFlag;1781}17821783/**1784* Clears any previous abort request. After this method has been1785* called, <code>abortRequested</code> will return1786* <code>false</code>.1787*1788* @see #abort1789* @see #abortRequested1790*/1791protected synchronized void clearAbortRequest() {1792this.abortFlag = false;1793}17941795// Listeners17961797// Add an element to a list, creating a new list if the1798// existing list is null, and return the list.1799static List addToList(List l, Object elt) {1800if (l == null) {1801l = new ArrayList();1802}1803l.add(elt);1804return l;1805}180618071808// Remove an element from a list, discarding the list if the1809// resulting list is empty, and return the list or null.1810static List removeFromList(List l, Object elt) {1811if (l == null) {1812return l;1813}1814l.remove(elt);1815if (l.size() == 0) {1816l = null;1817}1818return l;1819}18201821/**1822* Adds an <code>IIOReadWarningListener</code> to the list of1823* registered warning listeners. If <code>listener</code> is1824* <code>null</code>, no exception will be thrown and no action1825* will be taken. Messages sent to the given listener will be1826* localized, if possible, to match the current1827* <code>Locale</code>. If no <code>Locale</code> has been set,1828* warning messages may be localized as the reader sees fit.1829*1830* @param listener an <code>IIOReadWarningListener</code> to be registered.1831*1832* @see #removeIIOReadWarningListener1833*/1834public void addIIOReadWarningListener(IIOReadWarningListener listener) {1835if (listener == null) {1836return;1837}1838warningListeners = addToList(warningListeners, listener);1839warningLocales = addToList(warningLocales, getLocale());1840}18411842/**1843* Removes an <code>IIOReadWarningListener</code> from the list of1844* registered error listeners. If the listener was not previously1845* registered, or if <code>listener</code> is <code>null</code>,1846* no exception will be thrown and no action will be taken.1847*1848* @param listener an IIOReadWarningListener to be unregistered.1849*1850* @see #addIIOReadWarningListener1851*/1852public void removeIIOReadWarningListener(IIOReadWarningListener listener) {1853if (listener == null || warningListeners == null) {1854return;1855}1856int index = warningListeners.indexOf(listener);1857if (index != -1) {1858warningListeners.remove(index);1859warningLocales.remove(index);1860if (warningListeners.size() == 0) {1861warningListeners = null;1862warningLocales = null;1863}1864}1865}18661867/**1868* Removes all currently registered1869* <code>IIOReadWarningListener</code> objects.1870*1871* <p> The default implementation sets the1872* <code>warningListeners</code> and <code>warningLocales</code>1873* instance variables to <code>null</code>.1874*/1875public void removeAllIIOReadWarningListeners() {1876warningListeners = null;1877warningLocales = null;1878}18791880/**1881* Adds an <code>IIOReadProgressListener</code> to the list of1882* registered progress listeners. If <code>listener</code> is1883* <code>null</code>, no exception will be thrown and no action1884* will be taken.1885*1886* @param listener an IIOReadProgressListener to be registered.1887*1888* @see #removeIIOReadProgressListener1889*/1890public void addIIOReadProgressListener(IIOReadProgressListener listener) {1891if (listener == null) {1892return;1893}1894progressListeners = addToList(progressListeners, listener);1895}18961897/**1898* Removes an <code>IIOReadProgressListener</code> from the list1899* of registered progress listeners. If the listener was not1900* previously registered, or if <code>listener</code> is1901* <code>null</code>, no exception will be thrown and no action1902* will be taken.1903*1904* @param listener an IIOReadProgressListener to be unregistered.1905*1906* @see #addIIOReadProgressListener1907*/1908public void1909removeIIOReadProgressListener (IIOReadProgressListener listener) {1910if (listener == null || progressListeners == null) {1911return;1912}1913progressListeners = removeFromList(progressListeners, listener);1914}19151916/**1917* Removes all currently registered1918* <code>IIOReadProgressListener</code> objects.1919*1920* <p> The default implementation sets the1921* <code>progressListeners</code> instance variable to1922* <code>null</code>.1923*/1924public void removeAllIIOReadProgressListeners() {1925progressListeners = null;1926}19271928/**1929* Adds an <code>IIOReadUpdateListener</code> to the list of1930* registered update listeners. If <code>listener</code> is1931* <code>null</code>, no exception will be thrown and no action1932* will be taken. The listener will receive notification of pixel1933* updates as images and thumbnails are decoded, including the1934* starts and ends of progressive passes.1935*1936* <p> If no update listeners are present, the reader may choose1937* to perform fewer updates to the pixels of the destination1938* images and/or thumbnails, which may result in more efficient1939* decoding.1940*1941* <p> For example, in progressive JPEG decoding each pass1942* contains updates to a set of coefficients, which would have to1943* be transformed into pixel values and converted to an RGB color1944* space for each pass if listeners are present. If no listeners1945* are present, the coefficients may simply be accumulated and the1946* final results transformed and color converted one time only.1947*1948* <p> The final results of decoding will be the same whether or1949* not intermediate updates are performed. Thus if only the final1950* image is desired it may be preferable not to register any1951* <code>IIOReadUpdateListener</code>s. In general, progressive1952* updating is most effective when fetching images over a network1953* connection that is very slow compared to local CPU processing;1954* over a fast connection, progressive updates may actually slow1955* down the presentation of the image.1956*1957* @param listener an IIOReadUpdateListener to be registered.1958*1959* @see #removeIIOReadUpdateListener1960*/1961public void1962addIIOReadUpdateListener(IIOReadUpdateListener listener) {1963if (listener == null) {1964return;1965}1966updateListeners = addToList(updateListeners, listener);1967}19681969/**1970* Removes an <code>IIOReadUpdateListener</code> from the list of1971* registered update listeners. If the listener was not1972* previously registered, or if <code>listener</code> is1973* <code>null</code>, no exception will be thrown and no action1974* will be taken.1975*1976* @param listener an IIOReadUpdateListener to be unregistered.1977*1978* @see #addIIOReadUpdateListener1979*/1980public void removeIIOReadUpdateListener(IIOReadUpdateListener listener) {1981if (listener == null || updateListeners == null) {1982return;1983}1984updateListeners = removeFromList(updateListeners, listener);1985}19861987/**1988* Removes all currently registered1989* <code>IIOReadUpdateListener</code> objects.1990*1991* <p> The default implementation sets the1992* <code>updateListeners</code> instance variable to1993* <code>null</code>.1994*/1995public void removeAllIIOReadUpdateListeners() {1996updateListeners = null;1997}19981999/**2000* Broadcasts the start of an sequence of image reads to all2001* registered <code>IIOReadProgressListener</code>s by calling2002* their <code>sequenceStarted</code> method. Subclasses may use2003* this method as a convenience.2004*2005* @param minIndex the lowest index being read.2006*/2007protected void processSequenceStarted(int minIndex) {2008if (progressListeners == null) {2009return;2010}2011int numListeners = progressListeners.size();2012for (int i = 0; i < numListeners; i++) {2013IIOReadProgressListener listener =2014(IIOReadProgressListener)progressListeners.get(i);2015listener.sequenceStarted(this, minIndex);2016}2017}20182019/**2020* Broadcasts the completion of an sequence of image reads to all2021* registered <code>IIOReadProgressListener</code>s by calling2022* their <code>sequenceComplete</code> method. Subclasses may use2023* this method as a convenience.2024*/2025protected void processSequenceComplete() {2026if (progressListeners == null) {2027return;2028}2029int numListeners = progressListeners.size();2030for (int i = 0; i < numListeners; i++) {2031IIOReadProgressListener listener =2032(IIOReadProgressListener)progressListeners.get(i);2033listener.sequenceComplete(this);2034}2035}20362037/**2038* Broadcasts the start of an image read to all registered2039* <code>IIOReadProgressListener</code>s by calling their2040* <code>imageStarted</code> method. Subclasses may use this2041* method as a convenience.2042*2043* @param imageIndex the index of the image about to be read.2044*/2045protected void processImageStarted(int imageIndex) {2046if (progressListeners == null) {2047return;2048}2049int numListeners = progressListeners.size();2050for (int i = 0; i < numListeners; i++) {2051IIOReadProgressListener listener =2052(IIOReadProgressListener)progressListeners.get(i);2053listener.imageStarted(this, imageIndex);2054}2055}20562057/**2058* Broadcasts the current percentage of image completion to all2059* registered <code>IIOReadProgressListener</code>s by calling2060* their <code>imageProgress</code> method. Subclasses may use2061* this method as a convenience.2062*2063* @param percentageDone the current percentage of completion,2064* as a <code>float</code>.2065*/2066protected void processImageProgress(float percentageDone) {2067if (progressListeners == null) {2068return;2069}2070int numListeners = progressListeners.size();2071for (int i = 0; i < numListeners; i++) {2072IIOReadProgressListener listener =2073(IIOReadProgressListener)progressListeners.get(i);2074listener.imageProgress(this, percentageDone);2075}2076}20772078/**2079* Broadcasts the completion of an image read to all registered2080* <code>IIOReadProgressListener</code>s by calling their2081* <code>imageComplete</code> method. Subclasses may use this2082* method as a convenience.2083*/2084protected void processImageComplete() {2085if (progressListeners == null) {2086return;2087}2088int numListeners = progressListeners.size();2089for (int i = 0; i < numListeners; i++) {2090IIOReadProgressListener listener =2091(IIOReadProgressListener)progressListeners.get(i);2092listener.imageComplete(this);2093}2094}20952096/**2097* Broadcasts the start of a thumbnail read to all registered2098* <code>IIOReadProgressListener</code>s by calling their2099* <code>thumbnailStarted</code> method. Subclasses may use this2100* method as a convenience.2101*2102* @param imageIndex the index of the image associated with the2103* thumbnail.2104* @param thumbnailIndex the index of the thumbnail.2105*/2106protected void processThumbnailStarted(int imageIndex,2107int thumbnailIndex) {2108if (progressListeners == null) {2109return;2110}2111int numListeners = progressListeners.size();2112for (int i = 0; i < numListeners; i++) {2113IIOReadProgressListener listener =2114(IIOReadProgressListener)progressListeners.get(i);2115listener.thumbnailStarted(this, imageIndex, thumbnailIndex);2116}2117}21182119/**2120* Broadcasts the current percentage of thumbnail completion to2121* all registered <code>IIOReadProgressListener</code>s by calling2122* their <code>thumbnailProgress</code> method. Subclasses may2123* use this method as a convenience.2124*2125* @param percentageDone the current percentage of completion,2126* as a <code>float</code>.2127*/2128protected void processThumbnailProgress(float percentageDone) {2129if (progressListeners == null) {2130return;2131}2132int numListeners = progressListeners.size();2133for (int i = 0; i < numListeners; i++) {2134IIOReadProgressListener listener =2135(IIOReadProgressListener)progressListeners.get(i);2136listener.thumbnailProgress(this, percentageDone);2137}2138}21392140/**2141* Broadcasts the completion of a thumbnail read to all registered2142* <code>IIOReadProgressListener</code>s by calling their2143* <code>thumbnailComplete</code> method. Subclasses may use this2144* method as a convenience.2145*/2146protected void processThumbnailComplete() {2147if (progressListeners == null) {2148return;2149}2150int numListeners = progressListeners.size();2151for (int i = 0; i < numListeners; i++) {2152IIOReadProgressListener listener =2153(IIOReadProgressListener)progressListeners.get(i);2154listener.thumbnailComplete(this);2155}2156}21572158/**2159* Broadcasts that the read has been aborted to all registered2160* <code>IIOReadProgressListener</code>s by calling their2161* <code>readAborted</code> method. Subclasses may use this2162* method as a convenience.2163*/2164protected void processReadAborted() {2165if (progressListeners == null) {2166return;2167}2168int numListeners = progressListeners.size();2169for (int i = 0; i < numListeners; i++) {2170IIOReadProgressListener listener =2171(IIOReadProgressListener)progressListeners.get(i);2172listener.readAborted(this);2173}2174}21752176/**2177* Broadcasts the beginning of a progressive pass to all2178* registered <code>IIOReadUpdateListener</code>s by calling their2179* <code>passStarted</code> method. Subclasses may use this2180* method as a convenience.2181*2182* @param theImage the <code>BufferedImage</code> being updated.2183* @param pass the index of the current pass, starting with 0.2184* @param minPass the index of the first pass that will be decoded.2185* @param maxPass the index of the last pass that will be decoded.2186* @param minX the X coordinate of the upper-left pixel included2187* in the pass.2188* @param minY the X coordinate of the upper-left pixel included2189* in the pass.2190* @param periodX the horizontal separation between pixels.2191* @param periodY the vertical separation between pixels.2192* @param bands an array of <code>int</code>s indicating the2193* set of affected bands of the destination.2194*/2195protected void processPassStarted(BufferedImage theImage,2196int pass,2197int minPass, int maxPass,2198int minX, int minY,2199int periodX, int periodY,2200int[] bands) {2201if (updateListeners == null) {2202return;2203}2204int numListeners = updateListeners.size();2205for (int i = 0; i < numListeners; i++) {2206IIOReadUpdateListener listener =2207(IIOReadUpdateListener)updateListeners.get(i);2208listener.passStarted(this, theImage, pass,2209minPass,2210maxPass,2211minX, minY,2212periodX, periodY,2213bands);2214}2215}22162217/**2218* Broadcasts the update of a set of samples to all registered2219* <code>IIOReadUpdateListener</code>s by calling their2220* <code>imageUpdate</code> method. Subclasses may use this2221* method as a convenience.2222*2223* @param theImage the <code>BufferedImage</code> being updated.2224* @param minX the X coordinate of the upper-left pixel included2225* in the pass.2226* @param minY the X coordinate of the upper-left pixel included2227* in the pass.2228* @param width the total width of the area being updated, including2229* pixels being skipped if <code>periodX > 1</code>.2230* @param height the total height of the area being updated,2231* including pixels being skipped if <code>periodY > 1</code>.2232* @param periodX the horizontal separation between pixels.2233* @param periodY the vertical separation between pixels.2234* @param bands an array of <code>int</code>s indicating the2235* set of affected bands of the destination.2236*/2237protected void processImageUpdate(BufferedImage theImage,2238int minX, int minY,2239int width, int height,2240int periodX, int periodY,2241int[] bands) {2242if (updateListeners == null) {2243return;2244}2245int numListeners = updateListeners.size();2246for (int i = 0; i < numListeners; i++) {2247IIOReadUpdateListener listener =2248(IIOReadUpdateListener)updateListeners.get(i);2249listener.imageUpdate(this,2250theImage,2251minX, minY,2252width, height,2253periodX, periodY,2254bands);2255}2256}22572258/**2259* Broadcasts the end of a progressive pass to all2260* registered <code>IIOReadUpdateListener</code>s by calling their2261* <code>passComplete</code> method. Subclasses may use this2262* method as a convenience.2263*2264* @param theImage the <code>BufferedImage</code> being updated.2265*/2266protected void processPassComplete(BufferedImage theImage) {2267if (updateListeners == null) {2268return;2269}2270int numListeners = updateListeners.size();2271for (int i = 0; i < numListeners; i++) {2272IIOReadUpdateListener listener =2273(IIOReadUpdateListener)updateListeners.get(i);2274listener.passComplete(this, theImage);2275}2276}22772278/**2279* Broadcasts the beginning of a thumbnail progressive pass to all2280* registered <code>IIOReadUpdateListener</code>s by calling their2281* <code>thumbnailPassStarted</code> method. Subclasses may use this2282* method as a convenience.2283*2284* @param theThumbnail the <code>BufferedImage</code> thumbnail2285* being updated.2286* @param pass the index of the current pass, starting with 0.2287* @param minPass the index of the first pass that will be decoded.2288* @param maxPass the index of the last pass that will be decoded.2289* @param minX the X coordinate of the upper-left pixel included2290* in the pass.2291* @param minY the X coordinate of the upper-left pixel included2292* in the pass.2293* @param periodX the horizontal separation between pixels.2294* @param periodY the vertical separation between pixels.2295* @param bands an array of <code>int</code>s indicating the2296* set of affected bands of the destination.2297*/2298protected void processThumbnailPassStarted(BufferedImage theThumbnail,2299int pass,2300int minPass, int maxPass,2301int minX, int minY,2302int periodX, int periodY,2303int[] bands) {2304if (updateListeners == null) {2305return;2306}2307int numListeners = updateListeners.size();2308for (int i = 0; i < numListeners; i++) {2309IIOReadUpdateListener listener =2310(IIOReadUpdateListener)updateListeners.get(i);2311listener.thumbnailPassStarted(this, theThumbnail, pass,2312minPass,2313maxPass,2314minX, minY,2315periodX, periodY,2316bands);2317}2318}23192320/**2321* Broadcasts the update of a set of samples in a thumbnail image2322* to all registered <code>IIOReadUpdateListener</code>s by2323* calling their <code>thumbnailUpdate</code> method. Subclasses may2324* use this method as a convenience.2325*2326* @param theThumbnail the <code>BufferedImage</code> thumbnail2327* being updated.2328* @param minX the X coordinate of the upper-left pixel included2329* in the pass.2330* @param minY the X coordinate of the upper-left pixel included2331* in the pass.2332* @param width the total width of the area being updated, including2333* pixels being skipped if <code>periodX > 1</code>.2334* @param height the total height of the area being updated,2335* including pixels being skipped if <code>periodY > 1</code>.2336* @param periodX the horizontal separation between pixels.2337* @param periodY the vertical separation between pixels.2338* @param bands an array of <code>int</code>s indicating the2339* set of affected bands of the destination.2340*/2341protected void processThumbnailUpdate(BufferedImage theThumbnail,2342int minX, int minY,2343int width, int height,2344int periodX, int periodY,2345int[] bands) {2346if (updateListeners == null) {2347return;2348}2349int numListeners = updateListeners.size();2350for (int i = 0; i < numListeners; i++) {2351IIOReadUpdateListener listener =2352(IIOReadUpdateListener)updateListeners.get(i);2353listener.thumbnailUpdate(this,2354theThumbnail,2355minX, minY,2356width, height,2357periodX, periodY,2358bands);2359}2360}23612362/**2363* Broadcasts the end of a thumbnail progressive pass to all2364* registered <code>IIOReadUpdateListener</code>s by calling their2365* <code>thumbnailPassComplete</code> method. Subclasses may use this2366* method as a convenience.2367*2368* @param theThumbnail the <code>BufferedImage</code> thumbnail2369* being updated.2370*/2371protected void processThumbnailPassComplete(BufferedImage theThumbnail) {2372if (updateListeners == null) {2373return;2374}2375int numListeners = updateListeners.size();2376for (int i = 0; i < numListeners; i++) {2377IIOReadUpdateListener listener =2378(IIOReadUpdateListener)updateListeners.get(i);2379listener.thumbnailPassComplete(this, theThumbnail);2380}2381}23822383/**2384* Broadcasts a warning message to all registered2385* <code>IIOReadWarningListener</code>s by calling their2386* <code>warningOccurred</code> method. Subclasses may use this2387* method as a convenience.2388*2389* @param warning the warning message to send.2390*2391* @exception IllegalArgumentException if <code>warning</code>2392* is <code>null</code>.2393*/2394protected void processWarningOccurred(String warning) {2395if (warningListeners == null) {2396return;2397}2398if (warning == null) {2399throw new IllegalArgumentException("warning == null!");2400}2401int numListeners = warningListeners.size();2402for (int i = 0; i < numListeners; i++) {2403IIOReadWarningListener listener =2404(IIOReadWarningListener)warningListeners.get(i);24052406listener.warningOccurred(this, warning);2407}2408}24092410/**2411* Broadcasts a localized warning message to all registered2412* <code>IIOReadWarningListener</code>s by calling their2413* <code>warningOccurred</code> method with a string taken2414* from a <code>ResourceBundle</code>. Subclasses may use this2415* method as a convenience.2416*2417* @param baseName the base name of a set of2418* <code>ResourceBundle</code>s containing localized warning2419* messages.2420* @param keyword the keyword used to index the warning message2421* within the set of <code>ResourceBundle</code>s.2422*2423* @exception IllegalArgumentException if <code>baseName</code>2424* is <code>null</code>.2425* @exception IllegalArgumentException if <code>keyword</code>2426* is <code>null</code>.2427* @exception IllegalArgumentException if no appropriate2428* <code>ResourceBundle</code> may be located.2429* @exception IllegalArgumentException if the named resource is2430* not found in the located <code>ResourceBundle</code>.2431* @exception IllegalArgumentException if the object retrieved2432* from the <code>ResourceBundle</code> is not a2433* <code>String</code>.2434*/2435protected void processWarningOccurred(String baseName,2436String keyword) {2437if (warningListeners == null) {2438return;2439}2440if (baseName == null) {2441throw new IllegalArgumentException("baseName == null!");2442}2443if (keyword == null) {2444throw new IllegalArgumentException("keyword == null!");2445}2446int numListeners = warningListeners.size();2447for (int i = 0; i < numListeners; i++) {2448IIOReadWarningListener listener =2449(IIOReadWarningListener)warningListeners.get(i);2450Locale locale = (Locale)warningLocales.get(i);2451if (locale == null) {2452locale = Locale.getDefault();2453}24542455/**2456* If an applet supplies an implementation of ImageReader and2457* resource bundles, then the resource bundle will need to be2458* accessed via the applet class loader. So first try the context2459* class loader to locate the resource bundle.2460* If that throws MissingResourceException, then try the2461* system class loader.2462*/2463ClassLoader loader = (ClassLoader)2464java.security.AccessController.doPrivileged(2465new java.security.PrivilegedAction() {2466public Object run() {2467return Thread.currentThread().getContextClassLoader();2468}2469});24702471ResourceBundle bundle = null;2472try {2473bundle = ResourceBundle.getBundle(baseName, locale, loader);2474} catch (MissingResourceException mre) {2475try {2476bundle = ResourceBundle.getBundle(baseName, locale);2477} catch (MissingResourceException mre1) {2478throw new IllegalArgumentException("Bundle not found!");2479}2480}24812482String warning = null;2483try {2484warning = bundle.getString(keyword);2485} catch (ClassCastException cce) {2486throw new IllegalArgumentException("Resource is not a String!");2487} catch (MissingResourceException mre) {2488throw new IllegalArgumentException("Resource is missing!");2489}24902491listener.warningOccurred(this, warning);2492}2493}24942495// State management24962497/**2498* Restores the <code>ImageReader</code> to its initial state.2499*2500* <p> The default implementation calls <code>setInput(null,2501* false)</code>, <code>setLocale(null)</code>,2502* <code>removeAllIIOReadUpdateListeners()</code>,2503* <code>removeAllIIOReadWarningListeners()</code>,2504* <code>removeAllIIOReadProgressListeners()</code>, and2505* <code>clearAbortRequest</code>.2506*/2507public void reset() {2508setInput(null, false, false);2509setLocale(null);2510removeAllIIOReadUpdateListeners();2511removeAllIIOReadProgressListeners();2512removeAllIIOReadWarningListeners();2513clearAbortRequest();2514}25152516/**2517* Allows any resources held by this object to be released. The2518* result of calling any other method (other than2519* <code>finalize</code>) subsequent to a call to this method2520* is undefined.2521*2522* <p>It is important for applications to call this method when they2523* know they will no longer be using this <code>ImageReader</code>.2524* Otherwise, the reader may continue to hold on to resources2525* indefinitely.2526*2527* <p>The default implementation of this method in the superclass does2528* nothing. Subclass implementations should ensure that all resources,2529* especially native resources, are released.2530*/2531public void dispose() {2532}25332534// Utility methods25352536/**2537* A utility method that may be used by readers to compute the2538* region of the source image that should be read, taking into2539* account any source region and subsampling offset settings in2540* the supplied <code>ImageReadParam</code>. The actual2541* subsampling factors, destination size, and destination offset2542* are <em>not</em> taken into consideration, thus further2543* clipping must take place. The {@link #computeRegions computeRegions}2544* method performs all necessary clipping.2545*2546* @param param the <code>ImageReadParam</code> being used, or2547* <code>null</code>.2548* @param srcWidth the width of the source image.2549* @param srcHeight the height of the source image.2550*2551* @return the source region as a <code>Rectangle</code>.2552*/2553protected static Rectangle getSourceRegion(ImageReadParam param,2554int srcWidth,2555int srcHeight) {2556Rectangle sourceRegion = new Rectangle(0, 0, srcWidth, srcHeight);2557if (param != null) {2558Rectangle region = param.getSourceRegion();2559if (region != null) {2560sourceRegion = sourceRegion.intersection(region);2561}25622563int subsampleXOffset = param.getSubsamplingXOffset();2564int subsampleYOffset = param.getSubsamplingYOffset();2565sourceRegion.x += subsampleXOffset;2566sourceRegion.y += subsampleYOffset;2567sourceRegion.width -= subsampleXOffset;2568sourceRegion.height -= subsampleYOffset;2569}25702571return sourceRegion;2572}25732574/**2575* Computes the source region of interest and the destination2576* region of interest, taking the width and height of the source2577* image, an optional destination image, and an optional2578* <code>ImageReadParam</code> into account. The source region2579* begins with the entire source image. Then that is clipped to2580* the source region specified in the <code>ImageReadParam</code>,2581* if one is specified.2582*2583* <p> If either of the destination offsets are negative, the2584* source region is clipped so that its top left will coincide2585* with the top left of the destination image, taking subsampling2586* into account. Then the result is clipped to the destination2587* image on the right and bottom, if one is specified, taking2588* subsampling and destination offsets into account.2589*2590* <p> Similarly, the destination region begins with the source2591* image, is translated to the destination offset given in the2592* <code>ImageReadParam</code> if there is one, and finally is2593* clipped to the destination image, if there is one.2594*2595* <p> If either the source or destination regions end up having a2596* width or height of 0, an <code>IllegalArgumentException</code>2597* is thrown.2598*2599* <p> The {@link #getSourceRegion getSourceRegion>}2600* method may be used if only source clipping is desired.2601*2602* @param param an <code>ImageReadParam</code>, or <code>null</code>.2603* @param srcWidth the width of the source image.2604* @param srcHeight the height of the source image.2605* @param image a <code>BufferedImage</code> that will be the2606* destination image, or <code>null</code>.2607* @param srcRegion a <code>Rectangle</code> that will be filled with2608* the source region of interest.2609* @param destRegion a <code>Rectangle</code> that will be filled with2610* the destination region of interest.2611* @exception IllegalArgumentException if <code>srcRegion</code>2612* is <code>null</code>.2613* @exception IllegalArgumentException if <code>dstRegion</code>2614* is <code>null</code>.2615* @exception IllegalArgumentException if the resulting source or2616* destination region is empty.2617*/2618protected static void computeRegions(ImageReadParam param,2619int srcWidth,2620int srcHeight,2621BufferedImage image,2622Rectangle srcRegion,2623Rectangle destRegion) {2624if (srcRegion == null) {2625throw new IllegalArgumentException("srcRegion == null!");2626}2627if (destRegion == null) {2628throw new IllegalArgumentException("destRegion == null!");2629}26302631// Start with the entire source image2632srcRegion.setBounds(0, 0, srcWidth, srcHeight);26332634// Destination also starts with source image, as that is the2635// maximum extent if there is no subsampling2636destRegion.setBounds(0, 0, srcWidth, srcHeight);26372638// Clip that to the param region, if there is one2639int periodX = 1;2640int periodY = 1;2641int gridX = 0;2642int gridY = 0;2643if (param != null) {2644Rectangle paramSrcRegion = param.getSourceRegion();2645if (paramSrcRegion != null) {2646srcRegion.setBounds(srcRegion.intersection(paramSrcRegion));2647}2648periodX = param.getSourceXSubsampling();2649periodY = param.getSourceYSubsampling();2650gridX = param.getSubsamplingXOffset();2651gridY = param.getSubsamplingYOffset();2652srcRegion.translate(gridX, gridY);2653srcRegion.width -= gridX;2654srcRegion.height -= gridY;2655destRegion.setLocation(param.getDestinationOffset());2656}26572658// Now clip any negative destination offsets, i.e. clip2659// to the top and left of the destination image2660if (destRegion.x < 0) {2661int delta = -destRegion.x*periodX;2662srcRegion.x += delta;2663srcRegion.width -= delta;2664destRegion.x = 0;2665}2666if (destRegion.y < 0) {2667int delta = -destRegion.y*periodY;2668srcRegion.y += delta;2669srcRegion.height -= delta;2670destRegion.y = 0;2671}26722673// Now clip the destination Region to the subsampled width and height2674int subsampledWidth = (srcRegion.width + periodX - 1)/periodX;2675int subsampledHeight = (srcRegion.height + periodY - 1)/periodY;2676destRegion.width = subsampledWidth;2677destRegion.height = subsampledHeight;26782679// Now clip that to right and bottom of the destination image,2680// if there is one, taking subsampling into account2681if (image != null) {2682Rectangle destImageRect = new Rectangle(0, 0,2683image.getWidth(),2684image.getHeight());2685destRegion.setBounds(destRegion.intersection(destImageRect));2686if (destRegion.isEmpty()) {2687throw new IllegalArgumentException2688("Empty destination region!");2689}26902691int deltaX = destRegion.x + subsampledWidth - image.getWidth();2692if (deltaX > 0) {2693srcRegion.width -= deltaX*periodX;2694}2695int deltaY = destRegion.y + subsampledHeight - image.getHeight();2696if (deltaY > 0) {2697srcRegion.height -= deltaY*periodY;2698}2699}2700if (srcRegion.isEmpty() || destRegion.isEmpty()) {2701throw new IllegalArgumentException("Empty region!");2702}2703}27042705/**2706* A utility method that may be used by readers to test the2707* validity of the source and destination band settings of an2708* <code>ImageReadParam</code>. This method may be called as soon2709* as the reader knows both the number of bands of the source2710* image as it exists in the input stream, and the number of bands2711* of the destination image that being written.2712*2713* <p> The method retrieves the source and destination band2714* setting arrays from param using the <code>getSourceBands</code>2715* and <code>getDestinationBands</code>methods (or considers them2716* to be <code>null</code> if <code>param</code> is2717* <code>null</code>). If the source band setting array is2718* <code>null</code>, it is considered to be equal to the array2719* <code>{ 0, 1, ..., numSrcBands - 1 }</code>, and similarly for2720* the destination band setting array.2721*2722* <p> The method then tests that both arrays are equal in length,2723* and that neither array contains a value larger than the largest2724* available band index.2725*2726* <p> Any failure results in an2727* <code>IllegalArgumentException</code> being thrown; success2728* results in the method returning silently.2729*2730* @param param the <code>ImageReadParam</code> being used to read2731* the image.2732* @param numSrcBands the number of bands of the image as it exists2733* int the input source.2734* @param numDstBands the number of bands in the destination image2735* being written.2736*2737* @exception IllegalArgumentException if <code>param</code>2738* contains an invalid specification of a source and/or2739* destination band subset.2740*/2741protected static void checkReadParamBandSettings(ImageReadParam param,2742int numSrcBands,2743int numDstBands) {2744// A null param is equivalent to srcBands == dstBands == null.2745int[] srcBands = null;2746int[] dstBands = null;2747if (param != null) {2748srcBands = param.getSourceBands();2749dstBands = param.getDestinationBands();2750}27512752int paramSrcBandLength =2753(srcBands == null) ? numSrcBands : srcBands.length;2754int paramDstBandLength =2755(dstBands == null) ? numDstBands : dstBands.length;27562757if (paramSrcBandLength != paramDstBandLength) {2758throw new IllegalArgumentException("ImageReadParam num source & dest bands differ!");2759}27602761if (srcBands != null) {2762for (int i = 0; i < srcBands.length; i++) {2763if (srcBands[i] >= numSrcBands) {2764throw new IllegalArgumentException("ImageReadParam source bands contains a value >= the number of source bands!");2765}2766}2767}27682769if (dstBands != null) {2770for (int i = 0; i < dstBands.length; i++) {2771if (dstBands[i] >= numDstBands) {2772throw new IllegalArgumentException("ImageReadParam dest bands contains a value >= the number of dest bands!");2773}2774}2775}2776}27772778/**2779* Returns the <code>BufferedImage</code> to which decoded pixel2780* data should be written. The image is determined by inspecting2781* the supplied <code>ImageReadParam</code> if it is2782* non-<code>null</code>; if its <code>getDestination</code>2783* method returns a non-<code>null</code> value, that image is2784* simply returned. Otherwise,2785* <code>param.getDestinationType</code> method is called to2786* determine if a particular image type has been specified. If2787* so, the returned <code>ImageTypeSpecifier</code> is used after2788* checking that it is equal to one of those included in2789* <code>imageTypes</code>.2790*2791* <p> If <code>param</code> is <code>null</code> or the above2792* steps have not yielded an image or an2793* <code>ImageTypeSpecifier</code>, the first value obtained from2794* the <code>imageTypes</code> parameter is used. Typically, the2795* caller will set <code>imageTypes</code> to the value of2796* <code>getImageTypes(imageIndex)</code>.2797*2798* <p> Next, the dimensions of the image are determined by a call2799* to <code>computeRegions</code>. The actual width and height of2800* the image being decoded are passed in as the <code>width</code>2801* and <code>height</code> parameters.2802*2803* @param param an <code>ImageReadParam</code> to be used to get2804* the destination image or image type, or <code>null</code>.2805* @param imageTypes an <code>Iterator</code> of2806* <code>ImageTypeSpecifier</code>s indicating the legal image2807* types, with the default first.2808* @param width the true width of the image or tile begin decoded.2809* @param height the true width of the image or tile being decoded.2810*2811* @return the <code>BufferedImage</code> to which decoded pixel2812* data should be written.2813*2814* @exception IIOException if the <code>ImageTypeSpecifier</code>2815* specified by <code>param</code> does not match any of the legal2816* ones from <code>imageTypes</code>.2817* @exception IllegalArgumentException if <code>imageTypes</code>2818* is <code>null</code> or empty, or if an object not of type2819* <code>ImageTypeSpecifier</code> is retrieved from it.2820* @exception IllegalArgumentException if the resulting image would2821* have a width or height less than 1.2822* @exception IllegalArgumentException if the product of2823* <code>width</code> and <code>height</code> is greater than2824* <code>Integer.MAX_VALUE</code>.2825*/2826protected static BufferedImage2827getDestination(ImageReadParam param,2828Iterator<ImageTypeSpecifier> imageTypes,2829int width, int height)2830throws IIOException {2831if (imageTypes == null || !imageTypes.hasNext()) {2832throw new IllegalArgumentException("imageTypes null or empty!");2833}2834if ((long)width*height > Integer.MAX_VALUE) {2835throw new IllegalArgumentException2836("width*height > Integer.MAX_VALUE!");2837}28382839BufferedImage dest = null;2840ImageTypeSpecifier imageType = null;28412842// If param is non-null, use it2843if (param != null) {2844// Try to get the image itself2845dest = param.getDestination();2846if (dest != null) {2847return dest;2848}28492850// No image, get the image type2851imageType = param.getDestinationType();2852}28532854// No info from param, use fallback image type2855if (imageType == null) {2856Object o = imageTypes.next();2857if (!(o instanceof ImageTypeSpecifier)) {2858throw new IllegalArgumentException2859("Non-ImageTypeSpecifier retrieved from imageTypes!");2860}2861imageType = (ImageTypeSpecifier)o;2862} else {2863boolean foundIt = false;2864while (imageTypes.hasNext()) {2865ImageTypeSpecifier type =2866(ImageTypeSpecifier)imageTypes.next();2867if (type.equals(imageType)) {2868foundIt = true;2869break;2870}2871}28722873if (!foundIt) {2874throw new IIOException2875("Destination type from ImageReadParam does not match!");2876}2877}28782879Rectangle srcRegion = new Rectangle(0,0,0,0);2880Rectangle destRegion = new Rectangle(0,0,0,0);2881computeRegions(param,2882width,2883height,2884null,2885srcRegion,2886destRegion);28872888int destWidth = destRegion.x + destRegion.width;2889int destHeight = destRegion.y + destRegion.height;2890// Create a new image based on the type specifier2891return imageType.createBufferedImage(destWidth, destHeight);2892}2893}289428952896