EMMA Coverage Report (generated Wed Aug 16 18:51:55 GMT 2006)
[all classes][javax.imageio]

COVERAGE SUMMARY FOR SOURCE FILE [ImageReader.java]

nameclass, %method, %block, %line, %
ImageReader.java100% (1/1)4%   (3/73)6%   (84/1475)7%   (28/417)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ImageReader100% (1/1)4%   (3/73)6%   (84/1475)7%   (28/417)
ImageReader (ImageReaderSpi): void 100% (1/1)100% (39/39)100% (14/14)
abort (): void 0%   (0/1)0%   (0/4)0%   (0/2)
abortRequested (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
addIIOReadProgressListener (IIOReadProgressListener): void 0%   (0/1)0%   (0/17)0%   (0/6)
addIIOReadUpdateListener (IIOReadUpdateListener): void 0%   (0/1)0%   (0/17)0%   (0/6)
addIIOReadWarningListener (IIOReadWarningListener): void 0%   (0/1)0%   (0/17)0%   (0/6)
canReadRaster (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
checkReadParamBandSettings (ImageReadParam, int, int): void 0%   (0/1)0%   (0/139)0%   (0/39)
clearAbortRequest (): void 0%   (0/1)0%   (0/4)0%   (0/2)
computeRegions (ImageReadParam, int, int, BufferedImage, Rectangle, Rectangle... 0%   (0/1)0%   (0/153)0%   (0/29)
dispose (): void 0%   (0/1)0%   (0/1)0%   (0/1)
getAspectRatio (int): float 0%   (0/1)0%   (0/17)0%   (0/3)
getAvailableLocales (): Locale [] 0%   (0/1)0%   (0/10)0%   (0/3)
getDefaultReadParam (): ImageReadParam 0%   (0/1)0%   (0/4)0%   (0/1)
getDestination (ImageReadParam, Iterator, int, int): BufferedImage 0%   (0/1)0%   (0/140)0%   (0/39)
getFormatName (): String 0%   (0/1)0%   (0/6)0%   (0/1)
getImageMetadata (int, String, Set): IIOMetadata 0%   (0/1)0%   (0/13)0%   (0/3)
getInput (): Object 0%   (0/1)0%   (0/3)0%   (0/1)
getLocale (): Locale 0%   (0/1)0%   (0/3)0%   (0/1)
getMinIndex (): int 0%   (0/1)0%   (0/3)0%   (0/1)
getNumThumbnails (int): int 0%   (0/1)0%   (0/2)0%   (0/1)
getOriginatingProvider (): ImageReaderSpi 0%   (0/1)0%   (0/3)0%   (0/1)
getRawImageType (int): ImageTypeSpecifier 0%   (0/1)0%   (0/6)0%   (0/1)
getSourceRegion (ImageReadParam, int, int): Rectangle 0%   (0/1)0%   (0/95)0%   (0/19)
getStreamMetadata (String, Set): IIOMetadata 0%   (0/1)0%   (0/12)0%   (0/3)
getThumbnailHeight (int, int): int 0%   (0/1)0%   (0/6)0%   (0/1)
getThumbnailWidth (int, int): int 0%   (0/1)0%   (0/6)0%   (0/1)
getTileGridXOffset (int): int 0%   (0/1)0%   (0/2)0%   (0/1)
getTileGridYOffset (int): int 0%   (0/1)0%   (0/2)0%   (0/1)
getTileHeight (int): int 0%   (0/1)0%   (0/4)0%   (0/1)
getTileWidth (int): int 0%   (0/1)0%   (0/4)0%   (0/1)
hasThumbnails (int): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
isIgnoringMetadata (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
isImageTiled (int): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
isRandomAccessEasy (int): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
isSeekForwardOnly (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
processImageComplete (): void 0%   (0/1)0%   (0/19)0%   (0/7)
processImageProgress (float): void 0%   (0/1)0%   (0/20)0%   (0/7)
processImageStarted (int): void 0%   (0/1)0%   (0/20)0%   (0/7)
processImageUpdate (BufferedImage, int, int, int, int, int, int, int []): void 0%   (0/1)0%   (0/27)0%   (0/7)
processPassComplete (BufferedImage): void 0%   (0/1)0%   (0/20)0%   (0/6)
processPassStarted (BufferedImage, int, int, int, int, int, int, int, int [])... 0%   (0/1)0%   (0/28)0%   (0/7)
processReadAborted (): void 0%   (0/1)0%   (0/19)0%   (0/7)
processSequenceComplete (): void 0%   (0/1)0%   (0/19)0%   (0/7)
processSequenceStarted (int): void 0%   (0/1)0%   (0/20)0%   (0/7)
processThumbnailComplete (): void 0%   (0/1)0%   (0/19)0%   (0/7)
processThumbnailPassComplete (BufferedImage): void 0%   (0/1)0%   (0/20)0%   (0/6)
processThumbnailPassStarted (BufferedImage, int, int, int, int, int, int, int... 0%   (0/1)0%   (0/28)0%   (0/8)
processThumbnailProgress (float): void 0%   (0/1)0%   (0/20)0%   (0/7)
processThumbnailStarted (int, int): void 0%   (0/1)0%   (0/21)0%   (0/7)
processThumbnailUpdate (BufferedImage, int, int, int, int, int, int, int []):... 0%   (0/1)0%   (0/27)0%   (0/7)
processWarningOccurred (String): void 0%   (0/1)0%   (0/27)0%   (0/9)
processWarningOccurred (String, String): void 0%   (0/1)0%   (0/67)0%   (0/20)
read (int): BufferedImage 0%   (0/1)0%   (0/5)0%   (0/1)
readAll (Iterator): Iterator 0%   (0/1)0%   (0/33)0%   (0/7)
readAll (int, ImageReadParam): IIOImage 0%   (0/1)0%   (0/47)0%   (0/11)
readAsRenderedImage (int, ImageReadParam): RenderedImage 0%   (0/1)0%   (0/5)0%   (0/1)
readRaster (int, ImageReadParam): Raster 0%   (0/1)0%   (0/4)0%   (0/1)
readThumbnail (int, int): BufferedImage 0%   (0/1)0%   (0/4)0%   (0/1)
readTile (int, int, int): BufferedImage 0%   (0/1)0%   (0/13)0%   (0/3)
readTileRaster (int, int, int): Raster 0%   (0/1)0%   (0/22)0%   (0/5)
readerSupportsThumbnails (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
removeAllIIOReadProgressListeners (): void 0%   (0/1)0%   (0/4)0%   (0/2)
removeAllIIOReadUpdateListeners (): void 0%   (0/1)0%   (0/4)0%   (0/2)
removeAllIIOReadWarningListeners (): void 0%   (0/1)0%   (0/4)0%   (0/2)
removeIIOReadProgressListener (IIOReadProgressListener): void 0%   (0/1)0%   (0/12)0%   (0/5)
removeIIOReadUpdateListener (IIOReadUpdateListener): void 0%   (0/1)0%   (0/12)0%   (0/5)
removeIIOReadWarningListener (IIOReadWarningListener): void 0%   (0/1)0%   (0/12)0%   (0/5)
reset (): void 0%   (0/1)0%   (0/16)0%   (0/7)
setInput (Object): void 100% (1/1)100% (6/6)100% (2/2)
setInput (Object, boolean): void 0%   (0/1)0%   (0/6)0%   (0/2)
setInput (Object, boolean, boolean): void 100% (1/1)76%  (39/51)80%  (12/15)
setLocale (Locale): void 0%   (0/1)0%   (0/37)0%   (0/10)

1/* ImageReader.java -- Decodes raster images.
2   Copyright (C) 2004, 2005  Free Software Foundation, Inc.
3 
4This file is part of GNU Classpath.
5 
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10 
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14General Public License for more details.
15 
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING.  If not, write to the
18Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1902110-1301 USA.
20 
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library.  Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25 
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module.  An independent module is a module which is not derived from
33or based on this library.  If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so.  If you do not wish to do so, delete this
36exception statement from your version. */
37 
38 
39package javax.imageio;
40 
41import java.awt.Point;
42import java.awt.Rectangle;
43import java.awt.image.BufferedImage;
44import java.awt.image.Raster;
45import java.awt.image.RenderedImage;
46import java.io.IOException;
47import java.util.ArrayList;
48import java.util.Iterator;
49import java.util.List;
50import java.util.Locale;
51import java.util.ResourceBundle;
52import java.util.MissingResourceException;
53import java.util.Set;
54 
55import javax.imageio.event.IIOReadProgressListener;
56import javax.imageio.event.IIOReadUpdateListener;
57import javax.imageio.event.IIOReadWarningListener;
58import javax.imageio.metadata.IIOMetadata;
59import javax.imageio.spi.ImageReaderSpi;
60import 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 */
76public abstract class ImageReader
77{
78  private boolean aborted;
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)
153  {
154    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()
165  {
166    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()
176  {
177    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)
187  {
188    if (listener == null)
189      return;
190    if (progressListeners == null)
191      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)
202  {
203    if (listener == null)
204      return;
205    if (updateListeners == null)
206      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)
220  {
221    if (listener == null)
222      return;
223    if (warningListeners == null)
224      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()
236  {
237    return false;
238  }
239 
240  /**
241   * Clear the abort flag.
242   */
243  protected void clearAbortRequest()
244  {
245    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()
256  {
257    // 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)
275    throws IOException
276  {
277    if (input == null)
278      throw new IllegalStateException("input is null");
279 
280    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()
290  {
291    if (availableLocales == null)
292      return null;
293    
294    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()
306  {
307    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()
318    throws IOException
319  {
320    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)
337    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)
354    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)
375    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,
399                       boolean seekForwardOnly,
400                       boolean ignoreMetadata)
401  {
402    Class[] okClasses = originatingProvider.getInputTypes();
403    if (okClasses == null)
404      {
405        if (!(input instanceof ImageInputStream))
406          throw new IllegalArgumentException();
407      }
408    else
409      {
410        boolean classOk = false;
411        for (int i = 0; i < okClasses.length; ++i)
412          if (okClasses[i].isInstance(input))
413            classOk = true;
414        if (!classOk)
415          throw new IllegalArgumentException();
416      }
417 
418    this.input = input;
419    this.seekForwardOnly = seekForwardOnly;
420    this.ignoreMetadata = ignoreMetadata;
421    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)
440  {
441    setInput(in, seekForwardOnly, false);
442  }
443 
444  /**
445   * Set the input source to the given object.  The input source must
446   * 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()
467  {
468    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()
478  {
479    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)
508    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)
518    throws IOException
519  {
520    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()
529  {
530    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()
546    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)
564    throws IOException
565  {
566    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)
585    throws IOException
586  {
587    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)
605    throws IOException
606  {
607    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)
625    throws IOException
626  {
627    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)
643    throws IOException
644  {
645    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)
661    throws IOException
662  {
663    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)
680    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)
694    throws IOException
695  {
696    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()
706  {
707    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)
725    throws IOException
726  {
727    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)
748    throws IOException
749  {
750    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()
761  {
762    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()
770  {
771    if (progressListeners != null)
772      {
773        Iterator it = progressListeners.iterator();
774 
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)
793  {
794     if (progressListeners != null)
795      {
796        Iterator it = progressListeners.iterator();
797 
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)
815  {
816     if (progressListeners != null)
817      {
818        Iterator it = progressListeners.iterator();
819 
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,
845                                    int width, int height, int periodX,
846                                    int periodY, int[] bands)
847  {
848    if (updateListeners != null)
849      {
850        Iterator it = updateListeners.iterator();
851 
852        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)
869  {
870    if (updateListeners != null)
871      {
872        Iterator it = updateListeners.iterator();
873 
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,
901                                    int maxPass, int minX, int minY,
902                                    int periodX, int periodY, int[] bands)
903  {
904    if (updateListeners != null)
905      {
906        Iterator it = updateListeners.iterator();
907 
908        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()
922  {
923     if (progressListeners != null)
924      {
925        Iterator it = progressListeners.iterator();
926 
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()
941  {
942     if (progressListeners != null)
943      {
944        Iterator it = progressListeners.iterator();
945 
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)
963  {
964 
965    if (progressListeners != null)
966      {
967        Iterator it = progressListeners.iterator();
968 
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()
984  {
985    if (progressListeners != null)
986      {
987        Iterator it = progressListeners.iterator();
988 
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)
1006  {
1007    if (updateListeners != null)
1008      {
1009        Iterator it = updateListeners.iterator();
1010 
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,
1038                                             int minPass, int maxPass, int minX,
1039                                             int minY, int periodX, int periodY,
1040                                             int[] bands)
1041  {
1042    if (updateListeners != null)
1043      {
1044        Iterator it = updateListeners.iterator();
1045 
1046        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)
1065  {
1066    if (progressListeners != null)
1067      {
1068        Iterator it = progressListeners.iterator();
1069 
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)
1090  {
1091    if (progressListeners != null)
1092      {
1093        Iterator it = progressListeners.iterator();
1094 
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,
1120                                        int width, int height, int periodX,
1121                                        int periodY, int[] bands)
1122  {
1123    if (updateListeners != null)
1124      {
1125        Iterator it = updateListeners.iterator();
1126 
1127        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)
1145  {
1146    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    if (warningListeners != null)
1215      {
1216        Iterator it = warningListeners.iterator();
1217 
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)
1243    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()
1252  {
1253    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)
1276    throws IOException
1277  {
1278    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)
1298    throws IOException
1299  {
1300    throw new UnsupportedOperationException();
1301  }
1302 
1303  /**
1304   * Uninstall all read progress listeners.
1305   */
1306  public void removeAllIIOReadProgressListeners()
1307  {
1308    progressListeners = null;
1309  }
1310 
1311  /**
1312   * Uninstall all read update listeners.
1313   */
1314  public void removeAllIIOReadUpdateListeners()
1315  {
1316    updateListeners = null;
1317  }
1318 
1319  /**
1320   * Uninstall all read warning listeners.
1321   */
1322  public void removeAllIIOReadWarningListeners()
1323  {
1324    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) 
1333  {
1334    if (listener == null)
1335      return;
1336    if (progressListeners != null)
1337      {
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) 
1348  {
1349    if (listener == null)
1350      return;
1351 
1352    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)
1364  {
1365    if (listener == null)
1366      return;
1367    if (warningListeners != null)
1368      {
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)
1379  {
1380    if (locale != null)
1381      {
1382        // Check if its a valid locale.
1383        boolean found = false;
1384 
1385        if (availableLocales != null)
1386          for (int i = availableLocales.length - 1; i >= 0; --i)
1387            if (availableLocales[i].equals(locale))
1388              found = true;
1389 
1390        if (! found)
1391          throw new IllegalArgumentException("looale not available");
1392      }
1393 
1394    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 

[all classes][javax.imageio]
EMMA 2.0.6427 (unsupported private build) (C) Vladimir Roubtsov