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