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