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

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

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