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} indicating the 658 * {@code SampleModel} and {@code ColorModel} which most 659 * closely represents the "raw" internal format of the image. For 660 * example, for a JPEG image the raw type might have a YCbCr color 661 * space even though the image would conventionally be transformed 662 * into an RGB color space prior to display. The returned value 663 * should also be included in the list of values returned by 664 * {@code getImageTypes}. 665 * 666 * <p> The default implementation simply returns the first entry 667 * from the list provided by {@code getImageType}. 668 * 669 * @param imageIndex the index of the image to be queried. 670 * 671 * @return an {@code ImageTypeSpecifier}. 672 * 673 * @exception IllegalStateException if the input source has not been set. 674 * @exception IndexOutOfBoundsException if the supplied index is 675 * out of bounds. 676 * @exception IOException if an error occurs reading the format 677 * information from the input source. 678 */ 679 public ImageTypeSpecifier getRawImageType(int imageIndex) 680 throws IOException { 681 return getImageTypes(imageIndex).next(); 682 } 683 684 /** 685 * Returns an {@code Iterator} containing possible image 686 * types to which the given image may be decoded, in the form of 687 * {@code ImageTypeSpecifiers}s. At least one legal image 688 * type will be returned. 689 * 690 * <p> The first element of the iterator should be the most 691 * "natural" type for decoding the image with as little loss as 692 * possible. For example, for a JPEG image the first entry should 693 * be an RGB image, even though the image data is stored 694 * internally in a YCbCr color space. 695 * 696 * @param imageIndex the index of the image to be 697 * {@code retrieved}. 698 * 699 * @return an {@code Iterator} containing at least one 700 * {@code ImageTypeSpecifier} representing suggested image 701 * types for decoding the current given image. 702 * 703 * @exception IllegalStateException if the input source has not been set. 704 * @exception IndexOutOfBoundsException if the supplied index is 705 * out of bounds. 706 * @exception IOException if an error occurs reading the format 707 * information from the input source. 708 * 709 * @see ImageReadParam#setDestination(BufferedImage) 710 * @see ImageReadParam#setDestinationType(ImageTypeSpecifier) 711 */ 712 public abstract Iterator<ImageTypeSpecifier> 713 getImageTypes(int imageIndex) throws IOException; 714 715 /** 716 * Returns a default {@code ImageReadParam} object 717 * appropriate for this format. All subclasses should define a 718 * set of default values for all parameters and return them with 719 * this call. This method may be called before the input source 720 * is set. 721 * 722 * <p> The default implementation constructs and returns a new 723 * {@code ImageReadParam} object that does not allow source 724 * scaling (<i>i.e.</i>, it returns 725 * {@code new ImageReadParam()}. 726 * 727 * @return an {@code ImageReadParam} object which may be used 728 * to control the decoding process using a set of default settings. 729 */ 730 public ImageReadParam getDefaultReadParam() { 731 return new ImageReadParam(); 732 } 733 734 /** 735 * Returns an {@code IIOMetadata} object representing the 736 * metadata associated with the input source as a whole (i.e., not 737 * associated with any particular image), or {@code null} if 738 * the reader does not support reading metadata, is set to ignore 739 * metadata, or if no metadata is available. 740 * 741 * @return an {@code IIOMetadata} object, or {@code null}. 742 * 743 * @exception IOException if an error occurs during reading. 744 */ 745 public abstract IIOMetadata getStreamMetadata() throws IOException; 746 747 /** 748 * Returns an {@code IIOMetadata} object representing the 749 * metadata associated with the input source as a whole (i.e., 750 * not associated with any particular image). If no such data 751 * exists, {@code null} is returned. 752 * 753 * <p> The resulting metadata object is only responsible for 754 * returning documents in the format named by 755 * {@code formatName}. Within any documents that are 756 * returned, only nodes whose names are members of 757 * {@code nodeNames} are required to be returned. In this 758 * way, the amount of metadata processing done by the reader may 759 * be kept to a minimum, based on what information is actually 760 * needed. 761 * 762 * <p> If {@code formatName} is not the name of a supported 763 * metadata format, {@code null} is returned. 764 * 765 * <p> In all cases, it is legal to return a more capable metadata 766 * object than strictly necessary. The format name and node names 767 * are merely hints that may be used to reduce the reader's 768 * workload. 769 * 770 * <p> The default implementation simply returns the result of 771 * calling {@code getStreamMetadata()}, after checking that 772 * the format name is supported. If it is not, 773 * {@code null} is returned. 774 * 775 * @param formatName a metadata format name that may be used to retrieve 776 * a document from the returned {@code IIOMetadata} object. 777 * @param nodeNames a {@code Set} containing the names of 778 * nodes that may be contained in a retrieved document. 779 * 780 * @return an {@code IIOMetadata} object, or {@code null}. 781 * 782 * @exception IllegalArgumentException if {@code formatName} 783 * is {@code null}. 784 * @exception IllegalArgumentException if {@code nodeNames} 785 * is {@code null}. 786 * @exception IOException if an error occurs during reading. 787 */ 788 public IIOMetadata getStreamMetadata(String formatName, 789 Set<String> nodeNames) 790 throws IOException 791 { 792 return getMetadata(formatName, nodeNames, true, 0); 793 } 794 795 private IIOMetadata getMetadata(String formatName, 796 Set<String> nodeNames, 797 boolean wantStream, 798 int imageIndex) throws IOException { 799 if (formatName == null) { 800 throw new IllegalArgumentException("formatName == null!"); 801 } 802 if (nodeNames == null) { 803 throw new IllegalArgumentException("nodeNames == null!"); 804 } 805 IIOMetadata metadata = 806 wantStream 807 ? getStreamMetadata() 808 : getImageMetadata(imageIndex); 809 if (metadata != null) { 810 if (metadata.isStandardMetadataFormatSupported() && 811 formatName.equals 812 (IIOMetadataFormatImpl.standardMetadataFormatName)) { 813 return metadata; 814 } 815 String nativeName = metadata.getNativeMetadataFormatName(); 816 if (nativeName != null && formatName.equals(nativeName)) { 817 return metadata; 818 } 819 String[] extraNames = metadata.getExtraMetadataFormatNames(); 820 if (extraNames != null) { 821 for (int i = 0; i < extraNames.length; i++) { 822 if (formatName.equals(extraNames[i])) { 823 return metadata; 824 } 825 } 826 } 827 } 828 return null; 829 } 830 831 /** 832 * Returns an {@code IIOMetadata} object containing metadata 833 * associated with the given image, or {@code null} if the 834 * reader does not support reading metadata, is set to ignore 835 * metadata, or if no metadata is available. 836 * 837 * @param imageIndex the index of the image whose metadata is to 838 * be retrieved. 839 * 840 * @return an {@code IIOMetadata} object, or 841 * {@code null}. 842 * 843 * @exception IllegalStateException if the input source has not been 844 * set. 845 * @exception IndexOutOfBoundsException if the supplied index is 846 * out of bounds. 847 * @exception IOException if an error occurs during reading. 848 */ 849 public abstract IIOMetadata getImageMetadata(int imageIndex) 850 throws IOException; 851 852 /** 853 * Returns an {@code IIOMetadata} object representing the 854 * metadata associated with the given image, or {@code null} 855 * if the reader does not support reading metadata or none 856 * is available. 857 * 858 * <p> The resulting metadata object is only responsible for 859 * returning documents in the format named by 860 * {@code formatName}. Within any documents that are 861 * returned, only nodes whose names are members of 862 * {@code nodeNames} are required to be returned. In this 863 * way, the amount of metadata processing done by the reader may 864 * be kept to a minimum, based on what information is actually 865 * needed. 866 * 867 * <p> If {@code formatName} is not the name of a supported 868 * metadata format, {@code null} may be returned. 869 * 870 * <p> In all cases, it is legal to return a more capable metadata 871 * object than strictly necessary. The format name and node names 872 * are merely hints that may be used to reduce the reader's 873 * workload. 874 * 875 * <p> The default implementation simply returns the result of 876 * calling {@code getImageMetadata(imageIndex)}, after 877 * checking that the format name is supported. If it is not, 878 * {@code null} is returned. 879 * 880 * @param imageIndex the index of the image whose metadata is to 881 * be retrieved. 882 * @param formatName a metadata format name that may be used to retrieve 883 * a document from the returned {@code IIOMetadata} object. 884 * @param nodeNames a {@code Set} containing the names of 885 * nodes that may be contained in a retrieved document. 886 * 887 * @return an {@code IIOMetadata} object, or {@code null}. 888 * 889 * @exception IllegalStateException if the input source has not been 890 * set. 891 * @exception IndexOutOfBoundsException if the supplied index is 892 * out of bounds. 893 * @exception IllegalArgumentException if {@code formatName} 894 * is {@code null}. 895 * @exception IllegalArgumentException if {@code nodeNames} 896 * is {@code null}. 897 * @exception IOException if an error occurs during reading. 898 */ 899 public IIOMetadata getImageMetadata(int imageIndex, 900 String formatName, 901 Set<String> nodeNames) 902 throws IOException { 903 return getMetadata(formatName, nodeNames, false, imageIndex); 904 } 905 906 /** 907 * Reads the image indexed by {@code imageIndex} and returns 908 * it as a complete {@code BufferedImage}, using a default 909 * {@code ImageReadParam}. This is a convenience method 910 * that calls {@code read(imageIndex, null)}. 911 * 912 * <p> The image returned will be formatted according to the first 913 * {@code ImageTypeSpecifier} returned from 914 * {@code getImageTypes}. 915 * 916 * <p> Any registered {@code IIOReadProgressListener} objects 917 * will be notified by calling their {@code imageStarted} 918 * method, followed by calls to their {@code imageProgress} 919 * method as the read progresses. Finally their 920 * {@code imageComplete} method will be called. 921 * {@code IIOReadUpdateListener} objects may be updated at 922 * other times during the read as pixels are decoded. Finally, 923 * {@code IIOReadWarningListener} objects will receive 924 * notification of any non-fatal warnings that occur during 925 * decoding. 926 * 927 * @param imageIndex the index of the image to be retrieved. 928 * 929 * @return the desired portion of the image as a 930 * {@code BufferedImage}. 931 * 932 * @exception IllegalStateException if the input source has not been 933 * set. 934 * @exception IndexOutOfBoundsException if the supplied index is 935 * out of bounds. 936 * @exception IOException if an error occurs during reading. 937 */ 938 public BufferedImage read(int imageIndex) throws IOException { 939 return read(imageIndex, null); 940 } 941 942 /** 943 * Reads the image indexed by {@code imageIndex} and returns 944 * it as a complete {@code BufferedImage}, using a supplied 945 * {@code ImageReadParam}. 946 * 947 * <p> The actual {@code BufferedImage} returned will be 948 * chosen using the algorithm defined by the 949 * {@code getDestination} method. 950 * 951 * <p> Any registered {@code IIOReadProgressListener} objects 952 * will be notified by calling their {@code imageStarted} 953 * method, followed by calls to their {@code imageProgress} 954 * method as the read progresses. Finally their 955 * {@code imageComplete} method will be called. 956 * {@code IIOReadUpdateListener} objects may be updated at 957 * other times during the read as pixels are decoded. Finally, 958 * {@code IIOReadWarningListener} objects will receive 959 * notification of any non-fatal warnings that occur during 960 * decoding. 961 * 962 * <p> The set of source bands to be read and destination bands to 963 * be written is determined by calling {@code getSourceBands} 964 * and {@code getDestinationBands} on the supplied 965 * {@code ImageReadParam}. If the lengths of the arrays 966 * returned by these methods differ, the set of source bands 967 * contains an index larger that the largest available source 968 * index, or the set of destination bands contains an index larger 969 * than the largest legal destination index, an 970 * {@code IllegalArgumentException} is thrown. 971 * 972 * <p> If the supplied {@code ImageReadParam} contains 973 * optional setting values not supported by this reader (<i>e.g.</i> 974 * source render size or any format-specific settings), they will 975 * be ignored. 976 * 977 * @param imageIndex the index of the image to be retrieved. 978 * @param param an {@code ImageReadParam} used to control 979 * the reading process, or {@code null}. 980 * 981 * @return the desired portion of the image as a 982 * {@code BufferedImage}. 983 * 984 * @exception IllegalStateException if the input source has not been 985 * set. 986 * @exception IndexOutOfBoundsException if the supplied index is 987 * out of bounds. 988 * @exception IllegalArgumentException if the set of source and 989 * destination bands specified by 990 * {@code param.getSourceBands} and 991 * {@code param.getDestinationBands} differ in length or 992 * include indices that are out of bounds. 993 * @exception IllegalArgumentException if the resulting image would 994 * have a width or height less than 1. 995 * @exception IOException if an error occurs during reading. 996 */ 997 public abstract BufferedImage read(int imageIndex, ImageReadParam param) 998 throws IOException; 999 1000 /** 1001 * Reads the image indexed by {@code imageIndex} and returns 1002 * an {@code IIOImage} containing the image, thumbnails, and 1003 * associated image metadata, using a supplied 1004 * {@code ImageReadParam}. 1005 * 1006 * <p> The actual {@code BufferedImage} referenced by the 1007 * returned {@code IIOImage} will be chosen using the 1008 * algorithm defined by the {@code getDestination} method. 1009 * 1010 * <p> Any registered {@code IIOReadProgressListener} objects 1011 * will be notified by calling their {@code imageStarted} 1012 * method, followed by calls to their {@code imageProgress} 1013 * method as the read progresses. Finally their 1014 * {@code imageComplete} method will be called. 1015 * {@code IIOReadUpdateListener} objects may be updated at 1016 * other times during the read as pixels are decoded. Finally, 1017 * {@code IIOReadWarningListener} objects will receive 1018 * notification of any non-fatal warnings that occur during 1019 * decoding. 1020 * 1021 * <p> The set of source bands to be read and destination bands to 1022 * be written is determined by calling {@code getSourceBands} 1023 * and {@code getDestinationBands} on the supplied 1024 * {@code ImageReadParam}. If the lengths of the arrays 1025 * returned by these methods differ, the set of source bands 1026 * contains an index larger that the largest available source 1027 * index, or the set of destination bands contains an index larger 1028 * than the largest legal destination index, an 1029 * {@code IllegalArgumentException} is thrown. 1030 * 1031 * <p> Thumbnails will be returned in their entirety regardless of 1032 * the region settings. 1033 * 1034 * <p> If the supplied {@code ImageReadParam} contains 1035 * optional setting values not supported by this reader (<i>e.g.</i> 1036 * source render size or any format-specific settings), those 1037 * values will be ignored. 1038 * 1039 * @param imageIndex the index of the image to be retrieved. 1040 * @param param an {@code ImageReadParam} used to control 1041 * the reading process, or {@code null}. 1042 * 1043 * @return an {@code IIOImage} containing the desired portion 1044 * of the image, a set of thumbnails, and associated image 1045 * metadata. 1046 * 1047 * @exception IllegalStateException if the input source has not been 1048 * set. 1049 * @exception IndexOutOfBoundsException if the supplied index is 1050 * out of bounds. 1051 * @exception IllegalArgumentException if the set of source and 1052 * destination bands specified by 1053 * {@code param.getSourceBands} and 1054 * {@code param.getDestinationBands} differ in length or 1055 * include indices that are out of bounds. 1056 * @exception IllegalArgumentException if the resulting image 1057 * would have a width or height less than 1. 1058 * @exception IOException if an error occurs during reading. 1059 */ 1060 public IIOImage readAll(int imageIndex, ImageReadParam param) 1061 throws IOException { 1062 if (imageIndex < getMinIndex()) { 1063 throw new IndexOutOfBoundsException("imageIndex < getMinIndex()!"); 1064 } 1065 1066 BufferedImage im = read(imageIndex, param); 1067 1068 ArrayList<BufferedImage> thumbnails = null; 1069 int numThumbnails = getNumThumbnails(imageIndex); 1070 if (numThumbnails > 0) { 1071 thumbnails = new ArrayList<>(); 1072 for (int j = 0; j < numThumbnails; j++) { 1073 thumbnails.add(readThumbnail(imageIndex, j)); 1074 } 1075 } 1076 1077 IIOMetadata metadata = getImageMetadata(imageIndex); 1078 return new IIOImage(im, thumbnails, metadata); 1079 } 1080 1081 /** 1082 * Returns an {@code Iterator} containing all the images, 1083 * thumbnails, and metadata, starting at the index given by 1084 * {@code getMinIndex}, from the input source in the form of 1085 * {@code IIOImage} objects. An {@code Iterator} 1086 * containing {@code ImageReadParam} objects is supplied; one 1087 * element is consumed for each image read from the input source 1088 * until no more images are available. If the read param 1089 * {@code Iterator} runs out of elements, but there are still 1090 * more images available from the input source, default read 1091 * params are used for the remaining images. 1092 * 1093 * <p> If {@code params} is {@code null}, a default read 1094 * param will be used for all images. 1095 * 1096 * <p> The actual {@code BufferedImage} referenced by the 1097 * returned {@code IIOImage} will be chosen using the 1098 * algorithm defined by the {@code getDestination} method. 1099 * 1100 * <p> Any registered {@code IIOReadProgressListener} objects 1101 * will be notified by calling their {@code sequenceStarted} 1102 * method once. Then, for each image decoded, there will be a 1103 * call to {@code imageStarted}, followed by calls to 1104 * {@code imageProgress} as the read progresses, and finally 1105 * to {@code imageComplete}. The 1106 * {@code sequenceComplete} method will be called after the 1107 * last image has been decoded. 1108 * {@code IIOReadUpdateListener} objects may be updated at 1109 * other times during the read as pixels are decoded. Finally, 1110 * {@code IIOReadWarningListener} objects will receive 1111 * notification of any non-fatal warnings that occur during 1112 * decoding. 1113 * 1114 * <p> The set of source bands to be read and destination bands to 1115 * be written is determined by calling {@code getSourceBands} 1116 * and {@code getDestinationBands} on the supplied 1117 * {@code ImageReadParam}. If the lengths of the arrays 1118 * returned by these methods differ, the set of source bands 1119 * contains an index larger that the largest available source 1120 * index, or the set of destination bands contains an index larger 1121 * than the largest legal destination index, an 1122 * {@code IllegalArgumentException} is thrown. 1123 * 1124 * <p> Thumbnails will be returned in their entirety regardless of the 1125 * region settings. 1126 * 1127 * <p> If any of the supplied {@code ImageReadParam}s contain 1128 * optional setting values not supported by this reader (<i>e.g.</i> 1129 * source render size or any format-specific settings), they will 1130 * be ignored. 1131 * 1132 * @param params an {@code Iterator} containing 1133 * {@code ImageReadParam} objects. 1134 * 1135 * @return an {@code Iterator} representing the 1136 * contents of the input source as {@code IIOImage}s. 1137 * 1138 * @exception IllegalStateException if the input source has not been 1139 * set. 1140 * @exception IllegalArgumentException if any 1141 * non-{@code null} element of {@code params} is not an 1142 * {@code ImageReadParam}. 1143 * @exception IllegalArgumentException if the set of source and 1144 * destination bands specified by 1145 * {@code param.getSourceBands} and 1146 * {@code param.getDestinationBands} differ in length or 1147 * include indices that are out of bounds. 1148 * @exception IllegalArgumentException if a resulting image would 1149 * have a width or height less than 1. 1150 * @exception IOException if an error occurs during reading. 1151 * 1152 * @see ImageReadParam 1153 * @see IIOImage 1154 */ 1155 public Iterator<IIOImage> 1156 readAll(Iterator<? extends ImageReadParam> params) 1157 throws IOException 1158 { 1159 List<IIOImage> output = new ArrayList<>(); 1160 1161 int imageIndex = getMinIndex(); 1162 1163 // Inform IIOReadProgressListeners we're starting a sequence 1164 processSequenceStarted(imageIndex); 1165 1166 while (true) { 1167 // Inform IIOReadProgressListeners and IIOReadUpdateListeners 1168 // that we're starting a new image 1169 1170 ImageReadParam param = null; 1171 if (params != null && params.hasNext()) { 1172 Object o = params.next(); 1173 if (o != null) { 1174 if (o instanceof ImageReadParam) { 1175 param = (ImageReadParam)o; 1176 } else { 1177 throw new IllegalArgumentException 1178 ("Non-ImageReadParam supplied as part of params!"); 1179 } 1180 } 1181 } 1182 1183 BufferedImage bi = null; 1184 try { 1185 bi = read(imageIndex, param); 1186 } catch (IndexOutOfBoundsException e) { 1187 break; 1188 } 1189 1190 ArrayList<BufferedImage> thumbnails = null; 1191 int numThumbnails = getNumThumbnails(imageIndex); 1192 if (numThumbnails > 0) { 1193 thumbnails = new ArrayList<>(); 1194 for (int j = 0; j < numThumbnails; j++) { 1195 thumbnails.add(readThumbnail(imageIndex, j)); 1196 } 1197 } 1198 1199 IIOMetadata metadata = getImageMetadata(imageIndex); 1200 IIOImage im = new IIOImage(bi, thumbnails, metadata); 1201 output.add(im); 1202 1203 ++imageIndex; 1204 } 1205 1206 // Inform IIOReadProgressListeners we're ending a sequence 1207 processSequenceComplete(); 1208 1209 return output.iterator(); 1210 } 1211 1212 /** 1213 * Returns {@code true} if this plug-in supports reading 1214 * just a {@link java.awt.image.Raster Raster} of pixel data. 1215 * If this method returns {@code false}, calls to 1216 * {@link #readRaster readRaster} or {@link #readTileRaster readTileRaster} 1217 * will throw an {@code UnsupportedOperationException}. 1218 * 1219 * <p> The default implementation returns {@code false}. 1220 * 1221 * @return {@code true} if this plug-in supports reading raw 1222 * {@code Raster}s. 1223 * 1224 * @see #readRaster 1225 * @see #readTileRaster 1226 */ 1227 public boolean canReadRaster() { 1228 return false; 1229 } 1230 1231 /** 1232 * Returns a new {@code Raster} object containing the raw pixel data 1233 * from the image stream, without any color conversion applied. The 1234 * application must determine how to interpret the pixel data by other 1235 * means. Any destination or image-type parameters in the supplied 1236 * {@code ImageReadParam} object are ignored, but all other 1237 * parameters are used exactly as in the {@link #read read} 1238 * method, except that any destination offset is used as a logical rather 1239 * than a physical offset. The size of the returned {@code Raster} 1240 * will always be that of the source region clipped to the actual image. 1241 * Logical offsets in the stream itself are ignored. 1242 * 1243 * <p> This method allows formats that normally apply a color 1244 * conversion, such as JPEG, and formats that do not normally have an 1245 * associated colorspace, such as remote sensing or medical imaging data, 1246 * to provide access to raw pixel data. 1247 * 1248 * <p> Any registered {@code readUpdateListener}s are ignored, as 1249 * there is no {@code BufferedImage}, but all other listeners are 1250 * called exactly as they are for the {@link #read read} method. 1251 * 1252 * <p> If {@link #canReadRaster canReadRaster()} returns 1253 * {@code false}, this method throws an 1254 * {@code UnsupportedOperationException}. 1255 * 1256 * <p> If the supplied {@code ImageReadParam} contains 1257 * optional setting values not supported by this reader (<i>e.g.</i> 1258 * source render size or any format-specific settings), they will 1259 * be ignored. 1260 * 1261 * <p> The default implementation throws an 1262 * {@code UnsupportedOperationException}. 1263 * 1264 * @param imageIndex the index of the image to be read. 1265 * @param param an {@code ImageReadParam} used to control 1266 * the reading process, or {@code null}. 1267 * 1268 * @return the desired portion of the image as a 1269 * {@code Raster}. 1270 * 1271 * @exception UnsupportedOperationException if this plug-in does not 1272 * support reading raw {@code Raster}s. 1273 * @exception IllegalStateException if the input source has not been 1274 * set. 1275 * @exception IndexOutOfBoundsException if the supplied index is 1276 * out of bounds. 1277 * @exception IOException if an error occurs during reading. 1278 * 1279 * @see #canReadRaster 1280 * @see #read 1281 * @see java.awt.image.Raster 1282 */ 1283 public Raster readRaster(int imageIndex, ImageReadParam param) 1284 throws IOException { 1285 throw new UnsupportedOperationException("readRaster not supported!"); 1286 } 1287 1288 /** 1289 * Returns {@code true} if the image is organized into 1290 * <i>tiles</i>, that is, equal-sized non-overlapping rectangles. 1291 * 1292 * <p> A reader plug-in may choose whether or not to expose tiling 1293 * that is present in the image as it is stored. It may even 1294 * choose to advertise tiling when none is explicitly present. In 1295 * general, tiling should only be advertised if there is some 1296 * advantage (in speed or space) to accessing individual tiles. 1297 * Regardless of whether the reader advertises tiling, it must be 1298 * capable of reading an arbitrary rectangular region specified in 1299 * an {@code ImageReadParam}. 1300 * 1301 * <p> A reader for which all images are guaranteed to be tiled, 1302 * or are guaranteed not to be tiled, may return {@code true} 1303 * or {@code false} respectively without accessing any image 1304 * data. In such cases, it is not necessary to throw an exception 1305 * even if no input source has been set or the image index is out 1306 * of bounds. 1307 * 1308 * <p> The default implementation just returns {@code false}. 1309 * 1310 * @param imageIndex the index of the image to be queried. 1311 * 1312 * @return {@code true} if the image is tiled. 1313 * 1314 * @exception IllegalStateException if an input source is required 1315 * to determine the return value, but none has been set. 1316 * @exception IndexOutOfBoundsException if an image must be 1317 * accessed to determine the return value, but the supplied index 1318 * is out of bounds. 1319 * @exception IOException if an error occurs during reading. 1320 */ 1321 public boolean isImageTiled(int imageIndex) throws IOException { 1322 return false; 1323 } 1324 1325 /** 1326 * Returns the width of a tile in the given image. 1327 * 1328 * <p> The default implementation simply returns 1329 * {@code getWidth(imageIndex)}, which is correct for 1330 * non-tiled images. Readers that support tiling should override 1331 * this method. 1332 * 1333 * @return the width of a tile. 1334 * 1335 * @param imageIndex the index of the image to be queried. 1336 * 1337 * @exception IllegalStateException if the input source has not been set. 1338 * @exception IndexOutOfBoundsException if the supplied index is 1339 * out of bounds. 1340 * @exception IOException if an error occurs during reading. 1341 */ 1342 public int getTileWidth(int imageIndex) throws IOException { 1343 return getWidth(imageIndex); 1344 } 1345 1346 /** 1347 * Returns the height of a tile in the given image. 1348 * 1349 * <p> The default implementation simply returns 1350 * {@code getHeight(imageIndex)}, which is correct for 1351 * non-tiled images. Readers that support tiling should override 1352 * this method. 1353 * 1354 * @return the height of a tile. 1355 * 1356 * @param imageIndex the index of the image to be queried. 1357 * 1358 * @exception IllegalStateException if the input source has not been set. 1359 * @exception IndexOutOfBoundsException if the supplied index is 1360 * out of bounds. 1361 * @exception IOException if an error occurs during reading. 1362 */ 1363 public int getTileHeight(int imageIndex) throws IOException { 1364 return getHeight(imageIndex); 1365 } 1366 1367 /** 1368 * Returns the X coordinate of the upper-left corner of tile (0, 1369 * 0) in the given image. 1370 * 1371 * <p> A reader for which the tile grid X offset always has the 1372 * same value (usually 0), may return the value without accessing 1373 * any image data. In such cases, it is not necessary to throw an 1374 * exception even if no input source has been set or the image 1375 * index is out of bounds. 1376 * 1377 * <p> The default implementation simply returns 0, which is 1378 * correct for non-tiled images and tiled images in most formats. 1379 * Readers that support tiling with non-(0, 0) offsets should 1380 * override this method. 1381 * 1382 * @return the X offset of the tile grid. 1383 * 1384 * @param imageIndex the index of the image to be queried. 1385 * 1386 * @exception IllegalStateException if an input source is required 1387 * to determine the return value, but none has been set. 1388 * @exception IndexOutOfBoundsException if an image must be 1389 * accessed to determine the return value, but the supplied index 1390 * is out of bounds. 1391 * @exception IOException if an error occurs during reading. 1392 */ 1393 public int getTileGridXOffset(int imageIndex) throws IOException { 1394 return 0; 1395 } 1396 1397 /** 1398 * Returns the Y coordinate of the upper-left corner of tile (0, 1399 * 0) in the given image. 1400 * 1401 * <p> A reader for which the tile grid Y offset always has the 1402 * same value (usually 0), may return the value without accessing 1403 * any image data. In such cases, it is not necessary to throw an 1404 * exception even if no input source has been set or the image 1405 * index is out of bounds. 1406 * 1407 * <p> The default implementation simply returns 0, which is 1408 * correct for non-tiled images and tiled images in most formats. 1409 * Readers that support tiling with non-(0, 0) offsets should 1410 * override this method. 1411 * 1412 * @return the Y offset of the tile grid. 1413 * 1414 * @param imageIndex the index of the image to be queried. 1415 * 1416 * @exception IllegalStateException if an input source is required 1417 * to determine the return value, but none has been set. 1418 * @exception IndexOutOfBoundsException if an image must be 1419 * accessed to determine the return value, but the supplied index 1420 * is out of bounds. 1421 * @exception IOException if an error occurs during reading. 1422 */ 1423 public int getTileGridYOffset(int imageIndex) throws IOException { 1424 return 0; 1425 } 1426 1427 /** 1428 * Reads the tile indicated by the {@code tileX} and 1429 * {@code tileY} arguments, returning it as a 1430 * {@code BufferedImage}. If the arguments are out of range, 1431 * an {@code IllegalArgumentException} is thrown. If the 1432 * image is not tiled, the values 0, 0 will return the entire 1433 * image; any other values will cause an 1434 * {@code IllegalArgumentException} to be thrown. 1435 * 1436 * <p> This method is merely a convenience equivalent to calling 1437 * {@code read(int, ImageReadParam)} with a read param 1438 * specifying a source region having offsets of 1439 * {@code tileX*getTileWidth(imageIndex)}, 1440 * {@code tileY*getTileHeight(imageIndex)} and width and 1441 * height of {@code getTileWidth(imageIndex)}, 1442 * {@code getTileHeight(imageIndex)}; and subsampling 1443 * factors of 1 and offsets of 0. To subsample a tile, call 1444 * {@code read} with a read param specifying this region 1445 * and different subsampling parameters. 1446 * 1447 * <p> The default implementation returns the entire image if 1448 * {@code tileX} and {@code tileY} are 0, or throws 1449 * an {@code IllegalArgumentException} otherwise. 1450 * 1451 * @param imageIndex the index of the image to be retrieved. 1452 * @param tileX the column index (starting with 0) of the tile 1453 * to be retrieved. 1454 * @param tileY the row index (starting with 0) of the tile 1455 * to be retrieved. 1456 * 1457 * @return the tile as a {@code BufferedImage}. 1458 * 1459 * @exception IllegalStateException if the input source has not been 1460 * set. 1461 * @exception IndexOutOfBoundsException if {@code imageIndex} 1462 * is out of bounds. 1463 * @exception IllegalArgumentException if the tile indices are 1464 * out of bounds. 1465 * @exception IOException if an error occurs during reading. 1466 */ 1467 public BufferedImage readTile(int imageIndex, 1468 int tileX, int tileY) throws IOException { 1469 if ((tileX != 0) || (tileY != 0)) { 1470 throw new IllegalArgumentException("Invalid tile indices"); 1471 } 1472 return read(imageIndex); 1473 } 1474 1475 /** 1476 * Returns a new {@code Raster} object containing the raw 1477 * pixel data from the tile, without any color conversion applied. 1478 * The application must determine how to interpret the pixel data by other 1479 * means. 1480 * 1481 * <p> If {@link #canReadRaster canReadRaster()} returns 1482 * {@code false}, this method throws an 1483 * {@code UnsupportedOperationException}. 1484 * 1485 * <p> The default implementation checks if reading 1486 * {@code Raster}s is supported, and if so calls {@link 1487 * #readRaster readRaster(imageIndex, null)} if 1488 * {@code tileX} and {@code tileY} are 0, or throws an 1489 * {@code IllegalArgumentException} otherwise. 1490 * 1491 * @param imageIndex the index of the image to be retrieved. 1492 * @param tileX the column index (starting with 0) of the tile 1493 * to be retrieved. 1494 * @param tileY the row index (starting with 0) of the tile 1495 * to be retrieved. 1496 * 1497 * @return the tile as a {@code Raster}. 1498 * 1499 * @exception UnsupportedOperationException if this plug-in does not 1500 * support reading raw {@code Raster}s. 1501 * @exception IllegalArgumentException if the tile indices are 1502 * out of bounds. 1503 * @exception IllegalStateException if the input source has not been 1504 * set. 1505 * @exception IndexOutOfBoundsException if {@code imageIndex} 1506 * is out of bounds. 1507 * @exception IOException if an error occurs during reading. 1508 * 1509 * @see #readTile 1510 * @see #readRaster 1511 * @see java.awt.image.Raster 1512 */ 1513 public Raster readTileRaster(int imageIndex, 1514 int tileX, int tileY) throws IOException { 1515 if (!canReadRaster()) { 1516 throw new UnsupportedOperationException 1517 ("readTileRaster not supported!"); 1518 } 1519 if ((tileX != 0) || (tileY != 0)) { 1520 throw new IllegalArgumentException("Invalid tile indices"); 1521 } 1522 return readRaster(imageIndex, null); 1523 } 1524 1525 // RenderedImages 1526 1527 /** 1528 * Returns a {@code RenderedImage} object that contains the 1529 * contents of the image indexed by {@code imageIndex}. By 1530 * default, the returned image is simply the 1531 * {@code BufferedImage} returned by 1532 * {@code read(imageIndex, param)}. 1533 * 1534 * <p> The semantics of this method may differ from those of the 1535 * other {@code read} methods in several ways. First, any 1536 * destination image and/or image type set in the 1537 * {@code ImageReadParam} may be ignored. Second, the usual 1538 * listener calls are not guaranteed to be made, or to be 1539 * meaningful if they are. This is because the returned image may 1540 * not be fully populated with pixel data at the time it is 1541 * returned, or indeed at any time. 1542 * 1543 * <p> If the supplied {@code ImageReadParam} contains 1544 * optional setting values not supported by this reader (<i>e.g.</i> 1545 * source render size or any format-specific settings), they will 1546 * be ignored. 1547 * 1548 * <p> The default implementation just calls 1549 * {@link #read read(imageIndex, param)}. 1550 * 1551 * @param imageIndex the index of the image to be retrieved. 1552 * @param param an {@code ImageReadParam} used to control 1553 * the reading process, or {@code null}. 1554 * 1555 * @return a {@code RenderedImage} object providing a view of 1556 * the image. 1557 * 1558 * @exception IllegalStateException if the input source has not been 1559 * set. 1560 * @exception IndexOutOfBoundsException if the supplied index is 1561 * out of bounds. 1562 * @exception IllegalArgumentException if the set of source and 1563 * destination bands specified by 1564 * {@code param.getSourceBands} and 1565 * {@code param.getDestinationBands} differ in length or 1566 * include indices that are out of bounds. 1567 * @exception IllegalArgumentException if the resulting image 1568 * would have a width or height less than 1. 1569 * @exception IOException if an error occurs during reading. 1570 */ 1571 public RenderedImage readAsRenderedImage(int imageIndex, 1572 ImageReadParam param) 1573 throws IOException { 1574 return read(imageIndex, param); 1575 } 1576 1577 // Thumbnails 1578 1579 /** 1580 * Returns {@code true} if the image format understood by 1581 * this reader supports thumbnail preview images associated with 1582 * it. The default implementation returns {@code false}. 1583 * 1584 * <p> If this method returns {@code false}, 1585 * {@code hasThumbnails} and {@code getNumThumbnails} 1586 * will return {@code false} and {@code 0}, 1587 * respectively, and {@code readThumbnail} will throw an 1588 * {@code UnsupportedOperationException}, regardless of their 1589 * arguments. 1590 * 1591 * <p> A reader that does not support thumbnails need not 1592 * implement any of the thumbnail-related methods. 1593 * 1594 * @return {@code true} if thumbnails are supported. 1595 */ 1596 public boolean readerSupportsThumbnails() { 1597 return false; 1598 } 1599 1600 /** 1601 * Returns {@code true} if the given image has thumbnail 1602 * preview images associated with it. If the format does not 1603 * support thumbnails ({@code readerSupportsThumbnails} 1604 * returns {@code false}), {@code false} will be 1605 * returned regardless of whether an input source has been set or 1606 * whether {@code imageIndex} is in bounds. 1607 * 1608 * <p> The default implementation returns {@code true} if 1609 * {@code getNumThumbnails} returns a value greater than 0. 1610 * 1611 * @param imageIndex the index of the image being queried. 1612 * 1613 * @return {@code true} if the given image has thumbnails. 1614 * 1615 * @exception IllegalStateException if the reader supports 1616 * thumbnails but the input source has not been set. 1617 * @exception IndexOutOfBoundsException if the reader supports 1618 * thumbnails but {@code imageIndex} is out of bounds. 1619 * @exception IOException if an error occurs during reading. 1620 */ 1621 public boolean hasThumbnails(int imageIndex) throws IOException { 1622 return getNumThumbnails(imageIndex) > 0; 1623 } 1624 1625 /** 1626 * Returns the number of thumbnail preview images associated with 1627 * the given image. If the format does not support thumbnails, 1628 * ({@code readerSupportsThumbnails} returns 1629 * {@code false}), {@code 0} will be returned regardless 1630 * of whether an input source has been set or whether 1631 * {@code imageIndex} is in bounds. 1632 * 1633 * <p> The default implementation returns 0 without checking its 1634 * argument. 1635 * 1636 * @param imageIndex the index of the image being queried. 1637 * 1638 * @return the number of thumbnails associated with the given 1639 * image. 1640 * 1641 * @exception IllegalStateException if the reader supports 1642 * thumbnails but the input source has not been set. 1643 * @exception IndexOutOfBoundsException if the reader supports 1644 * thumbnails but {@code imageIndex} is out of bounds. 1645 * @exception IOException if an error occurs during reading. 1646 */ 1647 public int getNumThumbnails(int imageIndex) 1648 throws IOException { 1649 return 0; 1650 } 1651 1652 /** 1653 * Returns the width of the thumbnail preview image indexed by 1654 * {@code thumbnailIndex}, associated with the image indexed 1655 * by {@code ImageIndex}. 1656 * 1657 * <p> If the reader does not support thumbnails, 1658 * ({@code readerSupportsThumbnails} returns 1659 * {@code false}), an {@code UnsupportedOperationException} 1660 * will be thrown. 1661 * 1662 * <p> The default implementation simply returns 1663 * {@code readThumbnail(imageindex, thumbnailIndex).getWidth()}. 1664 * Subclasses should therefore 1665 * override this method if possible in order to avoid forcing the 1666 * thumbnail to be read. 1667 * 1668 * @param imageIndex the index of the image to be retrieved. 1669 * @param thumbnailIndex the index of the thumbnail to be retrieved. 1670 * 1671 * @return the width of the desired thumbnail as an {@code int}. 1672 * 1673 * @exception UnsupportedOperationException if thumbnails are not 1674 * supported. 1675 * @exception IllegalStateException if the input source has not been set. 1676 * @exception IndexOutOfBoundsException if either of the supplied 1677 * indices are out of bounds. 1678 * @exception IOException if an error occurs during reading. 1679 */ 1680 public int getThumbnailWidth(int imageIndex, int thumbnailIndex) 1681 throws IOException { 1682 return readThumbnail(imageIndex, thumbnailIndex).getWidth(); 1683 } 1684 1685 /** 1686 * Returns the height of the thumbnail preview image indexed by 1687 * {@code thumbnailIndex}, associated with the image indexed 1688 * by {@code ImageIndex}. 1689 * 1690 * <p> If the reader does not support thumbnails, 1691 * ({@code readerSupportsThumbnails} returns 1692 * {@code false}), an {@code UnsupportedOperationException} 1693 * will be thrown. 1694 * 1695 * <p> The default implementation simply returns 1696 * {@code readThumbnail(imageindex, thumbnailIndex).getHeight()}. 1697 * Subclasses should therefore override 1698 * this method if possible in order to avoid 1699 * forcing the thumbnail to be read. 1700 * 1701 * @param imageIndex the index of the image to be retrieved. 1702 * @param thumbnailIndex the index of the thumbnail to be retrieved. 1703 * 1704 * @return the height of the desired thumbnail as an {@code int}. 1705 * 1706 * @exception UnsupportedOperationException if thumbnails are not 1707 * supported. 1708 * @exception IllegalStateException if the input source has not been set. 1709 * @exception IndexOutOfBoundsException if either of the supplied 1710 * indices are out of bounds. 1711 * @exception IOException if an error occurs during reading. 1712 */ 1713 public int getThumbnailHeight(int imageIndex, int thumbnailIndex) 1714 throws IOException { 1715 return readThumbnail(imageIndex, thumbnailIndex).getHeight(); 1716 } 1717 1718 /** 1719 * Returns the thumbnail preview image indexed by 1720 * {@code thumbnailIndex}, associated with the image indexed 1721 * by {@code ImageIndex} as a {@code BufferedImage}. 1722 * 1723 * <p> Any registered {@code IIOReadProgressListener} objects 1724 * will be notified by calling their 1725 * {@code thumbnailStarted}, {@code thumbnailProgress}, 1726 * and {@code thumbnailComplete} methods. 1727 * 1728 * <p> If the reader does not support thumbnails, 1729 * ({@code readerSupportsThumbnails} returns 1730 * {@code false}), an {@code UnsupportedOperationException} 1731 * will be thrown regardless of whether an input source has been 1732 * set or whether the indices are in bounds. 1733 * 1734 * <p> The default implementation throws an 1735 * {@code UnsupportedOperationException}. 1736 * 1737 * @param imageIndex the index of the image to be retrieved. 1738 * @param thumbnailIndex the index of the thumbnail to be retrieved. 1739 * 1740 * @return the desired thumbnail as a {@code BufferedImage}. 1741 * 1742 * @exception UnsupportedOperationException if thumbnails are not 1743 * supported. 1744 * @exception IllegalStateException if the input source has not been set. 1745 * @exception IndexOutOfBoundsException if either of the supplied 1746 * indices are out of bounds. 1747 * @exception IOException if an error occurs during reading. 1748 */ 1749 public BufferedImage readThumbnail(int imageIndex, 1750 int thumbnailIndex) 1751 throws IOException { 1752 throw new UnsupportedOperationException("Thumbnails not supported!"); 1753 } 1754 1755 // Abort 1756 1757 /** 1758 * Requests that any current read operation be aborted. The 1759 * contents of the image following the abort will be undefined. 1760 * 1761 * <p> Readers should call {@code clearAbortRequest} at the 1762 * beginning of each read operation, and poll the value of 1763 * {@code abortRequested} regularly during the read. 1764 */ 1765 public synchronized void abort() { 1766 this.abortFlag = true; 1767 } 1768 1769 /** 1770 * Returns {@code true} if a request to abort the current 1771 * read operation has been made since the reader was instantiated or 1772 * {@code clearAbortRequest} was called. 1773 * 1774 * @return {@code true} if the current read operation should 1775 * be aborted. 1776 * 1777 * @see #abort 1778 * @see #clearAbortRequest 1779 */ 1780 protected synchronized boolean abortRequested() { 1781 return this.abortFlag; 1782 } 1783 1784 /** 1785 * Clears any previous abort request. After this method has been 1786 * called, {@code abortRequested} will return 1787 * {@code false}. 1788 * 1789 * @see #abort 1790 * @see #abortRequested 1791 */ 1792 protected synchronized void clearAbortRequest() { 1793 this.abortFlag = false; 1794 } 1795 1796 // Listeners 1797 1798 // Add an element to a list, creating a new list if the 1799 // existing list is null, and return the list. 1800 static <T> List<T> addToList(List<T> l, T elt) { 1801 if (l == null) { 1802 l = new ArrayList<>(); 1803 } 1804 l.add(elt); 1805 return l; 1806 } 1807 1808 1809 // Remove an element from a list, discarding the list if the 1810 // resulting list is empty, and return the list or null. 1811 static <T> List<T> removeFromList(List<T> l, T elt) { 1812 if (l == null) { 1813 return l; 1814 } 1815 l.remove(elt); 1816 if (l.size() == 0) { 1817 l = null; 1818 } 1819 return l; 1820 } 1821 1822 /** 1823 * Adds an {@code IIOReadWarningListener} to the list of 1824 * registered warning listeners. If {@code listener} is 1825 * {@code null}, no exception will be thrown and no action 1826 * will be taken. Messages sent to the given listener will be 1827 * localized, if possible, to match the current 1828 * {@code Locale}. If no {@code Locale} has been set, 1829 * warning messages may be localized as the reader sees fit. 1830 * 1831 * @param listener an {@code IIOReadWarningListener} to be registered. 1832 * 1833 * @see #removeIIOReadWarningListener 1834 */ 1835 public void addIIOReadWarningListener(IIOReadWarningListener listener) { 1836 if (listener == null) { 1837 return; 1838 } 1839 warningListeners = addToList(warningListeners, listener); 1840 warningLocales = addToList(warningLocales, getLocale()); 1841 } 1842 1843 /** 1844 * Removes an {@code IIOReadWarningListener} from the list of 1845 * registered error listeners. If the listener was not previously 1846 * registered, or if {@code listener} is {@code null}, 1847 * no exception will be thrown and no action will be taken. 1848 * 1849 * @param listener an IIOReadWarningListener to be unregistered. 1850 * 1851 * @see #addIIOReadWarningListener 1852 */ 1853 public void removeIIOReadWarningListener(IIOReadWarningListener listener) { 1854 if (listener == null || warningListeners == null) { 1855 return; 1856 } 1857 int index = warningListeners.indexOf(listener); 1858 if (index != -1) { 1859 warningListeners.remove(index); 1860 warningLocales.remove(index); 1861 if (warningListeners.size() == 0) { 1862 warningListeners = null; 1863 warningLocales = null; 1864 } 1865 } 1866 } 1867 1868 /** 1869 * Removes all currently registered 1870 * {@code IIOReadWarningListener} objects. 1871 * 1872 * <p> The default implementation sets the 1873 * {@code warningListeners} and {@code warningLocales} 1874 * instance variables to {@code null}. 1875 */ 1876 public void removeAllIIOReadWarningListeners() { 1877 warningListeners = null; 1878 warningLocales = null; 1879 } 1880 1881 /** 1882 * Adds an {@code IIOReadProgressListener} to the list of 1883 * registered progress listeners. If {@code listener} is 1884 * {@code null}, no exception will be thrown and no action 1885 * will be taken. 1886 * 1887 * @param listener an IIOReadProgressListener to be registered. 1888 * 1889 * @see #removeIIOReadProgressListener 1890 */ 1891 public void addIIOReadProgressListener(IIOReadProgressListener listener) { 1892 if (listener == null) { 1893 return; 1894 } 1895 progressListeners = addToList(progressListeners, listener); 1896 } 1897 1898 /** 1899 * Removes an {@code IIOReadProgressListener} from the list 1900 * of registered progress listeners. If the listener was not 1901 * previously registered, or if {@code listener} is 1902 * {@code null}, no exception will be thrown and no action 1903 * will be taken. 1904 * 1905 * @param listener an IIOReadProgressListener to be unregistered. 1906 * 1907 * @see #addIIOReadProgressListener 1908 */ 1909 public void 1910 removeIIOReadProgressListener (IIOReadProgressListener listener) { 1911 if (listener == null || progressListeners == null) { 1912 return; 1913 } 1914 progressListeners = removeFromList(progressListeners, listener); 1915 } 1916 1917 /** 1918 * Removes all currently registered 1919 * {@code IIOReadProgressListener} objects. 1920 * 1921 * <p> The default implementation sets the 1922 * {@code progressListeners} instance variable to 1923 * {@code null}. 1924 */ 1925 public void removeAllIIOReadProgressListeners() { 1926 progressListeners = null; 1927 } 1928 1929 /** 1930 * Adds an {@code IIOReadUpdateListener} to the list of 1931 * registered update listeners. If {@code listener} is 1932 * {@code null}, no exception will be thrown and no action 1933 * will be taken. The listener will receive notification of pixel 1934 * updates as images and thumbnails are decoded, including the 1935 * starts and ends of progressive passes. 1936 * 1937 * <p> If no update listeners are present, the reader may choose 1938 * to perform fewer updates to the pixels of the destination 1939 * images and/or thumbnails, which may result in more efficient 1940 * decoding. 1941 * 1942 * <p> For example, in progressive JPEG decoding each pass 1943 * contains updates to a set of coefficients, which would have to 1944 * be transformed into pixel values and converted to an RGB color 1945 * space for each pass if listeners are present. If no listeners 1946 * are present, the coefficients may simply be accumulated and the 1947 * final results transformed and color converted one time only. 1948 * 1949 * <p> The final results of decoding will be the same whether or 1950 * not intermediate updates are performed. Thus if only the final 1951 * image is desired it may be preferable not to register any 1952 * {@code IIOReadUpdateListener}s. In general, progressive 1953 * updating is most effective when fetching images over a network 1954 * connection that is very slow compared to local CPU processing; 1955 * over a fast connection, progressive updates may actually slow 1956 * down the presentation of the image. 1957 * 1958 * @param listener an IIOReadUpdateListener to be registered. 1959 * 1960 * @see #removeIIOReadUpdateListener 1961 */ 1962 public void 1963 addIIOReadUpdateListener(IIOReadUpdateListener listener) { 1964 if (listener == null) { 1965 return; 1966 } 1967 updateListeners = addToList(updateListeners, listener); 1968 } 1969 1970 /** 1971 * Removes an {@code IIOReadUpdateListener} from the list of 1972 * registered update listeners. If the listener was not 1973 * previously registered, or if {@code listener} is 1974 * {@code null}, no exception will be thrown and no action 1975 * will be taken. 1976 * 1977 * @param listener an IIOReadUpdateListener to be unregistered. 1978 * 1979 * @see #addIIOReadUpdateListener 1980 */ 1981 public void removeIIOReadUpdateListener(IIOReadUpdateListener listener) { 1982 if (listener == null || updateListeners == null) { 1983 return; 1984 } 1985 updateListeners = removeFromList(updateListeners, listener); 1986 } 1987 1988 /** 1989 * Removes all currently registered 1990 * {@code IIOReadUpdateListener} objects. 1991 * 1992 * <p> The default implementation sets the 1993 * {@code updateListeners} instance variable to 1994 * {@code null}. 1995 */ 1996 public void removeAllIIOReadUpdateListeners() { 1997 updateListeners = null; 1998 } 1999 2000 /** 2001 * Broadcasts the start of an sequence of image reads to all 2002 * registered {@code IIOReadProgressListener}s by calling 2003 * their {@code sequenceStarted} method. Subclasses may use 2004 * this method as a convenience. 2005 * 2006 * @param minIndex the lowest index being read. 2007 */ 2008 protected void processSequenceStarted(int minIndex) { 2009 if (progressListeners == null) { 2010 return; 2011 } 2012 int numListeners = progressListeners.size(); 2013 for (int i = 0; i < numListeners; i++) { 2014 IIOReadProgressListener listener = 2015 progressListeners.get(i); 2016 listener.sequenceStarted(this, minIndex); 2017 } 2018 } 2019 2020 /** 2021 * Broadcasts the completion of an sequence of image reads to all 2022 * registered {@code IIOReadProgressListener}s by calling 2023 * their {@code sequenceComplete} method. Subclasses may use 2024 * this method as a convenience. 2025 */ 2026 protected void processSequenceComplete() { 2027 if (progressListeners == null) { 2028 return; 2029 } 2030 int numListeners = progressListeners.size(); 2031 for (int i = 0; i < numListeners; i++) { 2032 IIOReadProgressListener listener = 2033 progressListeners.get(i); 2034 listener.sequenceComplete(this); 2035 } 2036 } 2037 2038 /** 2039 * Broadcasts the start of an image read to all registered 2040 * {@code IIOReadProgressListener}s by calling their 2041 * {@code imageStarted} method. Subclasses may use this 2042 * method as a convenience. 2043 * 2044 * @param imageIndex the index of the image about to be read. 2045 */ 2046 protected void processImageStarted(int imageIndex) { 2047 if (progressListeners == null) { 2048 return; 2049 } 2050 int numListeners = progressListeners.size(); 2051 for (int i = 0; i < numListeners; i++) { 2052 IIOReadProgressListener listener = 2053 progressListeners.get(i); 2054 listener.imageStarted(this, imageIndex); 2055 } 2056 } 2057 2058 /** 2059 * Broadcasts the current percentage of image completion to all 2060 * registered {@code IIOReadProgressListener}s by calling 2061 * their {@code imageProgress} method. Subclasses may use 2062 * this method as a convenience. 2063 * 2064 * @param percentageDone the current percentage of completion, 2065 * as a {@code float}. 2066 */ 2067 protected void processImageProgress(float percentageDone) { 2068 if (progressListeners == null) { 2069 return; 2070 } 2071 int numListeners = progressListeners.size(); 2072 for (int i = 0; i < numListeners; i++) { 2073 IIOReadProgressListener listener = 2074 progressListeners.get(i); 2075 listener.imageProgress(this, percentageDone); 2076 } 2077 } 2078 2079 /** 2080 * Broadcasts the completion of an image read to all registered 2081 * {@code IIOReadProgressListener}s by calling their 2082 * {@code imageComplete} method. Subclasses may use this 2083 * method as a convenience. 2084 */ 2085 protected void processImageComplete() { 2086 if (progressListeners == null) { 2087 return; 2088 } 2089 int numListeners = progressListeners.size(); 2090 for (int i = 0; i < numListeners; i++) { 2091 IIOReadProgressListener listener = 2092 progressListeners.get(i); 2093 listener.imageComplete(this); 2094 } 2095 } 2096 2097 /** 2098 * Broadcasts the start of a thumbnail read to all registered 2099 * {@code IIOReadProgressListener}s by calling their 2100 * {@code thumbnailStarted} method. Subclasses may use this 2101 * method as a convenience. 2102 * 2103 * @param imageIndex the index of the image associated with the 2104 * thumbnail. 2105 * @param thumbnailIndex the index of the thumbnail. 2106 */ 2107 protected void processThumbnailStarted(int imageIndex, 2108 int thumbnailIndex) { 2109 if (progressListeners == null) { 2110 return; 2111 } 2112 int numListeners = progressListeners.size(); 2113 for (int i = 0; i < numListeners; i++) { 2114 IIOReadProgressListener listener = 2115 progressListeners.get(i); 2116 listener.thumbnailStarted(this, imageIndex, thumbnailIndex); 2117 } 2118 } 2119 2120 /** 2121 * Broadcasts the current percentage of thumbnail completion to 2122 * all registered {@code IIOReadProgressListener}s by calling 2123 * their {@code thumbnailProgress} method. Subclasses may 2124 * use this method as a convenience. 2125 * 2126 * @param percentageDone the current percentage of completion, 2127 * as a {@code float}. 2128 */ 2129 protected void processThumbnailProgress(float percentageDone) { 2130 if (progressListeners == null) { 2131 return; 2132 } 2133 int numListeners = progressListeners.size(); 2134 for (int i = 0; i < numListeners; i++) { 2135 IIOReadProgressListener listener = 2136 progressListeners.get(i); 2137 listener.thumbnailProgress(this, percentageDone); 2138 } 2139 } 2140 2141 /** 2142 * Broadcasts the completion of a thumbnail read to all registered 2143 * {@code IIOReadProgressListener}s by calling their 2144 * {@code thumbnailComplete} method. Subclasses may use this 2145 * method as a convenience. 2146 */ 2147 protected void processThumbnailComplete() { 2148 if (progressListeners == null) { 2149 return; 2150 } 2151 int numListeners = progressListeners.size(); 2152 for (int i = 0; i < numListeners; i++) { 2153 IIOReadProgressListener listener = 2154 progressListeners.get(i); 2155 listener.thumbnailComplete(this); 2156 } 2157 } 2158 2159 /** 2160 * Broadcasts that the read has been aborted to all registered 2161 * {@code IIOReadProgressListener}s by calling their 2162 * {@code readAborted} method. Subclasses may use this 2163 * method as a convenience. 2164 */ 2165 protected void processReadAborted() { 2166 if (progressListeners == null) { 2167 return; 2168 } 2169 int numListeners = progressListeners.size(); 2170 for (int i = 0; i < numListeners; i++) { 2171 IIOReadProgressListener listener = 2172 progressListeners.get(i); 2173 listener.readAborted(this); 2174 } 2175 } 2176 2177 /** 2178 * Broadcasts the beginning of a progressive pass to all 2179 * registered {@code IIOReadUpdateListener}s by calling their 2180 * {@code passStarted} method. Subclasses may use this 2181 * method as a convenience. 2182 * 2183 * @param theImage the {@code BufferedImage} being updated. 2184 * @param pass the index of the current pass, starting with 0. 2185 * @param minPass the index of the first pass that will be decoded. 2186 * @param maxPass the index of the last pass that will be decoded. 2187 * @param minX the X coordinate of the upper-left pixel included 2188 * in the pass. 2189 * @param minY the X coordinate of the upper-left pixel included 2190 * in the pass. 2191 * @param periodX the horizontal separation between pixels. 2192 * @param periodY the vertical separation between pixels. 2193 * @param bands an array of {@code int}s indicating the 2194 * set of affected bands of the destination. 2195 */ 2196 protected void processPassStarted(BufferedImage theImage, 2197 int pass, 2198 int minPass, int maxPass, 2199 int minX, int minY, 2200 int periodX, int periodY, 2201 int[] bands) { 2202 if (updateListeners == null) { 2203 return; 2204 } 2205 int numListeners = updateListeners.size(); 2206 for (int i = 0; i < numListeners; i++) { 2207 IIOReadUpdateListener listener = 2208 updateListeners.get(i); 2209 listener.passStarted(this, theImage, pass, 2210 minPass, 2211 maxPass, 2212 minX, minY, 2213 periodX, periodY, 2214 bands); 2215 } 2216 } 2217 2218 /** 2219 * Broadcasts the update of a set of samples to all registered 2220 * {@code IIOReadUpdateListener}s by calling their 2221 * {@code imageUpdate} method. Subclasses may use this 2222 * method as a convenience. 2223 * 2224 * @param theImage the {@code BufferedImage} being updated. 2225 * @param minX the X coordinate of the upper-left pixel included 2226 * in the pass. 2227 * @param minY the X coordinate of the upper-left pixel included 2228 * in the pass. 2229 * @param width the total width of the area being updated, including 2230 * pixels being skipped if {@code periodX > 1}. 2231 * @param height the total height of the area being updated, 2232 * including pixels being skipped if {@code periodY > 1}. 2233 * @param periodX the horizontal separation between pixels. 2234 * @param periodY the vertical separation between pixels. 2235 * @param bands an array of {@code int}s indicating the 2236 * set of affected bands of the destination. 2237 */ 2238 protected void processImageUpdate(BufferedImage theImage, 2239 int minX, int minY, 2240 int width, int height, 2241 int periodX, int periodY, 2242 int[] bands) { 2243 if (updateListeners == null) { 2244 return; 2245 } 2246 int numListeners = updateListeners.size(); 2247 for (int i = 0; i < numListeners; i++) { 2248 IIOReadUpdateListener listener = 2249 updateListeners.get(i); 2250 listener.imageUpdate(this, 2251 theImage, 2252 minX, minY, 2253 width, height, 2254 periodX, periodY, 2255 bands); 2256 } 2257 } 2258 2259 /** 2260 * Broadcasts the end of a progressive pass to all 2261 * registered {@code IIOReadUpdateListener}s by calling their 2262 * {@code passComplete} method. Subclasses may use this 2263 * method as a convenience. 2264 * 2265 * @param theImage the {@code BufferedImage} being updated. 2266 */ 2267 protected void processPassComplete(BufferedImage theImage) { 2268 if (updateListeners == null) { 2269 return; 2270 } 2271 int numListeners = updateListeners.size(); 2272 for (int i = 0; i < numListeners; i++) { 2273 IIOReadUpdateListener listener = 2274 updateListeners.get(i); 2275 listener.passComplete(this, theImage); 2276 } 2277 } 2278 2279 /** 2280 * Broadcasts the beginning of a thumbnail progressive pass to all 2281 * registered {@code IIOReadUpdateListener}s by calling their 2282 * {@code thumbnailPassStarted} method. Subclasses may use this 2283 * method as a convenience. 2284 * 2285 * @param theThumbnail the {@code BufferedImage} thumbnail 2286 * being updated. 2287 * @param pass the index of the current pass, starting with 0. 2288 * @param minPass the index of the first pass that will be decoded. 2289 * @param maxPass the index of the last pass that will be decoded. 2290 * @param minX the X coordinate of the upper-left pixel included 2291 * in the pass. 2292 * @param minY the X coordinate of the upper-left pixel included 2293 * in the pass. 2294 * @param periodX the horizontal separation between pixels. 2295 * @param periodY the vertical separation between pixels. 2296 * @param bands an array of {@code int}s indicating the 2297 * set of affected bands of the destination. 2298 */ 2299 protected void processThumbnailPassStarted(BufferedImage theThumbnail, 2300 int pass, 2301 int minPass, int maxPass, 2302 int minX, int minY, 2303 int periodX, int periodY, 2304 int[] bands) { 2305 if (updateListeners == null) { 2306 return; 2307 } 2308 int numListeners = updateListeners.size(); 2309 for (int i = 0; i < numListeners; i++) { 2310 IIOReadUpdateListener listener = 2311 updateListeners.get(i); 2312 listener.thumbnailPassStarted(this, theThumbnail, pass, 2313 minPass, 2314 maxPass, 2315 minX, minY, 2316 periodX, periodY, 2317 bands); 2318 } 2319 } 2320 2321 /** 2322 * Broadcasts the update of a set of samples in a thumbnail image 2323 * to all registered {@code IIOReadUpdateListener}s by 2324 * calling their {@code thumbnailUpdate} method. Subclasses may 2325 * use this method as a convenience. 2326 * 2327 * @param theThumbnail the {@code BufferedImage} thumbnail 2328 * being updated. 2329 * @param minX the X coordinate of the upper-left pixel included 2330 * in the pass. 2331 * @param minY the X coordinate of the upper-left pixel included 2332 * in the pass. 2333 * @param width the total width of the area being updated, including 2334 * pixels being skipped if {@code periodX > 1}. 2335 * @param height the total height of the area being updated, 2336 * including pixels being skipped if {@code periodY > 1}. 2337 * @param periodX the horizontal separation between pixels. 2338 * @param periodY the vertical separation between pixels. 2339 * @param bands an array of {@code int}s indicating the 2340 * set of affected bands of the destination. 2341 */ 2342 protected void processThumbnailUpdate(BufferedImage theThumbnail, 2343 int minX, int minY, 2344 int width, int height, 2345 int periodX, int periodY, 2346 int[] bands) { 2347 if (updateListeners == null) { 2348 return; 2349 } 2350 int numListeners = updateListeners.size(); 2351 for (int i = 0; i < numListeners; i++) { 2352 IIOReadUpdateListener listener = 2353 updateListeners.get(i); 2354 listener.thumbnailUpdate(this, 2355 theThumbnail, 2356 minX, minY, 2357 width, height, 2358 periodX, periodY, 2359 bands); 2360 } 2361 } 2362 2363 /** 2364 * Broadcasts the end of a thumbnail progressive pass to all 2365 * registered {@code IIOReadUpdateListener}s by calling their 2366 * {@code thumbnailPassComplete} method. Subclasses may use this 2367 * method as a convenience. 2368 * 2369 * @param theThumbnail the {@code BufferedImage} thumbnail 2370 * being updated. 2371 */ 2372 protected void processThumbnailPassComplete(BufferedImage theThumbnail) { 2373 if (updateListeners == null) { 2374 return; 2375 } 2376 int numListeners = updateListeners.size(); 2377 for (int i = 0; i < numListeners; i++) { 2378 IIOReadUpdateListener listener = 2379 updateListeners.get(i); 2380 listener.thumbnailPassComplete(this, theThumbnail); 2381 } 2382 } 2383 2384 /** 2385 * Broadcasts a warning message to all registered 2386 * {@code IIOReadWarningListener}s by calling their 2387 * {@code warningOccurred} method. Subclasses may use this 2388 * method as a convenience. 2389 * 2390 * @param warning the warning message to send. 2391 * 2392 * @exception IllegalArgumentException if {@code warning} 2393 * is {@code null}. 2394 */ 2395 protected void processWarningOccurred(String warning) { 2396 if (warningListeners == null) { 2397 return; 2398 } 2399 if (warning == null) { 2400 throw new IllegalArgumentException("warning == null!"); 2401 } 2402 int numListeners = warningListeners.size(); 2403 for (int i = 0; i < numListeners; i++) { 2404 IIOReadWarningListener listener = 2405 warningListeners.get(i); 2406 2407 listener.warningOccurred(this, warning); 2408 } 2409 } 2410 2411 /** 2412 * Broadcasts a localized warning message to all registered 2413 * {@code IIOReadWarningListener}s by calling their 2414 * {@code warningOccurred} method with a string taken 2415 * from a {@code ResourceBundle}. Subclasses may use this 2416 * method as a convenience. 2417 * 2418 * @param baseName the base name of a set of 2419 * {@code ResourceBundle}s containing localized warning 2420 * messages. 2421 * @param keyword the keyword used to index the warning message 2422 * within the set of {@code ResourceBundle}s. 2423 * 2424 * @exception IllegalArgumentException if {@code baseName} 2425 * is {@code null}. 2426 * @exception IllegalArgumentException if {@code keyword} 2427 * is {@code null}. 2428 * @exception IllegalArgumentException if no appropriate 2429 * {@code ResourceBundle} may be located. 2430 * @exception IllegalArgumentException if the named resource is 2431 * not found in the located {@code ResourceBundle}. 2432 * @exception IllegalArgumentException if the object retrieved 2433 * from the {@code ResourceBundle} is not a 2434 * {@code String}. 2435 */ 2436 protected void processWarningOccurred(String baseName, 2437 String keyword) { 2438 if (warningListeners == null) { 2439 return; 2440 } 2441 if (baseName == null) { 2442 throw new IllegalArgumentException("baseName == null!"); 2443 } 2444 if (keyword == null) { 2445 throw new IllegalArgumentException("keyword == null!"); 2446 } 2447 int numListeners = warningListeners.size(); 2448 for (int i = 0; i < numListeners; i++) { 2449 IIOReadWarningListener listener = 2450 warningListeners.get(i); 2451 Locale locale = warningLocales.get(i); 2452 if (locale == null) { 2453 locale = Locale.getDefault(); 2454 } 2455 2456 /** 2457 * If an applet supplies an implementation of ImageReader and 2458 * resource bundles, then the resource bundle will need to be 2459 * accessed via the applet class loader. So first try the context 2460 * class loader to locate the resource bundle. 2461 * If that throws MissingResourceException, then try the 2462 * system class loader. 2463 */ 2464 ClassLoader loader = 2465 java.security.AccessController.doPrivileged( 2466 new java.security.PrivilegedAction<ClassLoader>() { 2467 public ClassLoader run() { 2468 return Thread.currentThread().getContextClassLoader(); 2469 } 2470 }); 2471 2472 ResourceBundle bundle = null; 2473 try { 2474 bundle = ResourceBundle.getBundle(baseName, locale, loader); 2475 } catch (MissingResourceException mre) { 2476 try { 2477 bundle = ResourceBundle.getBundle(baseName, locale); 2478 } catch (MissingResourceException mre1) { 2479 throw new IllegalArgumentException("Bundle not found!"); 2480 } 2481 } 2482 2483 String warning = null; 2484 try { 2485 warning = bundle.getString(keyword); 2486 } catch (ClassCastException cce) { 2487 throw new IllegalArgumentException("Resource is not a String!"); 2488 } catch (MissingResourceException mre) { 2489 throw new IllegalArgumentException("Resource is missing!"); 2490 } 2491 2492 listener.warningOccurred(this, warning); 2493 } 2494 } 2495 2496 // State management 2497 2498 /** 2499 * Restores the {@code ImageReader} to its initial state. 2500 * 2501 * <p> The default implementation calls 2502 * {@code setInput(null, false)}, 2503 * {@code setLocale(null)}, 2504 * {@code removeAllIIOReadUpdateListeners()}, 2505 * {@code removeAllIIOReadWarningListeners()}, 2506 * {@code removeAllIIOReadProgressListeners()}, and 2507 * {@code clearAbortRequest}. 2508 */ 2509 public void reset() { 2510 setInput(null, false, false); 2511 setLocale(null); 2512 removeAllIIOReadUpdateListeners(); 2513 removeAllIIOReadProgressListeners(); 2514 removeAllIIOReadWarningListeners(); 2515 clearAbortRequest(); 2516 } 2517 2518 /** 2519 * Allows any resources held by this object to be released. The 2520 * result of calling any other method (other than 2521 * {@code finalize}) subsequent to a call to this method 2522 * is undefined. 2523 * 2524 * <p>It is important for applications to call this method when they 2525 * know they will no longer be using this {@code ImageReader}. 2526 * Otherwise, the reader may continue to hold on to resources 2527 * indefinitely. 2528 * 2529 * <p>The default implementation of this method in the superclass does 2530 * nothing. Subclass implementations should ensure that all resources, 2531 * especially native resources, are released. 2532 */ 2533 public void dispose() { 2534 } 2535 2536 // Utility methods 2537 2538 /** 2539 * A utility method that may be used by readers to compute the 2540 * region of the source image that should be read, taking into 2541 * account any source region and subsampling offset settings in 2542 * the supplied {@code ImageReadParam}. The actual 2543 * subsampling factors, destination size, and destination offset 2544 * are <em>not</em> taken into consideration, thus further 2545 * clipping must take place. The {@link #computeRegions computeRegions} 2546 * method performs all necessary clipping. 2547 * 2548 * @param param the {@code ImageReadParam} being used, or 2549 * {@code null}. 2550 * @param srcWidth the width of the source image. 2551 * @param srcHeight the height of the source image. 2552 * 2553 * @return the source region as a {@code Rectangle}. 2554 */ 2555 protected static Rectangle getSourceRegion(ImageReadParam param, 2556 int srcWidth, 2557 int srcHeight) { 2558 Rectangle sourceRegion = new Rectangle(0, 0, srcWidth, srcHeight); 2559 if (param != null) { 2560 Rectangle region = param.getSourceRegion(); 2561 if (region != null) { 2562 sourceRegion = sourceRegion.intersection(region); 2563 } 2564 2565 int subsampleXOffset = param.getSubsamplingXOffset(); 2566 int subsampleYOffset = param.getSubsamplingYOffset(); 2567 sourceRegion.x += subsampleXOffset; 2568 sourceRegion.y += subsampleYOffset; 2569 sourceRegion.width -= subsampleXOffset; 2570 sourceRegion.height -= subsampleYOffset; 2571 } 2572 2573 return sourceRegion; 2574 } 2575 2576 /** 2577 * Computes the source region of interest and the destination 2578 * region of interest, taking the width and height of the source 2579 * image, an optional destination image, and an optional 2580 * {@code ImageReadParam} into account. The source region 2581 * begins with the entire source image. Then that is clipped to 2582 * the source region specified in the {@code ImageReadParam}, 2583 * if one is specified. 2584 * 2585 * <p> If either of the destination offsets are negative, the 2586 * source region is clipped so that its top left will coincide 2587 * with the top left of the destination image, taking subsampling 2588 * into account. Then the result is clipped to the destination 2589 * image on the right and bottom, if one is specified, taking 2590 * subsampling and destination offsets into account. 2591 * 2592 * <p> Similarly, the destination region begins with the source 2593 * image, is translated to the destination offset given in the 2594 * {@code ImageReadParam} if there is one, and finally is 2595 * clipped to the destination image, if there is one. 2596 * 2597 * <p> If either the source or destination regions end up having a 2598 * width or height of 0, an {@code IllegalArgumentException} 2599 * is thrown. 2600 * 2601 * <p> The {@link #getSourceRegion getSourceRegion>} 2602 * method may be used if only source clipping is desired. 2603 * 2604 * @param param an {@code ImageReadParam}, or {@code null}. 2605 * @param srcWidth the width of the source image. 2606 * @param srcHeight the height of the source image. 2607 * @param image a {@code BufferedImage} that will be the 2608 * destination image, or {@code null}. 2609 * @param srcRegion a {@code Rectangle} that will be filled with 2610 * the source region of interest. 2611 * @param destRegion a {@code Rectangle} that will be filled with 2612 * the destination region of interest. 2613 * @exception IllegalArgumentException if {@code srcRegion} 2614 * is {@code null}. 2615 * @exception IllegalArgumentException if {@code dstRegion} 2616 * is {@code null}. 2617 * @exception IllegalArgumentException if the resulting source or 2618 * destination region is empty. 2619 */ 2620 protected static void computeRegions(ImageReadParam param, 2621 int srcWidth, 2622 int srcHeight, 2623 BufferedImage image, 2624 Rectangle srcRegion, 2625 Rectangle destRegion) { 2626 if (srcRegion == null) { 2627 throw new IllegalArgumentException("srcRegion == null!"); 2628 } 2629 if (destRegion == null) { 2630 throw new IllegalArgumentException("destRegion == null!"); 2631 } 2632 2633 // Start with the entire source image 2634 srcRegion.setBounds(0, 0, srcWidth, srcHeight); 2635 2636 // Destination also starts with source image, as that is the 2637 // maximum extent if there is no subsampling 2638 destRegion.setBounds(0, 0, srcWidth, srcHeight); 2639 2640 // Clip that to the param region, if there is one 2641 int periodX = 1; 2642 int periodY = 1; 2643 int gridX = 0; 2644 int gridY = 0; 2645 if (param != null) { 2646 Rectangle paramSrcRegion = param.getSourceRegion(); 2647 if (paramSrcRegion != null) { 2648 srcRegion.setBounds(srcRegion.intersection(paramSrcRegion)); 2649 } 2650 periodX = param.getSourceXSubsampling(); 2651 periodY = param.getSourceYSubsampling(); 2652 gridX = param.getSubsamplingXOffset(); 2653 gridY = param.getSubsamplingYOffset(); 2654 srcRegion.translate(gridX, gridY); 2655 srcRegion.width -= gridX; 2656 srcRegion.height -= gridY; 2657 destRegion.setLocation(param.getDestinationOffset()); 2658 } 2659 2660 // Now clip any negative destination offsets, i.e. clip 2661 // to the top and left of the destination image 2662 if (destRegion.x < 0) { 2663 int delta = -destRegion.x*periodX; 2664 srcRegion.x += delta; 2665 srcRegion.width -= delta; 2666 destRegion.x = 0; 2667 } 2668 if (destRegion.y < 0) { 2669 int delta = -destRegion.y*periodY; 2670 srcRegion.y += delta; 2671 srcRegion.height -= delta; 2672 destRegion.y = 0; 2673 } 2674 2675 // Now clip the destination Region to the subsampled width and height 2676 int subsampledWidth = (srcRegion.width + periodX - 1)/periodX; 2677 int subsampledHeight = (srcRegion.height + periodY - 1)/periodY; 2678 destRegion.width = subsampledWidth; 2679 destRegion.height = subsampledHeight; 2680 2681 // Now clip that to right and bottom of the destination image, 2682 // if there is one, taking subsampling into account 2683 if (image != null) { 2684 Rectangle destImageRect = new Rectangle(0, 0, 2685 image.getWidth(), 2686 image.getHeight()); 2687 destRegion.setBounds(destRegion.intersection(destImageRect)); 2688 if (destRegion.isEmpty()) { 2689 throw new IllegalArgumentException 2690 ("Empty destination region!"); 2691 } 2692 2693 int deltaX = destRegion.x + subsampledWidth - image.getWidth(); 2694 if (deltaX > 0) { 2695 srcRegion.width -= deltaX*periodX; 2696 } 2697 int deltaY = destRegion.y + subsampledHeight - image.getHeight(); 2698 if (deltaY > 0) { 2699 srcRegion.height -= deltaY*periodY; 2700 } 2701 } 2702 if (srcRegion.isEmpty() || destRegion.isEmpty()) { 2703 throw new IllegalArgumentException("Empty region!"); 2704 } 2705 } 2706 2707 /** 2708 * A utility method that may be used by readers to test the 2709 * validity of the source and destination band settings of an 2710 * {@code ImageReadParam}. This method may be called as soon 2711 * as the reader knows both the number of bands of the source 2712 * image as it exists in the input stream, and the number of bands 2713 * of the destination image that being written. 2714 * 2715 * <p> The method retrieves the source and destination band 2716 * setting arrays from param using the {@code getSourceBands} 2717 * and {@code getDestinationBands} methods (or considers them 2718 * to be {@code null} if {@code param} is 2719 * {@code null}). If the source band setting array is 2720 * {@code null}, it is considered to be equal to the array 2721 * {@code { 0, 1, ..., numSrcBands - 1 }}, and similarly for 2722 * the destination band setting array. 2723 * 2724 * <p> The method then tests that both arrays are equal in length, 2725 * and that neither array contains a value larger than the largest 2726 * available band index. 2727 * 2728 * <p> Any failure results in an 2729 * {@code IllegalArgumentException} being thrown; success 2730 * results in the method returning silently. 2731 * 2732 * @param param the {@code ImageReadParam} being used to read 2733 * the image. 2734 * @param numSrcBands the number of bands of the image as it exists 2735 * int the input source. 2736 * @param numDstBands the number of bands in the destination image 2737 * being written. 2738 * 2739 * @exception IllegalArgumentException if {@code param} 2740 * contains an invalid specification of a source and/or 2741 * destination band subset. 2742 */ 2743 protected static void checkReadParamBandSettings(ImageReadParam param, 2744 int numSrcBands, 2745 int numDstBands) { 2746 // A null param is equivalent to srcBands == dstBands == null. 2747 int[] srcBands = null; 2748 int[] dstBands = null; 2749 if (param != null) { 2750 srcBands = param.getSourceBands(); 2751 dstBands = param.getDestinationBands(); 2752 } 2753 2754 int paramSrcBandLength = 2755 (srcBands == null) ? numSrcBands : srcBands.length; 2756 int paramDstBandLength = 2757 (dstBands == null) ? numDstBands : dstBands.length; 2758 2759 if (paramSrcBandLength != paramDstBandLength) { 2760 throw new IllegalArgumentException("ImageReadParam num source & dest bands differ!"); 2761 } 2762 2763 if (srcBands != null) { 2764 for (int i = 0; i < srcBands.length; i++) { 2765 if (srcBands[i] >= numSrcBands) { 2766 throw new IllegalArgumentException("ImageReadParam source bands contains a value >= the number of source bands!"); 2767 } 2768 } 2769 } 2770 2771 if (dstBands != null) { 2772 for (int i = 0; i < dstBands.length; i++) { 2773 if (dstBands[i] >= numDstBands) { 2774 throw new IllegalArgumentException("ImageReadParam dest bands contains a value >= the number of dest bands!"); 2775 } 2776 } 2777 } 2778 } 2779 2780 /** 2781 * Returns the {@code BufferedImage} to which decoded pixel 2782 * data should be written. The image is determined by inspecting 2783 * the supplied {@code ImageReadParam} if it is 2784 * non-{@code null}; if its {@code getDestination} 2785 * method returns a non-{@code null} value, that image is 2786 * simply returned. Otherwise, 2787 * {@code param.getDestinationType} method is called to 2788 * determine if a particular image type has been specified. If 2789 * so, the returned {@code ImageTypeSpecifier} is used after 2790 * checking that it is equal to one of those included in 2791 * {@code imageTypes}. 2792 * 2793 * <p> If {@code param} is {@code null} or the above 2794 * steps have not yielded an image or an 2795 * {@code ImageTypeSpecifier}, the first value obtained from 2796 * the {@code imageTypes} parameter is used. Typically, the 2797 * caller will set {@code imageTypes} to the value of 2798 * {@code getImageTypes(imageIndex)}. 2799 * 2800 * <p> Next, the dimensions of the image are determined by a call 2801 * to {@code computeRegions}. The actual width and height of 2802 * the image being decoded are passed in as the {@code width} 2803 * and {@code height} parameters. 2804 * 2805 * @param param an {@code ImageReadParam} to be used to get 2806 * the destination image or image type, or {@code null}. 2807 * @param imageTypes an {@code Iterator} of 2808 * {@code ImageTypeSpecifier}s indicating the legal image 2809 * types, with the default first. 2810 * @param width the true width of the image or tile being decoded. 2811 * @param height the true width of the image or tile being decoded. 2812 * 2813 * @return the {@code BufferedImage} to which decoded pixel 2814 * data should be written. 2815 * 2816 * @exception IIOException if the {@code ImageTypeSpecifier} 2817 * specified by {@code param} does not match any of the legal 2818 * ones from {@code imageTypes}. 2819 * @exception IllegalArgumentException if {@code imageTypes} 2820 * is {@code null} or empty, or if an object not of type 2821 * {@code ImageTypeSpecifier} is retrieved from it. 2822 * @exception IllegalArgumentException if the resulting image would 2823 * have a width or height less than 1. 2824 * @exception IllegalArgumentException if the product of 2825 * {@code width} and {@code height} is greater than 2826 * {@code Integer.MAX_VALUE}. 2827 */ 2828 protected static BufferedImage 2829 getDestination(ImageReadParam param, 2830 Iterator<ImageTypeSpecifier> imageTypes, 2831 int width, int height) 2832 throws IIOException { 2833 if (imageTypes == null || !imageTypes.hasNext()) { 2834 throw new IllegalArgumentException("imageTypes null or empty!"); 2835 } 2836 if ((long)width*height > Integer.MAX_VALUE) { 2837 throw new IllegalArgumentException 2838 ("width*height > Integer.MAX_VALUE!"); 2839 } 2840 2841 BufferedImage dest = null; 2842 ImageTypeSpecifier imageType = null; 2843 2844 // If param is non-null, use it 2845 if (param != null) { 2846 // Try to get the image itself 2847 dest = param.getDestination(); 2848 if (dest != null) { 2849 return dest; 2850 } 2851 2852 // No image, get the image type 2853 imageType = param.getDestinationType(); 2854 } 2855 2856 // No info from param, use fallback image type 2857 if (imageType == null) { 2858 Object o = imageTypes.next(); 2859 if (!(o instanceof ImageTypeSpecifier)) { 2860 throw new IllegalArgumentException 2861 ("Non-ImageTypeSpecifier retrieved from imageTypes!"); 2862 } 2863 imageType = (ImageTypeSpecifier)o; 2864 } else { 2865 boolean foundIt = false; 2866 while (imageTypes.hasNext()) { 2867 ImageTypeSpecifier type = 2868 imageTypes.next(); 2869 if (type.equals(imageType)) { 2870 foundIt = true; 2871 break; 2872 } 2873 } 2874 2875 if (!foundIt) { 2876 throw new IIOException 2877 ("Destination type from ImageReadParam does not match!"); 2878 } 2879 } 2880 2881 Rectangle srcRegion = new Rectangle(0,0,0,0); 2882 Rectangle destRegion = new Rectangle(0,0,0,0); 2883 computeRegions(param, 2884 width, 2885 height, 2886 null, 2887 srcRegion, 2888 destRegion); 2889 2890 int destWidth = destRegion.x + destRegion.width; 2891 int destHeight = destRegion.y + destRegion.height; 2892 // Create a new image based on the type specifier 2893 return imageType.createBufferedImage(destWidth, destHeight); 2894 } 2895 }