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 */ ImageReader(ImageReaderSpi originatingProvider)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 */ getFormatName()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 */ getOriginatingProvider()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 */ setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata)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 */ setInput(Object input, boolean seekForwardOnly)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 */ setInput(Object input)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 */ getInput()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 */ isSeekForwardOnly()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 */ isIgnoringMetadata()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 */ getMinIndex()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 */ getAvailableLocales()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 */ setLocale(Locale locale)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 */ getLocale()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 */ getNumImages(boolean allowSearch)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 */ getWidth(int imageIndex)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 */ getHeight(int imageIndex)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 */ isRandomAccessEasy(int imageIndex)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 */ getAspectRatio(int imageIndex)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 */ getRawImageType(int imageIndex)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> getImageTypes(int imageIndex)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 */ getDefaultReadParam()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 */ getStreamMetadata()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 */ getStreamMetadata(String formatName, Set<String> nodeNames)787 public IIOMetadata getStreamMetadata(String formatName, 788 Set<String> nodeNames) 789 throws IOException 790 { 791 return getMetadata(formatName, nodeNames, true, 0); 792 } 793 getMetadata(String formatName, Set<String> nodeNames, boolean wantStream, int imageIndex)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 */ getImageMetadata(int imageIndex)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 */ getImageMetadata(int imageIndex, String formatName, Set<String> nodeNames)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 */ read(int imageIndex)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 */ read(int imageIndex, ImageReadParam param)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 */ readAll(int imageIndex, ImageReadParam param)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> readAll(Iterator<? extends ImageReadParam> params)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 */ canReadRaster()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 */ readRaster(int imageIndex, ImageReadParam param)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 */ isImageTiled(int imageIndex)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 */ getTileWidth(int imageIndex)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 */ getTileHeight(int imageIndex)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 */ getTileGridXOffset(int imageIndex)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 */ getTileGridYOffset(int imageIndex)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 */ readTile(int imageIndex, int tileX, int tileY)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 */ readTileRaster(int imageIndex, int tileX, int tileY)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 */ readAsRenderedImage(int imageIndex, ImageReadParam param)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 */ readerSupportsThumbnails()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 */ hasThumbnails(int imageIndex)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 */ getNumThumbnails(int imageIndex)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 */ getThumbnailWidth(int imageIndex, int thumbnailIndex)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 */ getThumbnailHeight(int imageIndex, int thumbnailIndex)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 */ readThumbnail(int imageIndex, int thumbnailIndex)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 */ abort()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 */ abortRequested()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 */ clearAbortRequest()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. addToList(List<T> l, T elt)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. removeFromList(List<T> l, T elt)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 */ addIIOReadWarningListener(IIOReadWarningListener listener)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 */ removeIIOReadWarningListener(IIOReadWarningListener listener)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 */ removeAllIIOReadWarningListeners()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 */ addIIOReadProgressListener(IIOReadProgressListener listener)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 removeIIOReadProgressListener(IIOReadProgressListener listener)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 */ removeAllIIOReadProgressListeners()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 addIIOReadUpdateListener(IIOReadUpdateListener listener)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 */ removeIIOReadUpdateListener(IIOReadUpdateListener listener)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 */ removeAllIIOReadUpdateListeners()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 */ processSequenceStarted(int minIndex)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 */ processSequenceComplete()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 */ processImageStarted(int imageIndex)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 */ processImageProgress(float percentageDone)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 */ processImageComplete()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 */ processThumbnailStarted(int imageIndex, int thumbnailIndex)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 */ processThumbnailProgress(float percentageDone)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 */ processThumbnailComplete()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 */ processReadAborted()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 */ processPassStarted(BufferedImage theImage, int pass, int minPass, int maxPass, int minX, int minY, int periodX, int periodY, int[] bands)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 */ processImageUpdate(BufferedImage theImage, int minX, int minY, int width, int height, int periodX, int periodY, int[] bands)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 */ processPassComplete(BufferedImage theImage)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 */ processThumbnailPassStarted(BufferedImage theThumbnail, int pass, int minPass, int maxPass, int minX, int minY, int periodX, int periodY, int[] bands)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 */ processThumbnailUpdate(BufferedImage theThumbnail, int minX, int minY, int width, int height, int periodX, int periodY, int[] bands)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 */ processThumbnailPassComplete(BufferedImage theThumbnail)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 */ processWarningOccurred(String warning)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 */ processWarningOccurred(String baseName, String keyword)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 */ reset()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 */ dispose()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 */ getSourceRegion(ImageReadParam param, int srcWidth, int srcHeight)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 */ computeRegions(ImageReadParam param, int srcWidth, int srcHeight, BufferedImage image, Rectangle srcRegion, Rectangle destRegion)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 */ checkReadParamBandSettings(ImageReadParam param, int numSrcBands, int numDstBands)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 getDestination(ImageReadParam param, Iterator<ImageTypeSpecifier> imageTypes, int width, int height)2813 getDestination(ImageReadParam param, 2814 Iterator<ImageTypeSpecifier> imageTypes, 2815 int width, int height) 2816 throws IIOException { 2817 if (imageTypes == null || !imageTypes.hasNext()) { 2818 throw new IllegalArgumentException("imageTypes null or empty!"); 2819 } 2820 if ((long)width*height > Integer.MAX_VALUE) { 2821 throw new IllegalArgumentException 2822 ("width*height > Integer.MAX_VALUE!"); 2823 } 2824 2825 BufferedImage dest = null; 2826 ImageTypeSpecifier imageType = null; 2827 2828 // If param is non-null, use it 2829 if (param != null) { 2830 // Try to get the image itself 2831 dest = param.getDestination(); 2832 if (dest != null) { 2833 return dest; 2834 } 2835 2836 // No image, get the image type 2837 imageType = param.getDestinationType(); 2838 } 2839 2840 // No info from param, use fallback image type 2841 if (imageType == null) { 2842 Object o = imageTypes.next(); 2843 if (!(o instanceof ImageTypeSpecifier)) { 2844 throw new IllegalArgumentException 2845 ("Non-ImageTypeSpecifier retrieved from imageTypes!"); 2846 } 2847 imageType = (ImageTypeSpecifier)o; 2848 } else { 2849 boolean foundIt = false; 2850 while (imageTypes.hasNext()) { 2851 ImageTypeSpecifier type = 2852 imageTypes.next(); 2853 if (type.equals(imageType)) { 2854 foundIt = true; 2855 break; 2856 } 2857 } 2858 2859 if (!foundIt) { 2860 throw new IIOException 2861 ("Destination type from ImageReadParam does not match!"); 2862 } 2863 } 2864 2865 Rectangle srcRegion = new Rectangle(0,0,0,0); 2866 Rectangle destRegion = new Rectangle(0,0,0,0); 2867 computeRegions(param, 2868 width, 2869 height, 2870 null, 2871 srcRegion, 2872 destRegion); 2873 2874 int destWidth = destRegion.x + destRegion.width; 2875 int destHeight = destRegion.y + destRegion.height; 2876 // Create a new image based on the type specifier 2877 return imageType.createBufferedImage(destWidth, destHeight); 2878 } 2879 } 2880