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