OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [imageio/] [ImageReader.java] - Blame information for rev 858

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* ImageReader.java -- Decodes raster images.
2
   Copyright (C) 2004, 2005  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.imageio;
40
 
41
import java.awt.Point;
42
import java.awt.Rectangle;
43
import java.awt.image.BufferedImage;
44
import java.awt.image.Raster;
45
import java.awt.image.RenderedImage;
46
import java.io.IOException;
47
import java.util.ArrayList;
48
import java.util.Iterator;
49
import java.util.List;
50
import java.util.Locale;
51
import java.util.ResourceBundle;
52
import java.util.MissingResourceException;
53
import java.util.Set;
54
 
55
import javax.imageio.event.IIOReadProgressListener;
56
import javax.imageio.event.IIOReadUpdateListener;
57
import javax.imageio.event.IIOReadWarningListener;
58
import javax.imageio.metadata.IIOMetadata;
59
import javax.imageio.spi.ImageReaderSpi;
60
import javax.imageio.stream.ImageInputStream;
61
 
62
/**
63
 * A class for decoding images within the ImageIO framework.
64
 *
65
 * An ImageReader for a given format is instantiated by an
66
 * ImageReaderSpi for that format.  ImageReaderSpis are registered
67
 * with the IIORegistry.
68
 *
69
 * The ImageReader API supports reading animated images that may have
70
 * multiple frames; to support such images many methods take an index
71
 * parameter.
72
 *
73
 * Images may also be read in multiple passes, where each successive
74
 * pass increases the level of detail in the destination image.
75
 */
76
public abstract class ImageReader
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<IIOReadProgressListener> 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<IIOReadUpdateListener> updateListeners = null;
133
 
134
  /**
135
   * A list of installed warning listeners.  Initially null, meaning
136
   * no installed listeners.
137
   */
138
  protected List<IIOReadWarningListener> 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<Locale> 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<ImageTypeSpecifier> 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 in 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 param 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<ImageTypeSpecifier> 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<String> 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 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<String> 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 imageIndex 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 imageIndex the index of the image frame to read
1859
   * @param 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 params 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<IIOImage> readAll (Iterator<? extends ImageReadParam> 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 imageIndex the index of the image frame to read
1942
   * @param 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.