/[classpath]/classpath/javax/imageio/ImageReader.java
ViewVC logotype

Diff of /classpath/javax/imageio/ImageReader.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.2.3 by gnu_andrew, Tue Aug 2 20:12:35 2005 UTC revision 1.1.2.4 by gnu_andrew, Wed Nov 2 00:43:39 2005 UTC
# Line 1  Line 1 
1  /* ImageReader.java -- Decodes raster images.  /* ImageReader.java -- Decodes raster images.
2     Copyright (C) 2004  Free Software Foundation, Inc.     Copyright (C) 2004, 2005  Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 38  exception statement from your version. * Line 38  exception statement from your version. *
38    
39  package javax.imageio;  package javax.imageio;
40    
41    import java.awt.Point;
42    import java.awt.Rectangle;
43  import java.awt.image.BufferedImage;  import java.awt.image.BufferedImage;
44  import java.awt.image.Raster;  import java.awt.image.Raster;
45    import java.awt.image.RenderedImage;
46  import java.io.IOException;  import java.io.IOException;
47  import java.util.ArrayList;  import java.util.ArrayList;
48  import java.util.Iterator;  import java.util.Iterator;
49  import java.util.List;  import java.util.List;
50  import java.util.Locale;  import java.util.Locale;
51    import java.util.ResourceBundle;
52    import java.util.MissingResourceException;
53    import java.util.Set;
54    
55  import javax.imageio.event.IIOReadProgressListener;  import javax.imageio.event.IIOReadProgressListener;
56  import javax.imageio.event.IIOReadUpdateListener;  import javax.imageio.event.IIOReadUpdateListener;
# Line 53  import javax.imageio.metadata.IIOMetadat Line 59  import javax.imageio.metadata.IIOMetadat
59  import javax.imageio.spi.ImageReaderSpi;  import javax.imageio.spi.ImageReaderSpi;
60  import javax.imageio.stream.ImageInputStream;  import javax.imageio.stream.ImageInputStream;
61    
62    /**
63     * A class for decoding images within the ImageIO framework.
64     *
65     * An ImageReader for a given format is instantiated by an
66     * ImageReaderSpi for that format.  ImageReaderSpis are registered
67     * with the IIORegistry.
68     *
69     * The ImageReader API supports reading animated images that may have
70     * multiple frames; to support such images many methods take an index
71     * parameter.
72     *
73     * Images may also be read in multiple passes, where each successive
74     * pass increases the level of detail in the destination image.
75     */
76  public abstract class ImageReader  public abstract class ImageReader
77  {  {
78    private boolean aborted;    private boolean aborted;
     
   protected Locale[] availableLocales;  
   protected boolean ignoreMetadata;  
   protected Object input;  
   protected Locale locale;  
   protected int minIndex;  
   protected ImageReaderSpi originatingProvider;  
   protected List progressListeners = new ArrayList();  
   protected boolean seekForwardOnly;  
   protected List updateListeners = new ArrayList();  
   protected List warningListeners = new ArrayList();  
   protected List warningLocales = new ArrayList();  
79    
80      /**
81       * All locales available for localization of warning messages, or
82       * null if localization is not supported.
83       */
84      protected Locale[] availableLocales = null;
85    
86      /**
87       * true if the input source does not require metadata to be read,
88       * false otherwise.
89       */
90      protected boolean ignoreMetadata = false;
91    
92      /**
93       * An ImageInputStream from which image data is read.
94       */
95      protected Object input = null;
96    
97      /**
98       * The current locale used to localize warning messages, or null if
99       * no locale has been set.
100       */
101      protected Locale locale = null;
102    
103      /**
104       * The minimum index at which data can be read.  Constantly 0 if
105       * seekForwardOnly is false, always increasing if seekForwardOnly is
106       * true.
107       */
108      protected int minIndex = 0;
109    
110      /**
111       * The image reader SPI that instantiated this reader.
112       */
113      protected ImageReaderSpi originatingProvider = null;
114    
115      /**
116       * A list of installed progress listeners.  Initially null, meaning
117       * no installed listeners.
118       */
119      protected List progressListeners = null;
120    
121      /**
122       * true if this reader should only read data further ahead in the
123       * stream than its current location.  false if it can read backwards
124       * in the stream.  If this is true then caching can be avoided.
125       */
126      protected boolean seekForwardOnly = false;
127    
128      /**
129       * A list of installed update listeners.  Initially null, meaning no
130       * installed listeners.
131       */
132      protected List updateListeners = null;
133    
134      /**
135       * A list of installed warning listeners.  Initially null, meaning
136       * no installed listeners.
137       */
138      protected List warningListeners = null;
139    
140      /**
141       * A list of warning locales corresponding with the list of
142       * installed warning listeners.  Initially null, meaning no locales.
143       */
144      protected List warningLocales = null;
145    
146      /**
147       * Construct an image reader.
148       *
149       * @param originatingProvider the provider that is constructing this
150       * image reader, or null
151       */
152    protected ImageReader(ImageReaderSpi originatingProvider)    protected ImageReader(ImageReaderSpi originatingProvider)
153    {    {
154      this.originatingProvider = originatingProvider;      this.originatingProvider = originatingProvider;
155    }    }
156    
157      /**
158       * Request that reading be aborted.  The unread contents of the
159       * image will be undefined.
160       *
161       * Readers should clear the abort flag before starting a read
162       * operation, then poll it periodically during the read operation.
163       */
164    public void abort()    public void abort()
165    {    {
166      aborted = true;      aborted = true;
167    }    }
168    
169      /**
170       * Check if the abort flag is set.
171       *
172       * @return true if the current read operation should be aborted,
173       * false otherwise
174       */
175    protected boolean abortRequested()    protected boolean abortRequested()
176    {    {
177      return aborted;      return aborted;
178    }    }
179    
180      /**
181       * Install a read progress listener.  This method will return
182       * immediately if listener is null.
183       *
184       * @param listener a read progress listener or null
185       */
186    public void addIIOReadProgressListener(IIOReadProgressListener listener)    public void addIIOReadProgressListener(IIOReadProgressListener listener)
187    {    {
188      if (listener == null)      if (listener == null)
189        return;        return;
190            if (progressListeners == null)
191      progressListeners.add(listener);            progressListeners = new ArrayList ();
192        progressListeners.add(listener);
193    }    }
194    
195      /**
196       * Install a read update listener.  This method will return
197       * immediately if listener is null.
198       *
199       * @param listener a read update listener
200       */
201    public void addIIOReadUpdateListener(IIOReadUpdateListener listener)    public void addIIOReadUpdateListener(IIOReadUpdateListener listener)
202    {    {
203      if (listener == null)      if (listener == null)
204        return;        return;
205            if (updateListeners == null)
206      updateListeners.add(listener);            updateListeners = new ArrayList ();
207        updateListeners.add(listener);
208    }    }
209      
210      /**
211       * Install a read warning listener.  This method will return
212       * immediately if listener is null.  Warning messages sent to this
213       * listener will be localized using the current locale.  If the
214       * current locale is null then this reader will select a sensible
215       * default.
216       *
217       * @param listener a read warning listener
218       */
219    public void addIIOReadWarningListener(IIOReadWarningListener listener)    public void addIIOReadWarningListener(IIOReadWarningListener listener)
220    {    {
221      if (listener == null)      if (listener == null)
222        return;        return;
223            if (warningListeners == null)
224      warningListeners.add(listener);            warningListeners = new ArrayList ();
225        warningListeners.add(listener);
226    }    }
227    
228      /**
229       * Check if this reader can handle raster data.  Determines whether
230       * or not readRaster and readTileRaster throw
231       * UnsupportedOperationException.
232       *
233       * @return true if this reader supports raster data, false if not
234       */
235    public boolean canReadRaster()    public boolean canReadRaster()
236    {    {
237      return false;      return false;
238    }    }
239    
240      /**
241       * Clear the abort flag.
242       */
243    protected void clearAbortRequest()    protected void clearAbortRequest()
244    {    {
245      aborted = false;      aborted = false;
246    }    }
247      
248      /**
249       * Releases any resources allocated to this object.  Subsequent
250       * calls to methods on this object will produce undefined results.
251       *
252       * The default implementation does nothing; subclasses should use
253       * this method ensure that native resources are released.
254       */
255    public void dispose()    public void dispose()
256    {    {
257      // The default implementation does nothing.      // The default implementation does nothing.
258    }    }
259      
260      /**
261       * Returns the aspect ratio of this image, the ration of its width
262       * to its height.  The aspect ratio is useful when resizing an image
263       * while keeping its proportions constant.
264       *
265       * @param imageIndex the frame index
266       *
267       * @return the image's aspect ratio
268       *
269       * @exception IllegalStateException if input is null
270       * @exception IndexOutOfBoundsException if the frame index is
271       * out-of-bounds
272       * @exception IOException if a read error occurs
273       */
274    public float getAspectRatio(int imageIndex)    public float getAspectRatio(int imageIndex)
275      throws IOException      throws IOException
276    {    {
277        if (input == null)
278          throw new IllegalStateException("input is null");
279    
280      return (float) (getWidth(imageIndex) / getHeight(imageIndex));      return (float) (getWidth(imageIndex) / getHeight(imageIndex));
281    }    }
282    
283      /**
284       * Retrieve the available locales.  Return null if no locales are
285       * available or a clone of availableLocales.
286       *
287       * @return an array of locales or null
288       */
289    public Locale[] getAvailableLocales()    public Locale[] getAvailableLocales()
290    {    {
291      if (availableLocales == null)      if (availableLocales == null)
# Line 137  public abstract class ImageReader Line 294  public abstract class ImageReader
294      return (Locale[]) availableLocales.clone();      return (Locale[]) availableLocales.clone();
295    }    }
296    
297      /**
298       * Retrieve the default read parameters for this reader's image
299       * format.
300       *
301       * The default implementation returns new ImageReadParam().
302       *
303       * @return image reading parameters
304       */
305    public ImageReadParam getDefaultReadParam()    public ImageReadParam getDefaultReadParam()
306    {    {
307      return new ImageReadParam();      return new ImageReadParam();
308    }    }
309    
310      /**
311       * Retrieve the format of the input source.
312       *
313       * @return the input source format name
314       *
315       * @exception IOException if a read error occurs
316       */
317    public String getFormatName()    public String getFormatName()
318      throws IOException      throws IOException
319    {    {
320      return originatingProvider.getFormatNames()[0];      return originatingProvider.getFormatNames()[0];
321    }    }
322    
323      /**
324       * Get the height of the input image in pixels.  If the input image
325       * is resizable then a default height is returned.
326       *
327       * @param imageIndex the frame index
328       *
329       * @return the height of the input image
330       *
331       * @exception IllegalStateException if input has not been set
332       * @exception IndexOutOfBoundsException if the frame index is
333       * out-of-bounds
334       * @exception IOException if a read error occurs
335       */
336    public abstract int getHeight(int imageIndex)    public abstract int getHeight(int imageIndex)
337      throws IOException;      throws IOException;
338    
339      /**
340       * Get the metadata associated with this image.  If the reader is
341       * set to ignore metadata or does not support reading metadata, or
342       * if no metadata is available then null is returned.
343       *
344       * @param imageIndex the frame index
345       *
346       * @return a metadata object, or null
347       *
348       * @exception IllegalStateException if input has not been set
349       * @exception IndexOutOfBoundsException if the frame index is
350       * out-of-bounds
351       * @exception IOException if a read error occurs
352       */
353    public abstract IIOMetadata getImageMetadata(int imageIndex)    public abstract IIOMetadata getImageMetadata(int imageIndex)
354      throws IOException;      throws IOException;
355    
356      /**
357       * Get an iterator over the collection of image types into which
358       * this reader can decode image data.  This method is guaranteed to
359       * return at least one valid image type specifier.
360       *
361       * The elements of the iterator should be ordered; the first element
362       * should be the most appropriate image type for this decoder,
363       * followed by the second-most appropriate, and so on.
364       *
365       * @param imageIndex the frame index
366       *
367       * @return an iterator over a collection of image type specifiers
368       *
369       * @exception IllegalStateException if input has not been set
370       * @exception IndexOutOfBoundsException if the frame index is
371       * out-of-bounds
372       * @exception IOException if a read error occurs
373       */
374    public abstract Iterator getImageTypes(int imageIndex)    public abstract Iterator getImageTypes(int imageIndex)
375      throws IOException;      throws IOException;
376    
377      /**
378       * Set the input source to the given object, specify whether this
379       * reader should be allowed to read input from the data stream more
380       * than once, and specify whether this reader should ignore metadata
381       * in the input stream.  The input source must be set before many
382       * methods can be called on this reader. (see all ImageReader
383       * methods that throw IllegalStateException).  If input is null then
384       * the current input source will be removed.
385       *
386       * Unless this reader has direct access with imaging hardware, input
387       * should be an ImageInputStream.
388       *
389       * @param input the input source object
390       * @param seekForwardOnly true if this reader should be allowed to
391       * read input from the data stream more than once, false otherwise
392       * @param ignoreMetadata true if this reader should ignore metadata
393       * associated with the input source, false otherwise
394       *
395       * @exception IllegalArgumentException if input is not a valid input
396       * source for this reader and is not an ImageInputStream
397       */
398    public void setInput(Object input,    public void setInput(Object input,
399                         boolean seekForwardOnly,                         boolean seekForwardOnly,
400                         boolean ignoreMetadata)                         boolean ignoreMetadata)
# Line 183  public abstract class ImageReader Line 421  public abstract class ImageReader
421      this.minIndex = 0;      this.minIndex = 0;
422    }    }
423    
424      /**
425       * Set the input source to the given object and specify whether this
426       * reader should be allowed to read input from the data stream more
427       * than once.  The input source must be set before many methods can
428       * be called on this reader. (see all ImageReader methods that throw
429       * IllegalStateException).  If input is null then the current input
430       * source will be removed.
431       *
432       * @param input the input source object
433       * @param seekForwardOnly true if this reader should be allowed to
434       * read input from the data stream more than once, false otherwise
435       *
436       * @exception IllegalArgumentException if input is not a valid input
437       * source for this reader and is not an ImageInputStream
438       */
439    public void setInput(Object in, boolean seekForwardOnly)    public void setInput(Object in, boolean seekForwardOnly)
440    {    {
441      setInput(in, seekForwardOnly, false);      setInput(in, seekForwardOnly, false);
442    }    }
443    
444    public void setInput(Object in)    /**
445    {     * Set the input source to the given object.  The input source must
446      setInput(in, false, false);     * be set before many methods can be called on this reader. (see all
447    }     * ImageReader methods that throw IllegalStateException).  If input
448       * is null then the current input source will be removed.
449       *
450       * @param input the input source object
451       *
452       * @exception IllegalArgumentException if input is not a valid input
453       * source for this reader and is not an ImageInputStream
454       */
455      public void setInput(Object input)
456      {
457        setInput(input, false, false);
458      }
459    
460      /**
461       * Get this reader's image input source.  null is returned if the
462       * image source has not been set.
463       *
464       * @return an image input source object, or null
465       */
466    public Object getInput()    public Object getInput()
467    {    {
468      return input;      return input;
469    }    }
470    
471      /**
472       * Get this reader's locale.  null is returned if the locale has not
473       * been set.
474       *
475       * @return this reader's locale, or null
476       */
477    public Locale getLocale()    public Locale getLocale()
478    {    {
479      return locale;      return locale;
480    }    }
481    
482      /**
483       * Return the number of images available from the image input
484       * source, not including thumbnails.  This method will return 1
485       * unless this reader is reading an animated image.
486       *
487       * Certain multi-image formats do not encode the total number of
488       * images.  When reading images in those formats it may be necessary
489       * to repeatedly call read, incrementing the image index at each
490       * call, until an IndexOutOfBoundsException is thrown.
491       *
492       * The allowSearch parameter determines whether all images must be
493       * available at all times.  When allowSearch is false, getNumImages
494       * will return -1 if the total number of images is unknown.
495       * Otherwise this method returns the number of images.
496       *
497       * @param allowSearch true if all images should be available at
498       * once, false otherwise
499       *
500       * @return -1 if allowSearch is false and the total number of images
501       * is currently unknown, or the number of images
502       *
503       * @exception IllegalStateException if input has not been set, or if
504       * seekForwardOnly is true
505       * @exception IOException if a read error occurs
506       */
507    public abstract int getNumImages(boolean allowSearch)    public abstract int getNumImages(boolean allowSearch)
508      throws IOException;      throws IOException;
509    
510      /**
511       * Get the number of thumbnails associated with an image.
512       *
513       * @param imageIndex the frame index
514       *
515       * @return the number of thumbnails associated with this image
516       */
517    public int getNumThumbnails(int imageIndex)    public int getNumThumbnails(int imageIndex)
518      throws IOException      throws IOException
519    {    {
520      return 0;      return 0;
521    }    }
522    
523      /**
524       * Get the ImageReaderSpi that created this reader or null.
525       *
526       * @return an ImageReaderSpi, or null
527       */
528    public ImageReaderSpi getOriginatingProvider()    public ImageReaderSpi getOriginatingProvider()
529    {    {
530      return originatingProvider;      return originatingProvider;
531    }    }
532    
533      /**
534       * Get the metadata associated with the image being read.  If the
535       * reader is set to ignore metadata or does not support reading
536       * metadata, or if no metadata is available then null is returned.
537       * This method returns metadata associated with the entirety of the
538       * image data, whereas getImageMetadata(int) returns metadata
539       * associated with a frame within a multi-image data stream.
540       *
541       * @return metadata associated with the image being read, or null
542       *
543       * @exception IOException if a read error occurs
544       */
545    public abstract IIOMetadata getStreamMetadata()    public abstract IIOMetadata getStreamMetadata()
546      throws IOException;      throws IOException;
547    
548      /**
549       * Get the height of a thumbnail image.
550       *
551       * @param imageIndex the frame index
552       * @param thumbnailIndex the thumbnail index
553       *
554       * @return the height of the thumbnail image
555       *
556       * @exception UnsupportedOperationException if this reader does not
557       * support thumbnails
558       * @exception IllegalStateException if input is null
559       * @exception IndexOutOfBoundsException if either index is
560       * out-of-bounds
561       * @exception IOException if a read error occurs
562       */
563    public int getThumbnailHeight(int imageIndex, int thumbnailIndex)    public int getThumbnailHeight(int imageIndex, int thumbnailIndex)
564      throws IOException      throws IOException
565    {    {
566      return readThumbnail(imageIndex, thumbnailIndex).getHeight();      return readThumbnail(imageIndex, thumbnailIndex).getHeight();
567    }    }
568    
569      /**
570       * Get the width of a thumbnail image.
571       *
572       * @param imageIndex the frame index
573       * @param thumbnailIndex the thumbnail index
574       *
575       * @return the width of the thumbnail image
576       *
577       * @exception UnsupportedOperationException if this reader does not
578       * support thumbnails
579       * @exception IllegalStateException if input is null
580       * @exception IndexOutOfBoundsException if either index is
581       * out-of-bounds
582       * @exception IOException if a read error occurs
583       */
584    public int getThumbnailWidth(int imageIndex, int thumbnailIndex)    public int getThumbnailWidth(int imageIndex, int thumbnailIndex)
585      throws IOException      throws IOException
586    {    {
587      return readThumbnail(imageIndex, thumbnailIndex).getWidth();      return readThumbnail(imageIndex, thumbnailIndex).getWidth();
588    }    }
589    
590      /**
591       * Get the X coordinate in pixels of the top-left corner of the
592       * first tile in this image.
593       *
594       * @param imageIndex the frame index
595       *
596       * @return the X coordinate of this image's first tile
597       *
598       * @exception IllegalStateException if input is needed but the input
599       * source is not set
600       * @exception IndexOutOfBoundsException if the frame index is
601       * out-of-bounds
602       * @exception IOException if a read error occurs
603       */
604    public int getTileGridXOffset(int imageIndex)    public int getTileGridXOffset(int imageIndex)
605      throws IOException      throws IOException
606    {    {
607      return 0;      return 0;
608    }    }
609    
610      /**
611       * Get the Y coordinate in pixels of the top-left corner of the
612       * first tile in this image.
613       *
614       * @param imageIndex the frame index
615       *
616       * @return the Y coordinate of this image's first tile
617       *
618       * @exception IllegalStateException if input is needed but the input
619       * source is not set
620       * @exception IndexOutOfBoundsException if the frame index is
621       * out-of-bounds
622       * @exception IOException if a read error occurs
623       */
624    public int getTileGridYOffset(int imageIndex)    public int getTileGridYOffset(int imageIndex)
625      throws IOException      throws IOException
626    {    {
627      return 0;      return 0;
628    }    }
629    
630      /**
631       * Get the height of an image tile.
632       *
633       * @param imageIndex the frame index
634       *
635       * @return the tile height for the given image
636       *
637       * @exception IllegalStateException if input is null
638       * @exception IndexOutOfBoundsException if the frame index is
639       * out-of-bounds
640       * @exception IOException if a read error occurs
641       */
642    public int getTileHeight(int imageIndex)    public int getTileHeight(int imageIndex)
643      throws IOException      throws IOException
644    {    {
645      return getHeight(imageIndex);      return getHeight(imageIndex);
646    }    }
647    
648      /**
649       * Get the width of an image tile.
650       *
651       * @param imageIndex the frame index
652       *
653       * @return the tile width for the given image
654       *
655       * @exception IllegalStateException if input is null
656       * @exception IndexOutOfBoundsException if the frame index is
657       * out-of-bounds
658       * @exception IOException if a read error occurs
659       */
660    public int getTileWidth(int imageIndex)    public int getTileWidth(int imageIndex)
661      throws IOException      throws IOException
662    {    {
663      return getWidth(imageIndex);      return getWidth(imageIndex);
664    }    }
665    
666      /**
667       * Get the width of the input image in pixels.  If the input image
668       * is resizable then a default width is returned.
669       *
670       * @param imageIndex the image's index
671       *
672       * @return the width of the input image
673       *
674       * @exception IllegalStateException if input has not been set
675       * @exception IndexOutOfBoundsException if the frame index is
676       * out-of-bounds
677       * @exception IOException if a read error occurs
678       */
679    public abstract int getWidth(int imageIndex)    public abstract int getWidth(int imageIndex)
680      throws IOException;      throws IOException;
681    
682      /**
683       * Check whether or not the given image has thumbnails associated
684       * with it.
685       *
686       * @return true if the given image has thumbnails, false otherwise
687       *
688       * @exception IllegalStateException if input is null
689       * @exception IndexOutOfBoundsException if the frame index is
690       * out-of-bounds
691       * @exception IOException if a read error occurs
692       */
693    public boolean hasThumbnails(int imageIndex)    public boolean hasThumbnails(int imageIndex)
694      throws IOException      throws IOException
695    {    {
696      return getNumThumbnails(imageIndex) > 0;      return getNumThumbnails(imageIndex) > 0;
697    }    }
698    
699      /**
700       * Check if this image reader ignores metadata.  This method simply
701       * returns the value of ignoreMetadata.
702       *
703       * @return true if metadata is being ignored, false otherwise
704       */
705    public boolean isIgnoringMetadata()    public boolean isIgnoringMetadata()
706    {    {
707      return ignoreMetadata;      return ignoreMetadata;
708    }    }
709    
710      /**
711       * Check if the given image is sub-divided into equal-sized
712       * non-overlapping pixel rectangles.
713       *
714       * A reader may expose tiling in the underlying format, hide it, or
715       * simulate tiling even if the underlying format is not tiled.
716       *
717       * @return true if the given image is tiled, false otherwise
718       *
719       * @exception IllegalStateException if input is null
720       * @exception IndexOutOfBoundsException if the frame index is
721       * out-of-bounds
722       * @exception IOException if a read error occurs
723       */
724    public boolean isImageTiled(int imageIndex)    public boolean isImageTiled(int imageIndex)
725      throws IOException      throws IOException
726    {    {
727      return false;      return false;
728    }    }
729    
730      /**
731       * Check if all pixels in this image are readily accessible.  This
732       * method should return false for compressed formats.  The return
733       * value is a hint as to the efficiency of certain image reader
734       * operations.
735       *
736       * @param imageIndex the frame index
737       *
738       * @return true if random pixel access is fast, false otherwise
739       *
740       * @exception IllegalStateException if input is null and it is
741       * needed to determine the return value
742       * @exception IndexOutOfBoundsException if the frame index is
743       * out-of-bounds but the frame data must be accessed to determine
744       * the return value
745       * @exception IOException if a read error occurs
746       */
747    public boolean isRandomAccessEasy(int imageIndex)    public boolean isRandomAccessEasy(int imageIndex)
748      throws IOException      throws IOException
749    {    {
750      return false;      return false;
751    }    }
752    
753      /**
754       * Check if this image reader may only seek forward within the input
755       * stream.
756       *
757       * @return true if this reader may only seek forward, false
758       * otherwise
759       */
760    public boolean isSeekForwardOnly()    public boolean isSeekForwardOnly()
761    {    {
762      return seekForwardOnly;      return seekForwardOnly;
763    }    }
764    
765      /**
766       * Notifies all installed read progress listeners that image loading
767       * has completed by calling their imageComplete methods.
768       */
769    protected void processImageComplete()    protected void processImageComplete()
770    {    {
771      Iterator it = progressListeners.iterator();      if (progressListeners != null)
   
     while (it.hasNext())  
772        {        {
773          IIOReadProgressListener listener = (IIOReadProgressListener) it.next();          Iterator it = progressListeners.iterator();
774          listener.imageComplete (this);  
775            while (it.hasNext())
776              {
777                IIOReadProgressListener listener =
778                  (IIOReadProgressListener) it.next();
779                listener.imageComplete (this);
780              }
781        }        }
782    }    }
783    
784      /**
785       * Notifies all installed read progress listeners that a certain
786       * percentage of the image has been loaded, by calling their
787       * imageProgress methods.
788       *
789       * @param percentageDone the percentage of image data that has been
790       * loaded
791       */
792    protected void processImageProgress(float percentageDone)    protected void processImageProgress(float percentageDone)
793    {    {
794      Iterator it = progressListeners.iterator();       if (progressListeners != null)
   
     while (it.hasNext())  
795        {        {
796          IIOReadProgressListener listener = (IIOReadProgressListener) it.next();          Iterator it = progressListeners.iterator();
797          listener.imageProgress(this, percentageDone);  
798            while (it.hasNext())
799              {
800                IIOReadProgressListener listener =
801                  (IIOReadProgressListener) it.next();
802                listener.imageProgress(this, percentageDone);
803              }
804        }        }
805    }    }
806      /**
807       * Notifies all installed read progress listeners, by calling their
808       * imageStarted methods, that image loading has started on the given
809       * image.
810       *
811       * @param imageIndex the frame index of the image that has started
812       * loading
813       */
814    protected void processImageStarted(int imageIndex)    protected void processImageStarted(int imageIndex)
815    {    {
816      Iterator it = progressListeners.iterator();       if (progressListeners != null)
   
     while (it.hasNext())  
817        {        {
818          IIOReadProgressListener listener = (IIOReadProgressListener) it.next();          Iterator it = progressListeners.iterator();
819          listener.imageStarted(this, imageIndex);  
820            while (it.hasNext())
821              {
822                IIOReadProgressListener listener =
823                  (IIOReadProgressListener) it.next();
824                listener.imageStarted(this, imageIndex);
825              }
826        }        }
827    }    }
828    
829      /**
830       * Notifies all installed read update listeners, by calling their
831       * imageUpdate methods, that the set of samples has changed.
832       *
833       * @param image the buffered image that is being updated
834       * @param minX the X coordinate of the top-left pixel in this pass
835       * @param minY the Y coordinate of the top-left pixel in this pass
836       * @param width the total width of the rectangle covered by this
837       * pass, including skipped pixels
838       * @param height the total height of the rectangle covered by this
839       * pass, including skipped pixels
840       * @param periodX the horizontal sample interval
841       * @param periodY the vertical sample interval
842       * @param bands the affected bands in the destination
843       */
844    protected void processImageUpdate(BufferedImage image, int minX, int minY,    protected void processImageUpdate(BufferedImage image, int minX, int minY,
845                                      int width, int height, int periodX,                                      int width, int height, int periodX,
846                                      int periodY, int[] bands)                                      int periodY, int[] bands)
847    {    {
848      Iterator it = updateListeners.iterator();      if (updateListeners != null)
   
     while (it.hasNext())  
849        {        {
850          IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();          Iterator it = updateListeners.iterator();
851          listener.imageUpdate(this, image, minX, minY, width, height, periodX,  
852                               periodY, bands);          while (it.hasNext())
853              {
854                IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
855                listener.imageUpdate(this, image, minX, minY, width, height,
856                                     periodX, periodY, bands);
857              }
858        }        }
859    }    }
860    
861      /**
862       * Notifies all installed update progress listeners, by calling
863       * their passComplete methods, that a progressive pass has
864       * completed.
865       *
866       * @param image the image that has being updated
867       */
868    protected void processPassComplete(BufferedImage image)    protected void processPassComplete(BufferedImage image)
869    {    {
870      Iterator it = updateListeners.iterator();      if (updateListeners != null)
   
     while (it.hasNext())  
871        {        {
872          IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();          Iterator it = updateListeners.iterator();
873          listener.passComplete(this, image);  
874            while (it.hasNext())
875              {
876                IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
877                listener.passComplete(this, image);
878              }
879        }        }
880    }    }
881    
882      /**
883       * Notifies all installed read update listeners, by calling their
884       * passStarted methods, that a new pass has begun.
885       *
886       * @param image the buffered image that is being updated
887       * @param pass the current pass number
888       * @param minPass the pass at which decoding will begin
889       * @param maxPass the pass at which decoding will end
890       * @param minX the X coordinate of the top-left pixel in this pass
891       * @param minY the Y coordinate of the top-left pixel in this pass
892       * @param width the total width of the rectangle covered by this
893       * pass, including skipped pixels
894       * @param height the total height of the rectangle covered by this
895       * pass, including skipped pixels
896       * @param periodX the horizontal sample interval
897       * @param periodY the vertical sample interval
898       * @param bands the affected bands in the destination
899       */
900    protected void processPassStarted(BufferedImage image, int pass, int minPass,    protected void processPassStarted(BufferedImage image, int pass, int minPass,
901                                      int maxPass, int minX, int minY,                                      int maxPass, int minX, int minY,
902                                      int periodX, int periodY, int[] bands)                                      int periodX, int periodY, int[] bands)
903    {    {
904      Iterator it = updateListeners.iterator();      if (updateListeners != null)
   
     while (it.hasNext())  
905        {        {
906          IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();          Iterator it = updateListeners.iterator();
907          listener.passStarted(this, image, pass, minPass, maxPass, minX, minY,  
908                               periodX, periodY, bands);          while (it.hasNext())
909              {
910                IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
911                listener.passStarted(this, image, pass, minPass, maxPass, minX,
912                                     minY, periodX, periodY, bands);
913              }
914        }        }
915    }    }
916    
917      /**
918       * Notifies all installed read progress listeners that image loading
919       * has been aborted by calling their readAborted methods.
920       */
921    protected void processReadAborted()    protected void processReadAborted()
922    {    {
923      Iterator it = progressListeners.iterator();       if (progressListeners != null)
   
     while (it.hasNext())  
924        {        {
925          IIOReadProgressListener listener = (IIOReadProgressListener) it.next();          Iterator it = progressListeners.iterator();
926          listener.readAborted(this);  
927            while (it.hasNext())
928              {
929                IIOReadProgressListener listener =
930                  (IIOReadProgressListener) it.next();
931                listener.readAborted(this);
932              }
933        }        }
934    }    }
935      /**
936       * Notifies all installed read progress listeners, by calling their
937       * sequenceComplete methods, that a sequence of images has completed
938       * loading.
939       */
940    protected void processSequenceComplete()    protected void processSequenceComplete()
941    {    {
942      Iterator it = progressListeners.iterator();       if (progressListeners != null)
   
     while (it.hasNext())  
943        {        {
944          IIOReadProgressListener listener = (IIOReadProgressListener) it.next();          Iterator it = progressListeners.iterator();
945          listener.sequenceComplete(this);  
946            while (it.hasNext())
947              {
948                IIOReadProgressListener listener =
949                  (IIOReadProgressListener) it.next();
950                listener.sequenceComplete(this);
951              }
952        }        }
953    }    }
954    
955      /**
956       * Notifies all installed read progress listeners, by calling their
957       * sequenceStarted methods, a sequence of images has started
958       * loading.
959       *
960       * @param minIndex the index of the first image in the sequence
961       */
962    protected void processSequenceStarted(int minIndex)    protected void processSequenceStarted(int minIndex)
963    {    {
     Iterator it = progressListeners.iterator();  
964    
965      while (it.hasNext())      if (progressListeners != null)
966        {        {
967          IIOReadProgressListener listener = (IIOReadProgressListener) it.next();          Iterator it = progressListeners.iterator();
968          listener.sequenceStarted(this, minIndex);  
969            while (it.hasNext())
970              {
971                IIOReadProgressListener listener =
972                  (IIOReadProgressListener) it.next();
973                listener.sequenceStarted(this, minIndex);
974              }
975        }        }
976    }    }
977    
978      /**
979       * Notifies all installed read progress listeners, by calling their
980       * thumbnailComplete methods, that a thumbnail has completed
981       * loading.
982       */
983    protected void processThumbnailComplete()    protected void processThumbnailComplete()
984    {    {
985      Iterator it = progressListeners.iterator();      if (progressListeners != null)
   
     while (it.hasNext())  
986        {        {
987          IIOReadProgressListener listener = (IIOReadProgressListener) it.next();          Iterator it = progressListeners.iterator();
988          listener.thumbnailComplete(this);  
989            while (it.hasNext())
990              {
991                IIOReadProgressListener listener =
992                  (IIOReadProgressListener) it.next();
993                listener.thumbnailComplete(this);
994              }
995        }        }
996    }    }
997    
998      /**
999       * Notifies all installed update progress listeners, by calling
1000       * their thumbnailPassComplete methods, that a progressive pass has
1001       * completed on a thumbnail.
1002       *
1003       * @param thumbnail the thumbnail that has being updated
1004       */
1005    protected void processThumbnailPassComplete(BufferedImage thumbnail)    protected void processThumbnailPassComplete(BufferedImage thumbnail)
1006    {    {
1007      Iterator it = updateListeners.iterator();      if (updateListeners != null)
   
     while (it.hasNext())  
1008        {        {
1009          IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();          Iterator it = updateListeners.iterator();
1010          listener.thumbnailPassComplete(this, thumbnail);  
1011            while (it.hasNext())
1012              {
1013                IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
1014                listener.thumbnailPassComplete(this, thumbnail);
1015              }
1016        }        }
1017    }    }
1018    
1019      /**
1020       * Notifies all installed read update listeners, by calling their
1021       * thumbnailPassStarted methods, that a new pass has begun.
1022       *
1023       * @param thumbnail the thumbnail that is being updated
1024       * @param pass the current pass number
1025       * @param minPass the pass at which decoding will begin
1026       * @param maxPass the pass at which decoding will end
1027       * @param minX the X coordinate of the top-left pixel in this pass
1028       * @param minY the Y coordinate of the top-left pixel in this pass
1029       * @param width the total width of the rectangle covered by this
1030       * pass, including skipped pixels
1031       * @param height the total height of the rectangle covered by this
1032       * pass, including skipped pixels
1033       * @param periodX the horizontal sample interval
1034       * @param periodY the vertical sample interval
1035       * @param bands the affected bands in the destination
1036       */
1037    protected void processThumbnailPassStarted(BufferedImage thumbnail, int pass,    protected void processThumbnailPassStarted(BufferedImage thumbnail, int pass,
1038                                               int minPass, int maxPass, int minX,                                               int minPass, int maxPass, int minX,
1039                                               int minY, int periodX, int periodY,                                               int minY, int periodX, int periodY,
1040                                               int[] bands)                                               int[] bands)
1041    {    {
1042      Iterator it = updateListeners.iterator();      if (updateListeners != null)
   
     while (it.hasNext())  
1043        {        {
1044          IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();          Iterator it = updateListeners.iterator();
1045          listener.thumbnailPassStarted(this, thumbnail, pass, minPass, maxPass,  
1046                                        minX, minY, periodX, periodY, bands);          while (it.hasNext())
1047              {
1048                IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
1049                listener.thumbnailPassStarted(this, thumbnail, pass, minPass,
1050                                              maxPass, minX, minY, periodX,
1051                                              periodY, bands);
1052              }
1053        }        }
1054    }    }
1055      
1056      /**
1057       * Notifies all installed read progress listeners that a certain
1058       * percentage of a thumbnail has been loaded, by calling their
1059       * thumbnailProgress methods.
1060       *
1061       * @param percentageDone the percentage of thumbnail data that has
1062       * been loaded
1063       */
1064    protected void processThumbnailProgress(float percentageDone)    protected void processThumbnailProgress(float percentageDone)
1065    {    {
1066      Iterator it = progressListeners.iterator();      if (progressListeners != null)
   
     while (it.hasNext())  
1067        {        {
1068          IIOReadProgressListener listener = (IIOReadProgressListener) it.next();          Iterator it = progressListeners.iterator();
1069          listener.thumbnailProgress(this, percentageDone);  
1070            while (it.hasNext())
1071              {
1072                IIOReadProgressListener listener =
1073                  (IIOReadProgressListener) it.next();
1074                listener.thumbnailProgress(this, percentageDone);
1075              }
1076        }        }
1077    }    }
1078    
1079      /**
1080       * Notifies all installed read progress listeners, by calling their
1081       * imageStarted methods, that thumbnail loading has started on the
1082       * given thumbnail of the given image.
1083       *
1084       * @param imageIndex the frame index of the image one of who's
1085       * thumbnails has started loading
1086       * @param thumbnailIndex the index of the thumbnail that has started
1087       * loading
1088       */
1089    protected void processThumbnailStarted(int imageIndex, int thumbnailIndex)    protected void processThumbnailStarted(int imageIndex, int thumbnailIndex)
1090    {    {
1091      Iterator it = progressListeners.iterator();      if (progressListeners != null)
   
     while (it.hasNext())  
1092        {        {
1093          IIOReadProgressListener listener = (IIOReadProgressListener) it.next();          Iterator it = progressListeners.iterator();
1094          listener.thumbnailStarted(this, imageIndex, thumbnailIndex);  
1095            while (it.hasNext())
1096              {
1097                IIOReadProgressListener listener =
1098                  (IIOReadProgressListener) it.next();
1099                listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
1100              }
1101        }        }
1102    }    }
1103    
1104      /**
1105       * Notifies all installed read update listeners, by calling their
1106       * thumbnailUpdate methods, that the set of samples has changed.
1107       *
1108       * @param image the buffered image that is being updated
1109       * @param minX the X coordinate of the top-left pixel in this pass
1110       * @param minY the Y coordinate of the top-left pixel in this pass
1111       * @param width the total width of the rectangle covered by this
1112       * pass, including skipped pixels
1113       * @param height the total height of the rectangle covered by this
1114       * pass, including skipped pixels
1115       * @param periodX the horizontal sample interval
1116       * @param periodY the vertical sample interval
1117       * @param bands the affected bands in the destination
1118       */
1119    protected void processThumbnailUpdate(BufferedImage image, int minX, int minY,    protected void processThumbnailUpdate(BufferedImage image, int minX, int minY,
1120                                          int width, int height, int periodX,                                          int width, int height, int periodX,
1121                                          int periodY, int[] bands)                                          int periodY, int[] bands)
1122    {    {
1123      Iterator it = updateListeners.iterator();      if (updateListeners != null)
   
     while (it.hasNext())  
1124        {        {
1125          IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();          Iterator it = updateListeners.iterator();
1126          listener.thumbnailUpdate(this, image, minX, minY, width, height,  
1127                                   periodX, periodY, bands);          while (it.hasNext())
1128              {
1129                IIOReadUpdateListener listener = (IIOReadUpdateListener) it.next();
1130                listener.thumbnailUpdate(this, image, minX, minY, width, height,
1131                                         periodX, periodY, bands);
1132              }
1133        }        }
1134    }    }
1135    
1136      /**
1137       * Notifies all installed warning listeners, by calling their
1138       * warningOccurred methods, that a warning message has been raised.
1139       *
1140       * @param warning the warning message
1141       *
1142       * @exception IllegalArgumentException if warning is null
1143       */
1144    protected void processWarningOccurred(String warning)    protected void processWarningOccurred(String warning)
1145    {    {
1146      Iterator it = warningListeners.iterator();      if (warning == null)
1147          throw new IllegalArgumentException ("null argument");
1148        if (warningListeners != null)
1149          {
1150            Iterator it = warningListeners.iterator();
1151    
1152            while (it.hasNext())
1153              {
1154                IIOReadWarningListener listener =
1155                  (IIOReadWarningListener) it.next();
1156                listener.warningOccurred(this, warning);
1157              }
1158          }
1159      }
1160    
1161      /**
1162       * Notify all installed warning listeners, by calling their
1163       * warningOccurred methods, that a warning message has been raised.
1164       * The warning message is retrieved from a resource bundle, using
1165       * the given basename and keyword.
1166       *
1167       * @param baseName the basename of the resource from which to
1168       * retrieve the warning message
1169       * @param keyword the keyword used to retrieve the warning from the
1170       * resource bundle
1171       *
1172       * @exception IllegalArgumentException if either baseName or keyword
1173       * is null
1174       * @exception IllegalArgumentException if no resource bundle is
1175       * found using baseName
1176       * @exception IllegalArgumentException if the given keyword produces
1177       * no results from the resource bundle
1178       * @exception IllegalArgumentException if the retrieved object is
1179       * not a String
1180       */
1181      protected void processWarningOccurred(String baseName,
1182                                            String keyword)
1183      {
1184        if (baseName == null || keyword == null)
1185          throw new IllegalArgumentException ("null argument");
1186    
1187        ResourceBundle b = null;
1188    
1189        try
1190          {
1191            b = ResourceBundle.getBundle(baseName, getLocale());
1192          }
1193        catch (MissingResourceException e)
1194          {
1195            throw new IllegalArgumentException ("no resource bundle found");
1196          }
1197    
1198        Object str = null;
1199    
1200        try
1201          {
1202            str = b.getObject(keyword);
1203          }
1204        catch (MissingResourceException e)
1205          {
1206            throw new IllegalArgumentException ("no results found for keyword");
1207          }
1208    
1209        if (! (str instanceof String))
1210          throw new IllegalArgumentException ("retrieved object not a String");
1211    
1212        String warning = (String) str;
1213    
1214      while (it.hasNext())      if (warningListeners != null)
1215        {        {
1216          IIOReadWarningListener listener = (IIOReadWarningListener) it.next();          Iterator it = warningListeners.iterator();
1217          listener.warningOccurred(this, warning);  
1218            while (it.hasNext())
1219              {
1220                IIOReadWarningListener listener =
1221                  (IIOReadWarningListener) it.next();
1222                listener.warningOccurred(this, warning);
1223              }
1224        }        }
1225    }    }
1226    
1227      /**
1228       * Read the given frame into a buffered image using the given read
1229       * parameters.  Listeners will be notified of image loading progress
1230       * and warnings.
1231       *
1232       * @param imageIndex the index of the frame to read
1233       * @param param the image read parameters to use when reading
1234       *
1235       * @return a buffered image
1236       *
1237       * @exception IllegalStateException if input is null
1238       * @exception IndexOutOfBoundsException if the frame index is
1239       * out-of-bounds
1240       * @exception IOException if a read error occurs
1241       */
1242    public abstract BufferedImage read(int imageIndex, ImageReadParam param)    public abstract BufferedImage read(int imageIndex, ImageReadParam param)
1243      throws IOException;      throws IOException;
1244    
1245      /**
1246       * Check if this reader supports reading thumbnails.
1247       *
1248       * @return true if this reader supports reading thumbnails, false
1249       * otherwise
1250       */
1251    public boolean readerSupportsThumbnails()    public boolean readerSupportsThumbnails()
1252    {    {
1253      return false;      return false;
1254    }    }
1255    
1256      /**
1257       * Read raw raster data.  The image type specifier in param is
1258       * ignored but all other parameters are used.  Offset parameters are
1259       * translated into the raster's coordinate space.  This method may
1260       * be implemented by image readers that want to provide direct
1261       * access to raw image data.
1262       *
1263       * @param imageIndex the frame index
1264       * @param param the image read parameters
1265       *
1266       * @return a raster containing the read image data
1267       *
1268       * @exception UnsupportedOperationException if this reader doesn't
1269       * support rasters
1270       * @exception IllegalStateException if input is null
1271       * @exception IndexOutOfBoundsException if the frame index is
1272       * out-of-bounds
1273       * @exception IOException if a read error occurs
1274       */
1275    public Raster readRaster(int imageIndex, ImageReadParam param)    public Raster readRaster(int imageIndex, ImageReadParam param)
1276      throws IOException      throws IOException
1277    {    {
1278      throw new UnsupportedOperationException();      throw new UnsupportedOperationException();
1279    }    }
1280    
1281      /**
1282       * Read a thumbnail.
1283       *
1284       * @param imageIndex the frame index
1285       * @param thumbnailIndex the thumbnail index
1286       *
1287       * @return a buffered image of the thumbnail
1288       *
1289       * @exception UnsupportedOperationException if this reader doesn't
1290       * support thumbnails
1291       * @exception IllegalStateException if input is null
1292       * @exception IndexOutOfBoundsException if either the frame index or
1293       * the thumbnail index is out-of-bounds
1294       * @exception IOException if a read error occurs
1295       *
1296       */
1297    public BufferedImage readThumbnail(int imageIndex, int thumbnailIndex)    public BufferedImage readThumbnail(int imageIndex, int thumbnailIndex)
1298      throws IOException      throws IOException
1299    {    {
1300      throw new UnsupportedOperationException();      throw new UnsupportedOperationException();
1301    }    }
1302    
1303      /**
1304       * Uninstall all read progress listeners.
1305       */
1306    public void removeAllIIOReadProgressListeners()    public void removeAllIIOReadProgressListeners()
1307    {    {
1308      progressListeners.clear();      progressListeners = null;
1309    }    }
1310    
1311      /**
1312       * Uninstall all read update listeners.
1313       */
1314    public void removeAllIIOReadUpdateListeners()    public void removeAllIIOReadUpdateListeners()
1315    {    {
1316      updateListeners.clear();      updateListeners = null;
1317    }    }
1318    
1319      /**
1320       * Uninstall all read warning listeners.
1321       */
1322    public void removeAllIIOReadWarningListeners()    public void removeAllIIOReadWarningListeners()
1323    {    {
1324      warningListeners.clear();      warningListeners = null;
1325    }    }
1326      
1327      /**
1328       * Uninstall the given read progress listener.
1329       *
1330       * @param listener the listener to remove
1331       */
1332    public void removeIIOReadProgressListener(IIOReadProgressListener listener)    public void removeIIOReadProgressListener(IIOReadProgressListener listener)
1333    {    {
1334      if (listener == null)      if (listener == null)
1335        return;        return;
1336        if (progressListeners != null)
1337      progressListeners.remove(listener);        {
1338            progressListeners.remove(listener);
1339          }
1340    }    }
1341      
1342      /**
1343       * Uninstall the given read update listener.
1344       *
1345       * @param listener the listener to remove
1346       */
1347    public void removeIIOReadUpdateListener(IIOReadUpdateListener listener)    public void removeIIOReadUpdateListener(IIOReadUpdateListener listener)
1348    {    {
1349      if (listener == null)      if (listener == null)
1350        return;        return;
1351        
1352      updateListeners.remove(listener);      if (updateListeners != null)
1353          {
1354            updateListeners.remove(listener);
1355          }
1356    }    }
1357      
1358      /**
1359       * Uninstall the given read warning listener.
1360       *
1361       * @param listener the listener to remove
1362       */
1363    public void removeIIOReadWarningListener(IIOReadWarningListener listener)    public void removeIIOReadWarningListener(IIOReadWarningListener listener)
1364    {    {
1365      if (listener == null)      if (listener == null)
1366        return;        return;
1367            if (warningListeners != null)
1368      warningListeners.remove(listener);        {
1369            warningListeners.remove(listener);
1370          }
1371    }    }
1372      
1373      /**
1374       * Set the current locale or use the default locale.
1375       *
1376       * @param locale the locale to set, or null
1377       */
1378    public void setLocale(Locale locale)    public void setLocale(Locale locale)
1379    {    {
1380      if (locale != null)      if (locale != null)
# Line 553  public abstract class ImageReader Line 1393  public abstract class ImageReader
1393    
1394      this.locale = locale;      this.locale = locale;
1395    }    }
1396    
1397      /**
1398       * Check that the given read parameters have valid source and
1399       * destination band settings.  If the param.getSourceBands() returns
1400       * null, the array is assumed to include all band indices, 0 to
1401       * numSrcBands - 1; likewise if param.getDestinationBands() returns
1402       * null, it is assumed to be an array containing indices 0 to
1403       * numDstBands - 1.  A failure will cause this method to throw
1404       * IllegalArgumentException.
1405       *
1406       * @param param the image parameters to check
1407       * @param numSrcBands the number of input source bands
1408       * @param numDstBands the number of ouput destination bands
1409       *
1410       * @exception IllegalArgumentException if either the given source or
1411       * destination band indices are invalid
1412       */
1413      protected static void checkReadParamBandSettings(ImageReadParam param,
1414                                                       int numSrcBands,
1415                                                       int numDstBands)
1416      {
1417        int[] srcBands = param.getSourceBands();
1418        int[] dstBands = param.getDestinationBands();
1419        boolean lengthsDiffer = false;
1420        boolean srcOOB = false;
1421        boolean dstOOB = false;
1422    
1423        if (srcBands == null)
1424          {
1425            if (dstBands == null)
1426              {
1427                if (numSrcBands != numDstBands)
1428                  lengthsDiffer = true;
1429              }
1430            else
1431              {
1432                if (numSrcBands != dstBands.length)
1433                  lengthsDiffer = true;
1434    
1435                for (int i = 0; i < dstBands.length; i++)
1436                  if (dstBands[i] > numSrcBands - 1)
1437                    {
1438                      dstOOB = true;
1439                      break;
1440                    }
1441              }
1442          }
1443        else
1444          {
1445            if (dstBands == null)
1446              {
1447                if (srcBands.length != numDstBands)
1448                  lengthsDiffer = true;
1449    
1450                for (int i = 0; i < srcBands.length; i++)
1451                  if (srcBands[i] > numDstBands - 1)
1452                    {
1453                      srcOOB = true;
1454                      break;
1455                    }
1456              }
1457            else
1458              {
1459                if (srcBands.length != dstBands.length)
1460                  lengthsDiffer = true;
1461    
1462                for (int i = 0; i < srcBands.length; i++)
1463                  if (srcBands[i] > numDstBands - 1)
1464                    {
1465                      srcOOB = true;
1466                      break;
1467                    }
1468    
1469                for (int i = 0; i < dstBands.length; i++)
1470                  if (dstBands[i] > numSrcBands - 1)
1471                    {
1472                      dstOOB = true;
1473                      break;
1474                    }
1475              }
1476          }
1477    
1478        if (lengthsDiffer)
1479          throw new IllegalArgumentException ("array lengths differ");
1480    
1481        if (srcOOB)
1482          throw new IllegalArgumentException ("source band index"
1483                                              + " out-of-bounds");
1484    
1485        if (dstOOB)
1486          throw new IllegalArgumentException ("destination band index"
1487                                              + " out-of-bounds");
1488      }
1489    
1490      /**
1491       * Calcluate the source and destination regions that will be read
1492       * from and written to, given image parameters and/or a destination
1493       * buffered image.  The source region will be clipped if any of its
1494       * bounds are outside the destination region.  Clipping will account
1495       * for subsampling and destination offsets.  Likewise, the
1496       * destination region is clipped to the given destination image, if
1497       * it is not null, using the given image parameters, if they are not
1498       * null.  IllegalArgumentException is thrown if either region will
1499       * contain 0 pixels after clipping.
1500       *
1501       * @param image read parameters, or null
1502       * @param srcWidth the width of the source image
1503       * @param srcHeight the height of the source image
1504       * @param image the destination image, or null
1505       * @param srcRegion a rectangle whose values will be set to the
1506       * clipped source region
1507       * @param destRegion a rectangle whose values will be set to the
1508       * clipped destination region
1509       *
1510       * @exception IllegalArgumentException if either srcRegion or
1511       * destRegion is null
1512       * @exception IllegalArgumentException if either of the calculated
1513       * regions is empty
1514       */
1515      protected static void computeRegions (ImageReadParam param,
1516                                            int srcWidth,
1517                                            int srcHeight,
1518                                            BufferedImage image,
1519                                            Rectangle srcRegion,
1520                                            Rectangle destRegion)
1521      {
1522        if (srcRegion == null || destRegion == null)
1523          throw new IllegalArgumentException ("null region");
1524    
1525        if (srcWidth == 0 || srcHeight == 0)
1526          throw new IllegalArgumentException ("zero-sized region");
1527    
1528        srcRegion = getSourceRegion(param, srcWidth, srcHeight);
1529        if (image != null)
1530          destRegion = new Rectangle (0, 0, image.getWidth(), image.getHeight());
1531        else
1532          destRegion = new Rectangle (0, 0, srcWidth, srcHeight);
1533    
1534        if (param != null)
1535          {
1536            Point offset = param.getDestinationOffset();
1537    
1538            if (offset.x < 0)
1539              {
1540                srcRegion.x -= offset.x;
1541                srcRegion.width += offset.x;
1542              }
1543            if (offset.y < 0)
1544              {
1545                srcRegion.y -= offset.y;
1546                srcRegion.height += offset.y;
1547              }
1548    
1549            srcRegion.width = srcRegion.width > destRegion.width
1550              ? destRegion.width : srcRegion.width;
1551            srcRegion.height = srcRegion.height > destRegion.height
1552              ? destRegion.height : srcRegion.height;
1553    
1554            if (offset.x >= 0)
1555              {
1556                destRegion.x += offset.x;
1557                destRegion.width -= offset.x;
1558              }
1559            if (offset.y >= 0)
1560              {
1561                destRegion.y += offset.y;
1562                destRegion.height -= offset.y;
1563              }
1564          }
1565    
1566        if (srcRegion.isEmpty() || destRegion.isEmpty())
1567          throw new IllegalArgumentException ("zero-sized region");
1568      }
1569    
1570      /**
1571       * Return a suitable destination buffered image.  If
1572       * param.getDestination() is non-null, then it is returned,
1573       * otherwise a buffered image is created using
1574       * param.getDestinationType() if it is non-null and also in the
1575       * given imageTypes collection, or the first element of imageTypes
1576       * otherwise.
1577       *
1578       * @param param image read parameters from which a destination image
1579       * or image type is retrieved, or null
1580       * @param imageTypes a collection of legal image types
1581       * @param width the width of the source image
1582       * @param height the height of the source image
1583       *
1584       * @return a suitable destination buffered image
1585       *
1586       * @exception IIOException if param.getDestinationType() does not
1587       * return an image type in imageTypes
1588       * @exception IllegalArgumentException if imageTypes is null or
1589       * empty, or if a non-ImageTypeSpecifier object is retrieved from
1590       * imageTypes
1591       * @exception IllegalArgumentException if the resulting destination
1592       * region is empty
1593       * @exception IllegalArgumentException if the product of width and
1594       * height is greater than Integer.MAX_VALUE
1595       */
1596      protected static BufferedImage getDestination (ImageReadParam param,
1597                                                     Iterator imageTypes,
1598                                                     int width,
1599                                                     int height)
1600        throws IIOException
1601      {
1602        if (imageTypes == null || !imageTypes.hasNext())
1603          throw new IllegalArgumentException ("imageTypes null or empty");
1604    
1605        if (width < 0 || height < 0)
1606          throw new IllegalArgumentException ("negative dimension");
1607    
1608        // test for overflow
1609        if (width * height < Math.min (width, height))
1610          throw new IllegalArgumentException ("width * height > Integer.MAX_VALUE");
1611    
1612        BufferedImage dest = null;
1613        ImageTypeSpecifier destType = null;
1614    
1615        if (param != null)
1616          {
1617            dest = param.getDestination ();
1618            if (dest == null)
1619              {
1620                ImageTypeSpecifier type = param.getDestinationType();
1621                if (type != null)
1622                  {
1623                    Iterator it = imageTypes;
1624    
1625                    while (it.hasNext())
1626                      {
1627                        Object o = it.next ();
1628                        if (! (o instanceof ImageTypeSpecifier))
1629                          throw new IllegalArgumentException ("non-ImageTypeSpecifier object");
1630    
1631                        ImageTypeSpecifier t = (ImageTypeSpecifier) o;
1632                        if (t.equals (type))
1633                          {
1634                            dest = t.createBufferedImage (width, height);
1635                            break;
1636                          }
1637                        if (destType == null)
1638                          throw new IIOException ("invalid destination type");
1639    
1640                      }
1641                  }
1642              }
1643          }
1644        if (dest == null)
1645          {
1646            Rectangle srcRegion = new Rectangle ();
1647            Rectangle destRegion = new Rectangle ();
1648    
1649            computeRegions (param, width, height, null, srcRegion, destRegion);
1650    
1651            if (destRegion.isEmpty())
1652              throw new IllegalArgumentException ("destination region empty");
1653    
1654            if (destType == null)
1655              {
1656                Object o = imageTypes.next();
1657                if (! (o instanceof ImageTypeSpecifier))
1658                  throw new IllegalArgumentException ("non-ImageTypeSpecifier"
1659                                                      + " object");
1660    
1661                dest = ((ImageTypeSpecifier) o).createBufferedImage
1662                  (destRegion.width, destRegion.height);
1663              }
1664            else
1665              dest = destType.createBufferedImage
1666                (destRegion.width, destRegion.height);
1667          }
1668        return dest;
1669      }
1670    
1671      /**
1672       * Get the metadata associated with this image.  If the reader is
1673       * set to ignore metadata or does not support reading metadata, or
1674       * if no metadata is available then null is returned.
1675       *
1676       * This more specific version of getImageMetadata(int) can be used
1677       * to restrict metadata retrieval to specific formats and node
1678       * names, which can limit the amount of data that needs to be
1679       * processed.
1680       *
1681       * @param imageIndex the frame index
1682       * @param formatName the format of metadata requested
1683       * @param nodeNames a set of Strings specifiying node names to be
1684       * retrieved
1685       *
1686       * @return a metadata object, or null
1687       *
1688       * @exception IllegalStateException if input has not been set
1689       * @exception IndexOutOfBoundsException if the frame index is
1690       * out-of-bounds
1691       * @exception IllegalArgumentException if formatName is null
1692       * @exception IllegalArgumentException if nodeNames is null
1693       * @exception IOException if a read error occurs
1694       */
1695      public IIOMetadata getImageMetadata (int imageIndex,
1696                                           String formatName,
1697                                           Set nodeNames)
1698        throws IOException
1699      {
1700        if (formatName == null || nodeNames == null)
1701          throw new IllegalArgumentException ("null argument");
1702    
1703        return getImageMetadata (imageIndex);
1704      }
1705    
1706      /**
1707       * Get the index at which the next image will be read.  If
1708       * seekForwardOnly is true then the returned value will increase
1709       * monotonically each time an image frame is read.  If
1710       * seekForwardOnly is false then the returned value will always be
1711       * 0.
1712       *
1713       * @return the current frame index
1714       */
1715      public int getMinIndex()
1716      {
1717        return minIndex;
1718      }
1719    
1720      /**
1721       * Get the image type specifier that most closely represents the
1722       * internal data representation used by this reader.  This value
1723       * should be included in the return value of getImageTypes.
1724       *
1725       * @param imageIndex the frame index
1726       *
1727       * @return an image type specifier
1728       *
1729       * @exception IllegalStateException if input has not been set
1730       * @exception IndexOutOfBoundsException if the frame index is
1731       * out-of-bounds
1732       * @exception IOException if a read error occurs
1733       */
1734      public ImageTypeSpecifier getRawImageType (int imageIndex)
1735        throws IOException
1736      {
1737        return (ImageTypeSpecifier) getImageTypes(imageIndex).next();
1738      }
1739    
1740      /**
1741       * Calculate a source region based on the given source image
1742       * dimensions and parameters.  Subsampling offsets and a source
1743       * region are taken from the given image read parameters and used to
1744       * clip the given image dimensions, returning a new rectangular
1745       * region as a result.
1746       *
1747       * @param param image parameters, or null
1748       * @param srcWidth the width of the source image
1749       * @param srcHeight the height of the source image
1750       *
1751       * @return a clipped rectangle
1752       */
1753      protected static Rectangle getSourceRegion (ImageReadParam param,
1754                                                  int srcWidth,
1755                                                  int srcHeight)
1756      {
1757        Rectangle clippedRegion = new Rectangle (0, 0, srcWidth, srcHeight);
1758    
1759        if (param != null)
1760          {
1761            Rectangle srcRegion = param.getSourceRegion();
1762    
1763            if (srcRegion != null)
1764              {
1765                clippedRegion.x = srcRegion.x > clippedRegion.x
1766                  ? srcRegion.x : clippedRegion.x;
1767                clippedRegion.y = srcRegion.y > clippedRegion.y
1768                  ? srcRegion.y : clippedRegion.y;
1769                clippedRegion.width = srcRegion.width > clippedRegion.width
1770                  ? srcRegion.width : clippedRegion.width;
1771                clippedRegion.height = srcRegion.height > clippedRegion.height
1772                  ? srcRegion.height : clippedRegion.height;
1773              }
1774    
1775            int xOffset = param.getSubsamplingXOffset();
1776    
1777            clippedRegion.x += xOffset;
1778            clippedRegion.width -= xOffset;
1779    
1780            int yOffset = param.getSubsamplingYOffset();
1781    
1782            clippedRegion.y += yOffset;
1783            clippedRegion.height -= yOffset;
1784          }
1785        return clippedRegion;
1786      }
1787    
1788      /**
1789       * Get the metadata associated with the image being read.  If the
1790       * reader is set to ignore metadata or does not support reading
1791       * metadata, or if no metadata is available then null is returned.
1792       * This method returns metadata associated with the entirety of the
1793       * image data, whereas getStreamMetadata() returns metadata
1794       * associated with a frame within a multi-image data stream.
1795       *
1796       * This more specific version of getStreamMetadata() can be used to
1797       * restrict metadata retrieval to specific formats and node names,
1798       * which can limit the amount of data that needs to be processed.
1799       *
1800       * @param formatName the format of metadata requested
1801       * @param nodeNames a set of Strings specifiying node names to be
1802       * retrieved
1803       *
1804       * @return metadata associated with the image being read, or null
1805       *
1806       * @exception IllegalArgumentException if formatName is null
1807       * @exception IllegalArgumentException if nodeNames is null
1808       * @exception IOException if a read error occurs
1809       */
1810      public IIOMetadata getStreamMetadata (String formatName,
1811                                            Set nodeNames)
1812        throws IOException
1813      {
1814        if (formatName == null || nodeNames == null)
1815          throw new IllegalArgumentException ("null argument");
1816    
1817        return getStreamMetadata();
1818      }
1819    
1820      /**
1821       * Read the given frame all at once, using default image read
1822       * parameters, and return a buffered image.
1823       *
1824       * The returned image will be formatted according to the
1825       * currently-preferred image type specifier.
1826       *
1827       * Installed read progress listeners, update progress listeners and
1828       * warning listeners will be notified of read progress, changes in
1829       * sample sets and warnings respectively.
1830       *
1831       * @param the index of the image frame to read
1832       *
1833       * @return a buffered image
1834       *
1835       * @exception IllegalStateException if input has not been set
1836       * @exception IndexOutOfBoundsException if the frame index is
1837       * out-of-bounds
1838       * @exception IOException if a read error occurs
1839       */
1840      public BufferedImage read (int imageIndex)
1841        throws IOException
1842      {
1843        return read (imageIndex, null);
1844      }
1845    
1846      /**
1847       * Read the given frame all at once, using the given image read
1848       * parameters, and return an IIOImage.  The IIOImage will contain a
1849       * buffered image as returned by getDestination.
1850       *
1851       * Installed read progress listeners, update progress listeners and
1852       * warning listeners will be notified of read progress, changes in
1853       * sample sets and warnings respectively.
1854       *
1855       * The source and destination band settings are checked with a call
1856       * to checkReadParamBandSettings.
1857       *
1858       * @param the index of the image frame to read
1859       * @param the image read parameters
1860       *
1861       * @return an IIOImage
1862       *
1863       * @exception IllegalStateException if input has not been set
1864       * @exception IndexOutOfBoundsException if the frame index is
1865       * out-of-bounds
1866       * @exception IllegalArgumentException if param.getSourceBands() and
1867       * param.getDestinationBands() are incompatible
1868       * @exception IllegalArgumentException if either the source or
1869       * destination image regions are empty
1870       * @exception IOException if a read error occurs
1871       */
1872      public IIOImage readAll (int imageIndex,
1873                               ImageReadParam param)
1874        throws IOException
1875      {
1876        checkReadParamBandSettings (param,
1877                                    param.getSourceBands().length,
1878                                    param.getDestinationBands().length);
1879    
1880        List l = new ArrayList ();
1881    
1882        for (int i = 0; i < getNumThumbnails (imageIndex); i++)
1883          l.add (readThumbnail(imageIndex, i));
1884    
1885        return new IIOImage (getDestination(param, getImageTypes(imageIndex),
1886                                            getWidth(imageIndex),
1887                                            getHeight(imageIndex)),
1888                             l,
1889                             getImageMetadata (imageIndex));
1890      }
1891    
1892      /**
1893       * Read all image frames all at once, using the given image read
1894       * parameters iterator, and return an iterator over a collection of
1895       * IIOImages.  Each IIOImage in the collection will contain a
1896       * buffered image as returned by getDestination.
1897       *
1898       * Installed read progress listeners, update progress listeners and
1899       * warning listeners will be notified of read progress, changes in
1900       * sample sets and warnings respectively.
1901       *
1902       * Each set of source and destination band settings are checked with
1903       * a call to checkReadParamBandSettings.
1904       *
1905       * @param an iterator over the image read parameters
1906       *
1907       * @return an IIOImage
1908       *
1909       * @exception IllegalStateException if input has not been set
1910       * @exception IllegalArgumentException if a non-ImageReadParam is
1911       * found in params
1912       * @exception IllegalArgumentException if param.getSourceBands() and
1913       * param.getDestinationBands() are incompatible
1914       * @exception IllegalArgumentException if either the source or
1915       * destination image regions are empty
1916       * @exception IOException if a read error occurs
1917       */
1918      public Iterator readAll (Iterator params)
1919        throws IOException
1920      {
1921        List l = new ArrayList ();
1922        int index = 0;
1923    
1924        while (params.hasNext())
1925          {
1926            if (params != null && ! (params instanceof ImageReadParam))
1927              throw new IllegalArgumentException ("non-ImageReadParam found");
1928    
1929            l.add (readAll(index++, (ImageReadParam) params.next ()));
1930          }
1931    
1932        return l.iterator();
1933      }
1934    
1935      /**
1936       * Read a rendered image.  This is a more general counterpart to
1937       * read (int, ImageReadParam).  All image data may not be read
1938       * before this method returns and so listeners will not necessarily
1939       * be notified.
1940       *
1941       * @param the index of the image frame to read
1942       * @param the image read parameters
1943       *
1944       * @return a rendered image
1945       *
1946       * @exception IllegalStateException if input is null
1947       * @exception IndexOutOfBoundsException if the frame index is
1948       * out-of-bounds
1949       * @exception IllegalArgumentException if param.getSourceBands() and
1950       * param.getDestinationBands() are incompatible
1951       * @exception IllegalArgumentException if either the source or
1952       * destination image regions are empty
1953       * @exception IOException if a read error occurs
1954       */
1955      public RenderedImage readAsRenderedImage (int imageIndex,
1956                                                ImageReadParam param)
1957        throws IOException
1958      {
1959        return read (imageIndex, param);
1960      }
1961    
1962      /**
1963       * Read the given tile into a buffered image.  If the tile
1964       * coordinates are out-of-bounds an exception is thrown.  If the
1965       * image is not tiled then the coordinates 0, 0 are expected and the
1966       * entire image will be read.
1967       *
1968       * @param imageIndex the frame index
1969       * @param tileX the horizontal tile coordinate
1970       * @param tileY the vertical tile coordinate
1971       *
1972       * @return the contents of the tile as a buffered image
1973       *
1974       * @exception IllegalStateException if input is null
1975       * @exception IndexOutOfBoundsException if the frame index is
1976       * out-of-bounds
1977       * @exception IllegalArgumentException if the tile coordinates are
1978       * out-of-bounds
1979       * @exception IOException if a read error occurs
1980       */
1981      public BufferedImage readTile (int imageIndex, int tileX, int tileY)
1982        throws IOException
1983      {
1984        if (tileX != 0 || tileY != 0)
1985          throw new IllegalArgumentException ("tileX not 0 or tileY not 0");
1986    
1987        return read (imageIndex);
1988      }
1989    
1990      /**
1991       * Read the given tile into a raster containing the raw image data.
1992       * If the tile coordinates are out-of-bounds an exception is thrown.
1993       * If the image is not tiled then the coordinates 0, 0 are expected
1994       * and the entire image will be read.
1995       *
1996       * @param imageIndex the frame index
1997       * @param tileX the horizontal tile coordinate
1998       * @param tileY the vertical tile coordinate
1999       *
2000       * @return the contents of the tile as a raster
2001       *
2002       * @exception UnsupportedOperationException if rasters are not
2003       * supported
2004       * @exception IllegalStateException if input is null
2005       * @exception IndexOutOfBoundsException if the frame index is
2006       * out-of-bounds
2007       * @exception IllegalArgumentException if the tile coordinates are
2008       * out-of-bounds
2009       * @exception IOException if a read error occurs
2010       */
2011      public Raster readTileRaster (int imageIndex, int tileX, int tileY)
2012        throws IOException
2013      {
2014        if (!canReadRaster())
2015          throw new UnsupportedOperationException ("cannot read rasters");
2016    
2017        if (tileX != 0 || tileY != 0)
2018          throw new IllegalArgumentException ("tileX not 0 or tileY not 0");
2019    
2020        return readRaster (imageIndex, null);
2021      }
2022    
2023      /**
2024       * Reset this reader's internal state.
2025       */
2026      public void reset ()
2027      {
2028        setInput (null, false);
2029        setLocale (null);
2030        removeAllIIOReadUpdateListeners ();
2031        removeAllIIOReadWarningListeners ();
2032        removeAllIIOReadProgressListeners ();
2033        clearAbortRequest ();
2034      }
2035  }  }
2036    

Legend:
Removed from v.1.1.2.3  
changed lines
  Added in v.1.1.2.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26