History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/imageio/ImageReader.java (1 of 18352 files). Show all

Unified · Split

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