1/* 2 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package javax.imageio; 27 28import java.awt.Dimension; 29import java.awt.Rectangle; 30import java.awt.image.BufferedImage; 31import java.awt.image.RenderedImage; 32import java.awt.image.Raster; 33import java.io.IOException; 34import java.util.ArrayList; 35import java.util.List; 36import java.util.Locale; 37import java.util.MissingResourceException; 38import java.util.ResourceBundle; 39import javax.imageio.event.IIOWriteWarningListener; 40import javax.imageio.event.IIOWriteProgressListener; 41import javax.imageio.metadata.IIOMetadata; 42import javax.imageio.stream.ImageOutputStream; 43import javax.imageio.spi.ImageWriterSpi; 44 45/** 46 * An abstract superclass for encoding and writing images. This class 47 * must be subclassed by classes that write out images in the context 48 * of the Java Image I/O framework. 49 * 50 * <p> {@code ImageWriter} objects are normally instantiated by 51 * the service provider class for the specific format. Service 52 * provider classes are registered with the {@code IIORegistry}, 53 * which uses them for format recognition and presentation of 54 * available format readers and writers. 55 * 56 * @see ImageReader 57 * @see ImageWriteParam 58 * @see javax.imageio.spi.IIORegistry 59 * @see javax.imageio.spi.ImageWriterSpi 60 * 61 */ 62public abstract class ImageWriter implements ImageTranscoder { 63 64 /** 65 * The {@code ImageWriterSpi} that instantiated this object, 66 * or {@code null} if its identity is not known or none 67 * exists. By default it is initialized to {@code null}. 68 */ 69 protected ImageWriterSpi originatingProvider = null; 70 71 /** 72 * The {@code ImageOutputStream} or other {@code Object} 73 * set by {@code setOutput} and retrieved by 74 * {@code getOutput}. By default it is initialized to 75 * {@code null}. 76 */ 77 protected Object output = null; 78 79 /** 80 * An array of {@code Locale}s that may be used to localize 81 * warning messages and compression setting values, or 82 * {@code null} if localization is not supported. By default 83 * it is initialized to {@code null}. 84 */ 85 protected Locale[] availableLocales = null; 86 87 /** 88 * The current {@code Locale} to be used for localization, or 89 * {@code null} if none has been set. By default it is 90 * initialized to {@code null}. 91 */ 92 protected Locale locale = null; 93 94 /** 95 * A {@code List} of currently registered 96 * {@code IIOWriteWarningListener}s, initialized by default to 97 * {@code null}, which is synonymous with an empty 98 * {@code List}. 99 */ 100 protected List<IIOWriteWarningListener> warningListeners = null; 101 102 /** 103 * A {@code List} of {@code Locale}s, one for each 104 * element of {@code warningListeners}, initialized by default 105 * {@code null}, which is synonymous with an empty 106 * {@code List}. 107 */ 108 protected List<Locale> warningLocales = null; 109 110 /** 111 * A {@code List} of currently registered 112 * {@code IIOWriteProgressListener}s, initialized by default 113 * {@code null}, which is synonymous with an empty 114 * {@code List}. 115 */ 116 protected List<IIOWriteProgressListener> progressListeners = null; 117 118 /** 119 * If {@code true}, the current write operation should be 120 * aborted. 121 */ 122 private boolean abortFlag = false; 123 124 /** 125 * Constructs an {@code ImageWriter} and sets its 126 * {@code originatingProvider} instance variable to the 127 * supplied value. 128 * 129 * <p> Subclasses that make use of extensions should provide a 130 * constructor with signature {@code (ImageWriterSpi, Object)} 131 * in order to retrieve the extension object. If 132 * the extension object is unsuitable, an 133 * {@code IllegalArgumentException} should be thrown. 134 * 135 * @param originatingProvider the {@code ImageWriterSpi} that 136 * is constructing this object, or {@code null}. 137 */ 138 protected ImageWriter(ImageWriterSpi originatingProvider) { 139 this.originatingProvider = originatingProvider; 140 } 141 142 /** 143 * Returns the {@code ImageWriterSpi} object that created 144 * this {@code ImageWriter}, or {@code null} if this 145 * object was not created through the {@code IIORegistry}. 146 * 147 * <p> The default implementation returns the value of the 148 * {@code originatingProvider} instance variable. 149 * 150 * @return an {@code ImageWriterSpi}, or {@code null}. 151 * 152 * @see ImageWriterSpi 153 */ 154 public ImageWriterSpi getOriginatingProvider() { 155 return originatingProvider; 156 } 157 158 /** 159 * Sets the destination to the given 160 * {@code ImageOutputStream} or other {@code Object}. 161 * The destination is assumed to be ready to accept data, and will 162 * not be closed at the end of each write. This allows distributed 163 * imaging applications to transmit a series of images over a 164 * single network connection. If {@code output} is 165 * {@code null}, any currently set output will be removed. 166 * 167 * <p> If {@code output} is an 168 * {@code ImageOutputStream}, calls to the 169 * {@code write}, {@code writeToSequence}, and 170 * {@code prepareWriteEmpty}/{@code endWriteEmpty} 171 * methods will preserve the existing contents of the stream. 172 * Other write methods, such as {@code writeInsert}, 173 * {@code replaceStreamMetadata}, 174 * {@code replaceImageMetadata}, {@code replacePixels}, 175 * {@code prepareInsertEmpty}/{@code endInsertEmpty}, 176 * and {@code endWriteSequence}, require the full contents 177 * of the stream to be readable and writable, and may alter any 178 * portion of the stream. 179 * 180 * <p> Use of a general {@code Object} other than an 181 * {@code ImageOutputStream} is intended for writers that 182 * interact directly with an output device or imaging protocol. 183 * The set of legal classes is advertised by the writer's service 184 * provider's {@code getOutputTypes} method; most writers 185 * will return a single-element array containing only 186 * {@code ImageOutputStream.class} to indicate that they 187 * accept only an {@code ImageOutputStream}. 188 * 189 * <p> The default implementation sets the {@code output} 190 * instance variable to the value of {@code output} after 191 * checking {@code output} against the set of classes 192 * advertised by the originating provider, if there is one. 193 * 194 * @param output the {@code ImageOutputStream} or other 195 * {@code Object} to use for future writing. 196 * 197 * @exception IllegalArgumentException if {@code output} is 198 * not an instance of one of the classes returned by the 199 * originating service provider's {@code getOutputTypes} 200 * method. 201 * 202 * @see #getOutput 203 */ 204 public void setOutput(Object output) { 205 if (output != null) { 206 ImageWriterSpi provider = getOriginatingProvider(); 207 if (provider != null) { 208 Class<?>[] classes = provider.getOutputTypes(); 209 boolean found = false; 210 for (int i = 0; i < classes.length; i++) { 211 if (classes[i].isInstance(output)) { 212 found = true; 213 break; 214 } 215 } 216 if (!found) { 217 throw new IllegalArgumentException("Illegal output type!"); 218 } 219 } 220 } 221 222 this.output = output; 223 } 224 225 /** 226 * Returns the {@code ImageOutputStream} or other 227 * {@code Object} set by the most recent call to the 228 * {@code setOutput} method. If no destination has been 229 * set, {@code null} is returned. 230 * 231 * <p> The default implementation returns the value of the 232 * {@code output} instance variable. 233 * 234 * @return the {@code Object} that was specified using 235 * {@code setOutput}, or {@code null}. 236 * 237 * @see #setOutput 238 */ 239 public Object getOutput() { 240 return output; 241 } 242 243 // Localization 244 245 /** 246 * Returns an array of {@code Locale}s that may be used to 247 * localize warning listeners and compression settings. A return 248 * value of {@code null} indicates that localization is not 249 * supported. 250 * 251 * <p> The default implementation returns a clone of the 252 * {@code availableLocales} instance variable if it is 253 * non-{@code null}, or else returns {@code null}. 254 * 255 * @return an array of {@code Locale}s that may be used as 256 * arguments to {@code setLocale}, or {@code null}. 257 */ 258 public Locale[] getAvailableLocales() { 259 return (availableLocales == null) ? 260 null : availableLocales.clone(); 261 } 262 263 /** 264 * Sets the current {@code Locale} of this 265 * {@code ImageWriter} to the given value. A value of 266 * {@code null} removes any previous setting, and indicates 267 * that the writer should localize as it sees fit. 268 * 269 * <p> The default implementation checks {@code locale} 270 * against the values returned by 271 * {@code getAvailableLocales}, and sets the 272 * {@code locale} instance variable if it is found. If 273 * {@code locale} is {@code null}, the instance variable 274 * is set to {@code null} without any checking. 275 * 276 * @param locale the desired {@code Locale}, or 277 * {@code null}. 278 * 279 * @exception IllegalArgumentException if {@code locale} is 280 * non-{@code null} but is not one of the values returned by 281 * {@code getAvailableLocales}. 282 * 283 * @see #getLocale 284 */ 285 public void setLocale(Locale locale) { 286 if (locale != null) { 287 Locale[] locales = getAvailableLocales(); 288 boolean found = false; 289 if (locales != null) { 290 for (int i = 0; i < locales.length; i++) { 291 if (locale.equals(locales[i])) { 292 found = true; 293 break; 294 } 295 } 296 } 297 if (!found) { 298 throw new IllegalArgumentException("Invalid locale!"); 299 } 300 } 301 this.locale = locale; 302 } 303 304 /** 305 * Returns the currently set {@code Locale}, or 306 * {@code null} if none has been set. 307 * 308 * <p> The default implementation returns the value of the 309 * {@code locale} instance variable. 310 * 311 * @return the current {@code Locale}, or {@code null}. 312 * 313 * @see #setLocale 314 */ 315 public Locale getLocale() { 316 return locale; 317 } 318 319 // Write params 320 321 /** 322 * Returns a new {@code ImageWriteParam} object of the 323 * appropriate type for this file format containing default 324 * values, that is, those values that would be used 325 * if no {@code ImageWriteParam} object were specified. This 326 * is useful as a starting point for tweaking just a few parameters 327 * and otherwise leaving the default settings alone. 328 * 329 * <p> The default implementation constructs and returns a new 330 * {@code ImageWriteParam} object that does not allow tiling, 331 * progressive encoding, or compression, and that will be 332 * localized for the current {@code Locale} (<i>i.e.</i>, 333 * what you would get by calling 334 * {@code new ImageWriteParam(getLocale())}. 335 * 336 * <p> Individual plug-ins may return an instance of 337 * {@code ImageWriteParam} with additional optional features 338 * enabled, or they may return an instance of a plug-in specific 339 * subclass of {@code ImageWriteParam}. 340 * 341 * @return a new {@code ImageWriteParam} object containing 342 * default values. 343 */ 344 public ImageWriteParam getDefaultWriteParam() { 345 return new ImageWriteParam(getLocale()); 346 } 347 348 // Metadata 349 350 /** 351 * Returns an {@code IIOMetadata} object containing default 352 * values for encoding a stream of images. The contents of the 353 * object may be manipulated using either the XML tree structure 354 * returned by the {@code IIOMetadata.getAsTree} method, an 355 * {@code IIOMetadataController} object, or via plug-in 356 * specific interfaces, and the resulting data supplied to one of 357 * the {@code write} methods that take a stream metadata 358 * parameter. 359 * 360 * <p> An optional {@code ImageWriteParam} may be supplied 361 * for cases where it may affect the structure of the stream 362 * metadata. 363 * 364 * <p> If the supplied {@code ImageWriteParam} contains 365 * optional setting values not supported by this writer (<i>e.g.</i> 366 * progressive encoding or any format-specific settings), they 367 * will be ignored. 368 * 369 * <p> Writers that do not make use of stream metadata 370 * (<i>e.g.</i>, writers for single-image formats) should return 371 * {@code null}. 372 * 373 * @param param an {@code ImageWriteParam} that will be used to 374 * encode the image, or {@code null}. 375 * 376 * @return an {@code IIOMetadata} object. 377 */ 378 public abstract IIOMetadata 379 getDefaultStreamMetadata(ImageWriteParam param); 380 381 /** 382 * Returns an {@code IIOMetadata} object containing default 383 * values for encoding an image of the given type. The contents 384 * of the object may be manipulated using either the XML tree 385 * structure returned by the {@code IIOMetadata.getAsTree} 386 * method, an {@code IIOMetadataController} object, or via 387 * plug-in specific interfaces, and the resulting data supplied to 388 * one of the {@code write} methods that take a stream 389 * metadata parameter. 390 * 391 * <p> An optional {@code ImageWriteParam} may be supplied 392 * for cases where it may affect the structure of the image 393 * metadata. 394 * 395 * <p> If the supplied {@code ImageWriteParam} contains 396 * optional setting values not supported by this writer (<i>e.g.</i> 397 * progressive encoding or any format-specific settings), they 398 * will be ignored. 399 * 400 * @param imageType an {@code ImageTypeSpecifier} indicating the 401 * format of the image to be written later. 402 * @param param an {@code ImageWriteParam} that will be used to 403 * encode the image, or {@code null}. 404 * 405 * @return an {@code IIOMetadata} object. 406 */ 407 public abstract IIOMetadata 408 getDefaultImageMetadata(ImageTypeSpecifier imageType, 409 ImageWriteParam param); 410 411 // comment inherited 412 public abstract IIOMetadata convertStreamMetadata(IIOMetadata inData, 413 ImageWriteParam param); 414 415 // comment inherited 416 public abstract IIOMetadata 417 convertImageMetadata(IIOMetadata inData, 418 ImageTypeSpecifier imageType, 419 ImageWriteParam param); 420 421 // Thumbnails 422 423 /** 424 * Returns the number of thumbnails supported by the format being 425 * written, given the image type and any additional write 426 * parameters and metadata objects that will be used during 427 * encoding. A return value of {@code -1} indicates that 428 * insufficient information is available. 429 * 430 * <p> An {@code ImageWriteParam} may optionally be supplied 431 * for cases where it may affect thumbnail handling. 432 * 433 * <p> If the supplied {@code ImageWriteParam} contains 434 * optional setting values not supported by this writer (<i>e.g.</i> 435 * progressive encoding or any format-specific settings), they 436 * will be ignored. 437 * 438 * <p> The default implementation returns 0. 439 * 440 * @param imageType an {@code ImageTypeSpecifier} indicating 441 * the type of image to be written, or {@code null}. 442 * @param param the {@code ImageWriteParam} that will be used for 443 * writing, or {@code null}. 444 * @param streamMetadata an {@code IIOMetadata} object that will 445 * be used for writing, or {@code null}. 446 * @param imageMetadata an {@code IIOMetadata} object that will 447 * be used for writing, or {@code null}. 448 * 449 * @return the number of thumbnails that may be written given the 450 * supplied parameters, or {@code -1} if insufficient 451 * information is available. 452 */ 453 public int getNumThumbnailsSupported(ImageTypeSpecifier imageType, 454 ImageWriteParam param, 455 IIOMetadata streamMetadata, 456 IIOMetadata imageMetadata) { 457 return 0; 458 } 459 460 /** 461 * Returns an array of {@code Dimension}s indicating the 462 * legal size ranges for thumbnail images as they will be encoded 463 * in the output file or stream. This information is merely 464 * advisory; the writer will resize any supplied thumbnails as 465 * necessary. 466 * 467 * <p> The information is returned as a set of pairs; the first 468 * element of a pair contains an (inclusive) minimum width and 469 * height, and the second element contains an (inclusive) maximum 470 * width and height. Together, each pair defines a valid range of 471 * sizes. To specify a fixed size, the same width and height will 472 * appear for both elements. A return value of {@code null} 473 * indicates that the size is arbitrary or unknown. 474 * 475 * <p> An {@code ImageWriteParam} may optionally be supplied 476 * for cases where it may affect thumbnail handling. 477 * 478 * <p> If the supplied {@code ImageWriteParam} contains 479 * optional setting values not supported by this writer (<i>e.g.</i> 480 * progressive encoding or any format-specific settings), they 481 * will be ignored. 482 * 483 * <p> The default implementation returns {@code null}. 484 * 485 * @param imageType an {@code ImageTypeSpecifier} indicating the 486 * type of image to be written, or {@code null}. 487 * @param param the {@code ImageWriteParam} that will be used for 488 * writing, or {@code null}. 489 * @param streamMetadata an {@code IIOMetadata} object that will 490 * be used for writing, or {@code null}. 491 * @param imageMetadata an {@code IIOMetadata} object that will 492 * be used for writing, or {@code null}. 493 * 494 * @return an array of {@code Dimension}s with an even length 495 * of at least two, or {@code null}. 496 */ 497 public Dimension[] getPreferredThumbnailSizes(ImageTypeSpecifier imageType, 498 ImageWriteParam param, 499 IIOMetadata streamMetadata, 500 IIOMetadata imageMetadata) { 501 return null; 502 } 503 504 /** 505 * Returns {@code true} if the methods that take an 506 * {@code IIOImage} parameter are capable of dealing with a 507 * {@code Raster} (as opposed to {@code RenderedImage}) 508 * source image. If this method returns {@code false}, then 509 * those methods will throw an 510 * {@code UnsupportedOperationException} if supplied with an 511 * {@code IIOImage} containing a {@code Raster}. 512 * 513 * <p> The default implementation returns {@code false}. 514 * 515 * @return {@code true} if {@code Raster} sources are 516 * supported. 517 */ 518 public boolean canWriteRasters() { 519 return false; 520 } 521 522 /** 523 * Appends a complete image stream containing a single image and 524 * associated stream and image metadata and thumbnails to the 525 * output. Any necessary header information is included. If the 526 * output is an {@code ImageOutputStream}, its existing 527 * contents prior to the current seek position are not affected, 528 * and need not be readable or writable. 529 * 530 * <p> The output must have been set beforehand using the 531 * {@code setOutput} method. 532 * 533 * <p> Stream metadata may optionally be supplied; if it is 534 * {@code null}, default stream metadata will be used. 535 * 536 * <p> If {@code canWriteRasters} returns {@code true}, 537 * the {@code IIOImage} may contain a {@code Raster} 538 * source. Otherwise, it must contain a 539 * {@code RenderedImage} source. 540 * 541 * <p> The supplied thumbnails will be resized if needed, and any 542 * thumbnails in excess of the supported number will be ignored. 543 * If the format requires additional thumbnails that are not 544 * provided, the writer should generate them internally. 545 * 546 * <p> An {@code ImageWriteParam} may 547 * optionally be supplied to control the writing process. If 548 * {@code param} is {@code null}, a default write param 549 * will be used. 550 * 551 * <p> If the supplied {@code ImageWriteParam} contains 552 * optional setting values not supported by this writer (<i>e.g.</i> 553 * progressive encoding or any format-specific settings), they 554 * will be ignored. 555 * 556 * @param streamMetadata an {@code IIOMetadata} object representing 557 * stream metadata, or {@code null} to use default values. 558 * @param image an {@code IIOImage} object containing an 559 * image, thumbnails, and metadata to be written. 560 * @param param an {@code ImageWriteParam}, or 561 * {@code null} to use a default 562 * {@code ImageWriteParam}. 563 * 564 * @exception IllegalStateException if the output has not 565 * been set. 566 * @exception UnsupportedOperationException if {@code image} 567 * contains a {@code Raster} and {@code canWriteRasters} 568 * returns {@code false}. 569 * @exception IllegalArgumentException if {@code image} is 570 * {@code null}. 571 * @exception IOException if an error occurs during writing. 572 */ 573 public abstract void write(IIOMetadata streamMetadata, 574 IIOImage image, 575 ImageWriteParam param) throws IOException; 576 577 /** 578 * Appends a complete image stream containing a single image with 579 * default metadata and thumbnails to the output. This method is 580 * a shorthand for {@code write(null, image, null)}. 581 * 582 * @param image an {@code IIOImage} object containing an 583 * image, thumbnails, and metadata to be written. 584 * 585 * @exception IllegalStateException if the output has not 586 * been set. 587 * @exception IllegalArgumentException if {@code image} is 588 * {@code null}. 589 * @exception UnsupportedOperationException if {@code image} 590 * contains a {@code Raster} and {@code canWriteRasters} 591 * returns {@code false}. 592 * @exception IOException if an error occurs during writing. 593 */ 594 public void write(IIOImage image) throws IOException { 595 write(null, image, null); 596 } 597 598 /** 599 * Appends a complete image stream consisting of a single image 600 * with default metadata and thumbnails to the output. This 601 * method is a shorthand for 602 * {@code write(null, new IIOImage(image, null, null), null)}. 603 * 604 * @param image a {@code RenderedImage} to be written. 605 * 606 * @exception IllegalStateException if the output has not 607 * been set. 608 * @exception IllegalArgumentException if {@code image} is 609 * {@code null}. 610 * @exception IOException if an error occurs during writing. 611 */ 612 public void write(RenderedImage image) throws IOException { 613 write(null, new IIOImage(image, null, null), null); 614 } 615 616 // Check that the output has been set, then throw an 617 // UnsupportedOperationException. 618 private void unsupported() { 619 if (getOutput() == null) { 620 throw new IllegalStateException("getOutput() == null!"); 621 } 622 throw new UnsupportedOperationException("Unsupported write variant!"); 623 } 624 625 // Sequence writes 626 627 /** 628 * Returns {@code true} if the writer is able to append an 629 * image to an image stream that already contains header 630 * information and possibly prior images. 631 * 632 * <p> If {@code canWriteSequence} returns {@code false}, 633 * {@code writeToSequence} and {@code endWriteSequence} 634 * will throw an {@code UnsupportedOperationException}. 635 * 636 * <p> The default implementation returns {@code false}. 637 * 638 * @return {@code true} if images may be appended sequentially. 639 */ 640 public boolean canWriteSequence() { 641 return false; 642 } 643 644 /** 645 * Prepares a stream to accept a series of subsequent 646 * {@code writeToSequence} calls, using the provided stream 647 * metadata object. The metadata will be written to the stream if 648 * it should precede the image data. If the argument is {@code null}, 649 * default stream metadata is used. 650 * 651 * <p> If the output is an {@code ImageOutputStream}, the existing 652 * contents of the output prior to the current seek position are 653 * flushed, and need not be readable or writable. If the format 654 * requires that {@code endWriteSequence} be able to rewind to 655 * patch up the header information, such as for a sequence of images 656 * in a single TIFF file, then the metadata written by this method 657 * must remain in a writable portion of the stream. Other formats 658 * may flush the stream after this method and after each image. 659 * 660 * <p> If {@code canWriteSequence} returns {@code false}, 661 * this method will throw an 662 * {@code UnsupportedOperationException}. 663 * 664 * <p> The output must have been set beforehand using either 665 * the {@code setOutput} method. 666 * 667 * <p> The default implementation throws an 668 * {@code IllegalStateException} if the output is 669 * {@code null}, and otherwise throws an 670 * {@code UnsupportedOperationException}. 671 * 672 * @param streamMetadata A stream metadata object, or {@code null}. 673 * 674 * @exception IllegalStateException if the output has not 675 * been set. 676 * @exception UnsupportedOperationException if 677 * {@code canWriteSequence} returns {@code false}. 678 * @exception IOException if an error occurs writing the stream 679 * metadata. 680 */ 681 public void prepareWriteSequence(IIOMetadata streamMetadata) 682 throws IOException { 683 unsupported(); 684 } 685 686 /** 687 * Appends a single image and possibly associated metadata and 688 * thumbnails, to the output. If the output is an 689 * {@code ImageOutputStream}, the existing contents of the 690 * output prior to the current seek position may be flushed, and 691 * need not be readable or writable, unless the plug-in needs to 692 * be able to patch up the header information when 693 * {@code endWriteSequence} is called (<i>e.g.</i> TIFF). 694 * 695 * <p> If {@code canWriteSequence} returns {@code false}, 696 * this method will throw an 697 * {@code UnsupportedOperationException}. 698 * 699 * <p> The output must have been set beforehand using 700 * the {@code setOutput} method. 701 * 702 * <p> {@code prepareWriteSequence} must have been called 703 * beforehand, or an {@code IllegalStateException} is thrown. 704 * 705 * <p> If {@code canWriteRasters} returns {@code true}, 706 * the {@code IIOImage} may contain a {@code Raster} 707 * source. Otherwise, it must contain a 708 * {@code RenderedImage} source. 709 * 710 * <p> The supplied thumbnails will be resized if needed, and any 711 * thumbnails in excess of the supported number will be ignored. 712 * If the format requires additional thumbnails that are not 713 * provided, the writer will generate them internally. 714 * 715 * <p> An {@code ImageWriteParam} may optionally be supplied 716 * to control the writing process. If {@code param} is 717 * {@code null}, a default write param will be used. 718 * 719 * <p> If the supplied {@code ImageWriteParam} contains 720 * optional setting values not supported by this writer (<i>e.g.</i> 721 * progressive encoding or any format-specific settings), they 722 * will be ignored. 723 * 724 * <p> The default implementation throws an 725 * {@code IllegalStateException} if the output is 726 * {@code null}, and otherwise throws an 727 * {@code UnsupportedOperationException}. 728 * 729 * @param image an {@code IIOImage} object containing an 730 * image, thumbnails, and metadata to be written. 731 * @param param an {@code ImageWriteParam}, or 732 * {@code null} to use a default 733 * {@code ImageWriteParam}. 734 * 735 * @exception IllegalStateException if the output has not 736 * been set, or {@code prepareWriteSequence} has not been called. 737 * @exception UnsupportedOperationException if 738 * {@code canWriteSequence} returns {@code false}. 739 * @exception IllegalArgumentException if {@code image} is 740 * {@code null}. 741 * @exception UnsupportedOperationException if {@code image} 742 * contains a {@code Raster} and {@code canWriteRasters} 743 * returns {@code false}. 744 * @exception IOException if an error occurs during writing. 745 */ 746 public void writeToSequence(IIOImage image, ImageWriteParam param) 747 throws IOException { 748 unsupported(); 749 } 750 751 /** 752 * Completes the writing of a sequence of images begun with 753 * {@code prepareWriteSequence}. Any stream metadata that 754 * should come at the end of the sequence of images is written out, 755 * and any header information at the beginning of the sequence is 756 * patched up if necessary. If the output is an 757 * {@code ImageOutputStream}, data through the stream metadata 758 * at the end of the sequence are flushed and need not be readable 759 * or writable. 760 * 761 * <p> If {@code canWriteSequence} returns {@code false}, 762 * this method will throw an 763 * {@code UnsupportedOperationException}. 764 * 765 * <p> The default implementation throws an 766 * {@code IllegalStateException} if the output is 767 * {@code null}, and otherwise throws an 768 * {@code UnsupportedOperationException}. 769 * 770 * @exception IllegalStateException if the output has not 771 * been set, or {@code prepareWriteSequence} has not been called. 772 * @exception UnsupportedOperationException if 773 * {@code canWriteSequence} returns {@code false}. 774 * @exception IOException if an error occurs during writing. 775 */ 776 public void endWriteSequence() throws IOException { 777 unsupported(); 778 } 779 780 // Metadata replacement 781 782 /** 783 * Returns {@code true} if it is possible to replace the 784 * stream metadata already present in the output. 785 * 786 * <p> The default implementation throws an 787 * {@code IllegalStateException} if the output is 788 * {@code null}, and otherwise returns {@code false}. 789 * 790 * @return {@code true} if replacement of stream metadata is 791 * allowed. 792 * 793 * @exception IllegalStateException if the output has not 794 * been set. 795 * @exception IOException if an I/O error occurs during the query. 796 */ 797 public boolean canReplaceStreamMetadata() throws IOException { 798 if (getOutput() == null) { 799 throw new IllegalStateException("getOutput() == null!"); 800 } 801 return false; 802 } 803 804 /** 805 * Replaces the stream metadata in the output with new 806 * information. If the output is an 807 * {@code ImageOutputStream}, the prior contents of the 808 * stream are examined and possibly edited to make room for the 809 * new data. All of the prior contents of the output must be 810 * available for reading and writing. 811 * 812 * <p> If {@code canReplaceStreamMetadata} returns 813 * {@code false}, an 814 * {@code UnsupportedOperationException} will be thrown. 815 * 816 * <p> The default implementation throws an 817 * {@code IllegalStateException} if the output is 818 * {@code null}, and otherwise throws an 819 * {@code UnsupportedOperationException}. 820 * 821 * @param streamMetadata an {@code IIOMetadata} object representing 822 * stream metadata, or {@code null} to use default values. 823 * 824 * @exception IllegalStateException if the output has not 825 * been set. 826 * @exception UnsupportedOperationException if the 827 * {@code canReplaceStreamMetadata} returns 828 * {@code false}. modes do not include 829 * @exception IOException if an error occurs during writing. 830 */ 831 public void replaceStreamMetadata(IIOMetadata streamMetadata) 832 throws IOException { 833 unsupported(); 834 } 835 836 /** 837 * Returns {@code true} if it is possible to replace the 838 * image metadata associated with an existing image with index 839 * {@code imageIndex}. If this method returns 840 * {@code false}, a call to 841 * {@code replaceImageMetadata(imageIndex)} will throw an 842 * {@code UnsupportedOperationException}. 843 * 844 * <p> A writer that does not support any image metadata 845 * replacement may return {@code false} without performing 846 * bounds checking on the index. 847 * 848 * <p> The default implementation throws an 849 * {@code IllegalStateException} if the output is 850 * {@code null}, and otherwise returns {@code false} 851 * without checking the value of {@code imageIndex}. 852 * 853 * @param imageIndex the index of the image whose metadata is to 854 * be replaced. 855 * 856 * @return {@code true} if the image metadata of the given 857 * image can be replaced. 858 * 859 * @exception IllegalStateException if the output has not 860 * been set. 861 * @exception IndexOutOfBoundsException if the writer supports 862 * image metadata replacement in general, but 863 * {@code imageIndex} is less than 0 or greater than the 864 * largest available index. 865 * @exception IOException if an I/O error occurs during the query. 866 */ 867 public boolean canReplaceImageMetadata(int imageIndex) 868 throws IOException { 869 if (getOutput() == null) { 870 throw new IllegalStateException("getOutput() == null!"); 871 } 872 return false; 873 } 874 875 /** 876 * Replaces the image metadata associated with an existing image. 877 * 878 * <p> If {@code canReplaceImageMetadata(imageIndex)} returns 879 * {@code false}, an 880 * {@code UnsupportedOperationException} will be thrown. 881 * 882 * <p> The default implementation throws an 883 * {@code IllegalStateException} if the output is 884 * {@code null}, and otherwise throws an 885 * {@code UnsupportedOperationException}. 886 * 887 * @param imageIndex the index of the image whose metadata is to 888 * be replaced. 889 * @param imageMetadata an {@code IIOMetadata} object 890 * representing image metadata, or {@code null}. 891 * 892 * @exception IllegalStateException if the output has not been 893 * set. 894 * @exception UnsupportedOperationException if 895 * {@code canReplaceImageMetadata} returns 896 * {@code false}. 897 * @exception IndexOutOfBoundsException if {@code imageIndex} 898 * is less than 0 or greater than the largest available index. 899 * @exception IOException if an error occurs during writing. 900 */ 901 public void replaceImageMetadata(int imageIndex, 902 IIOMetadata imageMetadata) 903 throws IOException { 904 unsupported(); 905 } 906 907 // Image insertion 908 909 /** 910 * Returns {@code true} if the writer supports the insertion 911 * of a new image at the given index. Existing images with 912 * indices greater than or equal to the insertion index will have 913 * their indices increased by 1. A value for 914 * {@code imageIndex} of {@code -1} may be used to 915 * signify an index one larger than the current largest index. 916 * 917 * <p> A writer that does not support any image insertion may 918 * return {@code false} without performing bounds checking on 919 * the index. 920 * 921 * <p> The default implementation throws an 922 * {@code IllegalStateException} if the output is 923 * {@code null}, and otherwise returns {@code false} 924 * without checking the value of {@code imageIndex}. 925 * 926 * @param imageIndex the index at which the image is to be 927 * inserted. 928 * 929 * @return {@code true} if an image may be inserted at the 930 * given index. 931 * 932 * @exception IllegalStateException if the output has not 933 * been set. 934 * @exception IndexOutOfBoundsException if the writer supports 935 * image insertion in general, but {@code imageIndex} is less 936 * than -1 or greater than the largest available index. 937 * @exception IOException if an I/O error occurs during the query. 938 */ 939 public boolean canInsertImage(int imageIndex) throws IOException { 940 if (getOutput() == null) { 941 throw new IllegalStateException("getOutput() == null!"); 942 } 943 return false; 944 } 945 946 /** 947 * Inserts a new image into an existing image stream. Existing 948 * images with an index greater than {@code imageIndex} are 949 * preserved, and their indices are each increased by 1. A value 950 * for {@code imageIndex} of -1 may be used to signify an 951 * index one larger than the previous largest index; that is, it 952 * will cause the image to be logically appended to the end of the 953 * sequence. If the output is an {@code ImageOutputStream}, 954 * the entirety of the stream must be both readable and writeable. 955 * 956 * <p> If {@code canInsertImage(imageIndex)} returns 957 * {@code false}, an 958 * {@code UnsupportedOperationException} will be thrown. 959 * 960 * <p> An {@code ImageWriteParam} may optionally be supplied 961 * to control the writing process. If {@code param} is 962 * {@code null}, a default write param will be used. 963 * 964 * <p> If the supplied {@code ImageWriteParam} contains 965 * optional setting values not supported by this writer (<i>e.g.</i> 966 * progressive encoding or any format-specific settings), they 967 * will be ignored. 968 * 969 * <p> The default implementation throws an 970 * {@code IllegalStateException} if the output is 971 * {@code null}, and otherwise throws an 972 * {@code UnsupportedOperationException}. 973 * 974 * @param imageIndex the index at which to write the image. 975 * @param image an {@code IIOImage} object containing an 976 * image, thumbnails, and metadata to be written. 977 * @param param an {@code ImageWriteParam}, or 978 * {@code null} to use a default 979 * {@code ImageWriteParam}. 980 * 981 * @exception IllegalStateException if the output has not 982 * been set. 983 * @exception UnsupportedOperationException if 984 * {@code canInsertImage(imageIndex)} returns {@code false}. 985 * @exception IllegalArgumentException if {@code image} is 986 * {@code null}. 987 * @exception IndexOutOfBoundsException if {@code imageIndex} 988 * is less than -1 or greater than the largest available index. 989 * @exception UnsupportedOperationException if {@code image} 990 * contains a {@code Raster} and {@code canWriteRasters} 991 * returns {@code false}. 992 * @exception IOException if an error occurs during writing. 993 */ 994 public void writeInsert(int imageIndex, 995 IIOImage image, 996 ImageWriteParam param) throws IOException { 997 unsupported(); 998 } 999 1000 // Image removal 1001 1002 /** 1003 * Returns {@code true} if the writer supports the removal 1004 * of an existing image at the given index. Existing images with 1005 * indices greater than the insertion index will have 1006 * their indices decreased by 1. 1007 * 1008 * <p> A writer that does not support any image removal may 1009 * return {@code false} without performing bounds checking on 1010 * the index. 1011 * 1012 * <p> The default implementation throws an 1013 * {@code IllegalStateException} if the output is 1014 * {@code null}, and otherwise returns {@code false} 1015 * without checking the value of {@code imageIndex}. 1016 * 1017 * @param imageIndex the index of the image to be removed. 1018 * 1019 * @return {@code true} if it is possible to remove the given 1020 * image. 1021 * 1022 * @exception IllegalStateException if the output has not 1023 * been set. 1024 * @exception IndexOutOfBoundsException if the writer supports 1025 * image removal in general, but {@code imageIndex} is less 1026 * than 0 or greater than the largest available index. 1027 * @exception IOException if an I/O error occurs during the 1028 * query. 1029 */ 1030 public boolean canRemoveImage(int imageIndex) throws IOException { 1031 if (getOutput() == null) { 1032 throw new IllegalStateException("getOutput() == null!"); 1033 } 1034 return false; 1035 } 1036 1037 /** 1038 * Removes an image from the stream. 1039 * 1040 * <p> If {@code canRemoveImage(imageIndex)} returns false, 1041 * an {@code UnsupportedOperationException} will be thrown. 1042 * 1043 * <p> The removal may or may not cause a reduction in the actual 1044 * file size. 1045 * 1046 * <p> The default implementation throws an 1047 * {@code IllegalStateException} if the output is 1048 * {@code null}, and otherwise throws an 1049 * {@code UnsupportedOperationException}. 1050 * 1051 * @param imageIndex the index of the image to be removed. 1052 * 1053 * @exception IllegalStateException if the output has not 1054 * been set. 1055 * @exception UnsupportedOperationException if 1056 * {@code canRemoveImage(imageIndex)} returns {@code false}. 1057 * @exception IndexOutOfBoundsException if {@code imageIndex} 1058 * is less than 0 or greater than the largest available index. 1059 * @exception IOException if an I/O error occurs during the 1060 * removal. 1061 */ 1062 public void removeImage(int imageIndex) throws IOException { 1063 unsupported(); 1064 } 1065 1066 // Empty images 1067 1068 /** 1069 * Returns {@code true} if the writer supports the writing of 1070 * a complete image stream consisting of a single image with 1071 * undefined pixel values and associated metadata and thumbnails 1072 * to the output. The pixel values may be defined by future 1073 * calls to the {@code replacePixels} methods. If the output 1074 * is an {@code ImageOutputStream}, its existing contents 1075 * prior to the current seek position are not affected, and need 1076 * not be readable or writable. 1077 * 1078 * <p> The default implementation throws an 1079 * {@code IllegalStateException} if the output is 1080 * {@code null}, and otherwise returns {@code false}. 1081 * 1082 * @return {@code true} if the writing of complete image 1083 * stream with contents to be defined later is supported. 1084 * 1085 * @exception IllegalStateException if the output has not been 1086 * set. 1087 * @exception IOException if an I/O error occurs during the 1088 * query. 1089 */ 1090 public boolean canWriteEmpty() throws IOException { 1091 if (getOutput() == null) { 1092 throw new IllegalStateException("getOutput() == null!"); 1093 } 1094 return false; 1095 } 1096 1097 /** 1098 * Begins the writing of a complete image stream, consisting of a 1099 * single image with undefined pixel values and associated 1100 * metadata and thumbnails, to the output. The pixel values will 1101 * be defined by future calls to the {@code replacePixels} 1102 * methods. If the output is an {@code ImageOutputStream}, 1103 * its existing contents prior to the current seek position are 1104 * not affected, and need not be readable or writable. 1105 * 1106 * <p> The writing is not complete until a call to 1107 * {@code endWriteEmpty} occurs. Calls to 1108 * {@code prepareReplacePixels}, {@code replacePixels}, 1109 * and {@code endReplacePixels} may occur between calls to 1110 * {@code prepareWriteEmpty} and {@code endWriteEmpty}. 1111 * However, calls to {@code prepareWriteEmpty} cannot be 1112 * nested, and calls to {@code prepareWriteEmpty} and 1113 * {@code prepareInsertEmpty} may not be interspersed. 1114 * 1115 * <p> If {@code canWriteEmpty} returns {@code false}, 1116 * an {@code UnsupportedOperationException} will be thrown. 1117 * 1118 * <p> An {@code ImageWriteParam} may optionally be supplied 1119 * to control the writing process. If {@code param} is 1120 * {@code null}, a default write param will be used. 1121 * 1122 * <p> If the supplied {@code ImageWriteParam} contains 1123 * optional setting values not supported by this writer (<i>e.g.</i> 1124 * progressive encoding or any format-specific settings), they 1125 * will be ignored. 1126 * 1127 * <p> The default implementation throws an 1128 * {@code IllegalStateException} if the output is 1129 * {@code null}, and otherwise throws an 1130 * {@code UnsupportedOperationException}. 1131 * 1132 * @param streamMetadata an {@code IIOMetadata} object representing 1133 * stream metadata, or {@code null} to use default values. 1134 * @param imageType an {@code ImageTypeSpecifier} describing 1135 * the layout of the image. 1136 * @param width the width of the image. 1137 * @param height the height of the image. 1138 * @param imageMetadata an {@code IIOMetadata} object 1139 * representing image metadata, or {@code null}. 1140 * @param thumbnails a {@code List} of 1141 * {@code BufferedImage} thumbnails for this image, or 1142 * {@code null}. 1143 * @param param an {@code ImageWriteParam}, or 1144 * {@code null} to use a default 1145 * {@code ImageWriteParam}. 1146 * 1147 * @exception IllegalStateException if the output has not 1148 * been set. 1149 * @exception UnsupportedOperationException if 1150 * {@code canWriteEmpty} returns {@code false}. 1151 * @exception IllegalStateException if a previous call to 1152 * {@code prepareWriteEmpty} has been made without a 1153 * corresponding call to {@code endWriteEmpty}. 1154 * @exception IllegalStateException if a previous call to 1155 * {@code prepareInsertEmpty} has been made without a 1156 * corresponding call to {@code endInsertEmpty}. 1157 * @exception IllegalArgumentException if {@code imageType} 1158 * is {@code null} or {@code thumbnails} contains 1159 * {@code null} references or objects other than 1160 * {@code BufferedImage}s. 1161 * @exception IllegalArgumentException if width or height are less 1162 * than 1. 1163 * @exception IOException if an I/O error occurs during writing. 1164 */ 1165 public void prepareWriteEmpty(IIOMetadata streamMetadata, 1166 ImageTypeSpecifier imageType, 1167 int width, int height, 1168 IIOMetadata imageMetadata, 1169 List<? extends BufferedImage> thumbnails, 1170 ImageWriteParam param) throws IOException { 1171 unsupported(); 1172 } 1173 1174 /** 1175 * Completes the writing of a new image that was begun with a 1176 * prior call to {@code prepareWriteEmpty}. 1177 * 1178 * <p> If {@code canWriteEmpty()} returns {@code false}, 1179 * an {@code UnsupportedOperationException} will be thrown. 1180 * 1181 * <p> The default implementation throws an 1182 * {@code IllegalStateException} if the output is 1183 * {@code null}, and otherwise throws an 1184 * {@code UnsupportedOperationException}. 1185 * 1186 * @exception IllegalStateException if the output has not 1187 * been set. 1188 * @exception UnsupportedOperationException if 1189 * {@code canWriteEmpty(imageIndex)} returns 1190 * {@code false}. 1191 * @exception IllegalStateException if a previous call to 1192 * {@code prepareWriteEmpty} without a corresponding call to 1193 * {@code endWriteEmpty} has not been made. 1194 * @exception IllegalStateException if a previous call to 1195 * {@code prepareInsertEmpty} without a corresponding call to 1196 * {@code endInsertEmpty} has been made. 1197 * @exception IllegalStateException if a call to 1198 * {@code prepareReiplacePixels} has been made without a 1199 * matching call to {@code endReplacePixels}. 1200 * @exception IOException if an I/O error occurs during writing. 1201 */ 1202 public void endWriteEmpty() throws IOException { 1203 if (getOutput() == null) { 1204 throw new IllegalStateException("getOutput() == null!"); 1205 } 1206 throw new IllegalStateException("No call to prepareWriteEmpty!"); 1207 } 1208 1209 /** 1210 * Returns {@code true} if the writer supports the insertion 1211 * of a new, empty image at the given index. The pixel values of 1212 * the image are undefined, and may be specified in pieces using 1213 * the {@code replacePixels} methods. Existing images with 1214 * indices greater than or equal to the insertion index will have 1215 * their indices increased by 1. A value for 1216 * {@code imageIndex} of {@code -1} may be used to 1217 * signify an index one larger than the current largest index. 1218 * 1219 * <p> A writer that does not support insertion of empty images 1220 * may return {@code false} without performing bounds 1221 * checking on the index. 1222 * 1223 * <p> The default implementation throws an 1224 * {@code IllegalStateException} if the output is 1225 * {@code null}, and otherwise returns {@code false} 1226 * without checking the value of {@code imageIndex}. 1227 * 1228 * @param imageIndex the index at which the image is to be 1229 * inserted. 1230 * 1231 * @return {@code true} if an empty image may be inserted at 1232 * the given index. 1233 * 1234 * @exception IllegalStateException if the output has not been 1235 * set. 1236 * @exception IndexOutOfBoundsException if the writer supports 1237 * empty image insertion in general, but {@code imageIndex} 1238 * is less than -1 or greater than the largest available index. 1239 * @exception IOException if an I/O error occurs during the 1240 * query. 1241 */ 1242 public boolean canInsertEmpty(int imageIndex) throws IOException { 1243 if (getOutput() == null) { 1244 throw new IllegalStateException("getOutput() == null!"); 1245 } 1246 return false; 1247 } 1248 1249 /** 1250 * Begins the insertion of a new image with undefined pixel values 1251 * into an existing image stream. Existing images with an index 1252 * greater than {@code imageIndex} are preserved, and their 1253 * indices are each increased by 1. A value for 1254 * {@code imageIndex} of -1 may be used to signify an index 1255 * one larger than the previous largest index; that is, it will 1256 * cause the image to be logically appended to the end of the 1257 * sequence. If the output is an {@code ImageOutputStream}, 1258 * the entirety of the stream must be both readable and writeable. 1259 * 1260 * <p> The image contents may be 1261 * supplied later using the {@code replacePixels} method. 1262 * The insertion is not complete until a call to 1263 * {@code endInsertEmpty} occurs. Calls to 1264 * {@code prepareReplacePixels}, {@code replacePixels}, 1265 * and {@code endReplacePixels} may occur between calls to 1266 * {@code prepareInsertEmpty} and 1267 * {@code endInsertEmpty}. However, calls to 1268 * {@code prepareInsertEmpty} cannot be nested, and calls to 1269 * {@code prepareWriteEmpty} and 1270 * {@code prepareInsertEmpty} may not be interspersed. 1271 * 1272 * <p> If {@code canInsertEmpty(imageIndex)} returns 1273 * {@code false}, an 1274 * {@code UnsupportedOperationException} will be thrown. 1275 * 1276 * <p> An {@code ImageWriteParam} may optionally be supplied 1277 * to control the writing process. If {@code param} is 1278 * {@code null}, a default write param will be used. 1279 * 1280 * <p> If the supplied {@code ImageWriteParam} contains 1281 * optional setting values not supported by this writer (<i>e.g.</i> 1282 * progressive encoding or any format-specific settings), they 1283 * will be ignored. 1284 * 1285 * <p> The default implementation throws an 1286 * {@code IllegalStateException} if the output is 1287 * {@code null}, and otherwise throws an 1288 * {@code UnsupportedOperationException}. 1289 * 1290 * @param imageIndex the index at which to write the image. 1291 * @param imageType an {@code ImageTypeSpecifier} describing 1292 * the layout of the image. 1293 * @param width the width of the image. 1294 * @param height the height of the image. 1295 * @param imageMetadata an {@code IIOMetadata} object 1296 * representing image metadata, or {@code null}. 1297 * @param thumbnails a {@code List} of 1298 * {@code BufferedImage} thumbnails for this image, or 1299 * {@code null}. 1300 * @param param an {@code ImageWriteParam}, or 1301 * {@code null} to use a default 1302 * {@code ImageWriteParam}. 1303 * 1304 * @exception IllegalStateException if the output has not 1305 * been set. 1306 * @exception UnsupportedOperationException if 1307 * {@code canInsertEmpty(imageIndex)} returns 1308 * {@code false}. 1309 * @exception IndexOutOfBoundsException if {@code imageIndex} 1310 * is less than -1 or greater than the largest available index. 1311 * @exception IllegalStateException if a previous call to 1312 * {@code prepareInsertEmpty} has been made without a 1313 * corresponding call to {@code endInsertEmpty}. 1314 * @exception IllegalStateException if a previous call to 1315 * {@code prepareWriteEmpty} has been made without a 1316 * corresponding call to {@code endWriteEmpty}. 1317 * @exception IllegalArgumentException if {@code imageType} 1318 * is {@code null} or {@code thumbnails} contains 1319 * {@code null} references or objects other than 1320 * {@code BufferedImage}s. 1321 * @exception IllegalArgumentException if width or height are less 1322 * than 1. 1323 * @exception IOException if an I/O error occurs during writing. 1324 */ 1325 public void prepareInsertEmpty(int imageIndex, 1326 ImageTypeSpecifier imageType, 1327 int width, int height, 1328 IIOMetadata imageMetadata, 1329 List<? extends BufferedImage> thumbnails, 1330 ImageWriteParam param) throws IOException { 1331 unsupported(); 1332 } 1333 1334 /** 1335 * Completes the insertion of a new image that was begun with a 1336 * prior call to {@code prepareInsertEmpty}. 1337 * 1338 * <p> The default implementation throws an 1339 * {@code IllegalStateException} if the output is 1340 * {@code null}, and otherwise throws an 1341 * {@code UnsupportedOperationException}. 1342 * 1343 * @exception IllegalStateException if the output has not 1344 * been set. 1345 * @exception UnsupportedOperationException if 1346 * {@code canInsertEmpty(imageIndex)} returns 1347 * {@code false}. 1348 * @exception IllegalStateException if a previous call to 1349 * {@code prepareInsertEmpty} without a corresponding call to 1350 * {@code endInsertEmpty} has not been made. 1351 * @exception IllegalStateException if a previous call to 1352 * {@code prepareWriteEmpty} without a corresponding call to 1353 * {@code endWriteEmpty} has been made. 1354 * @exception IllegalStateException if a call to 1355 * {@code prepareReplacePixels} has been made without a 1356 * matching call to {@code endReplacePixels}. 1357 * @exception IOException if an I/O error occurs during writing. 1358 */ 1359 public void endInsertEmpty() throws IOException { 1360 unsupported(); 1361 } 1362 1363 // Pixel replacement 1364 1365 /** 1366 * Returns {@code true} if the writer allows pixels of the 1367 * given image to be replaced using the {@code replacePixels} 1368 * methods. 1369 * 1370 * <p> A writer that does not support any pixel replacement may 1371 * return {@code false} without performing bounds checking on 1372 * the index. 1373 * 1374 * <p> The default implementation throws an 1375 * {@code IllegalStateException} if the output is 1376 * {@code null}, and otherwise returns {@code false} 1377 * without checking the value of {@code imageIndex}. 1378 * 1379 * @param imageIndex the index of the image whose pixels are to be 1380 * replaced. 1381 * 1382 * @return {@code true} if the pixels of the given 1383 * image can be replaced. 1384 * 1385 * @exception IllegalStateException if the output has not been 1386 * set. 1387 * @exception IndexOutOfBoundsException if the writer supports 1388 * pixel replacement in general, but {@code imageIndex} is 1389 * less than 0 or greater than the largest available index. 1390 * @exception IOException if an I/O error occurs during the query. 1391 */ 1392 public boolean canReplacePixels(int imageIndex) throws IOException { 1393 if (getOutput() == null) { 1394 throw new IllegalStateException("getOutput() == null!"); 1395 } 1396 return false; 1397 } 1398 1399 /** 1400 * Prepares the writer to handle a series of calls to the 1401 * {@code replacePixels} methods. The affected pixel area 1402 * will be clipped against the supplied 1403 * 1404 * <p> If {@code canReplacePixels} returns 1405 * {@code false}, and 1406 * {@code UnsupportedOperationException} will be thrown. 1407 * 1408 * <p> The default implementation throws an 1409 * {@code IllegalStateException} if the output is 1410 * {@code null}, and otherwise throws an 1411 * {@code UnsupportedOperationException}. 1412 * 1413 * @param imageIndex the index of the image whose pixels are to be 1414 * replaced. 1415 * @param region a {@code Rectangle} that will be used to clip 1416 * future pixel regions. 1417 * 1418 * @exception IllegalStateException if the output has not 1419 * been set. 1420 * @exception UnsupportedOperationException if 1421 * {@code canReplacePixels(imageIndex)} returns 1422 * {@code false}. 1423 * @exception IndexOutOfBoundsException if {@code imageIndex} 1424 * is less than 0 or greater than the largest available index. 1425 * @exception IllegalStateException if there is a previous call to 1426 * {@code prepareReplacePixels} without a matching call to 1427 * {@code endReplacePixels} (<i>i.e.</i>, nesting is not 1428 * allowed). 1429 * @exception IllegalArgumentException if {@code region} is 1430 * {@code null} or has a width or height less than 1. 1431 * @exception IOException if an I/O error occurs during the 1432 * preparation. 1433 */ 1434 public void prepareReplacePixels(int imageIndex, 1435 Rectangle region) throws IOException { 1436 unsupported(); 1437 } 1438 1439 /** 1440 * Replaces a portion of an image already present in the output 1441 * with a portion of the given image. The image data must match, 1442 * or be convertible to, the image layout of the existing image. 1443 * 1444 * <p> The destination region is specified in the 1445 * {@code param} argument, and will be clipped to the image 1446 * boundaries and the region supplied to 1447 * {@code prepareReplacePixels}. At least one pixel of the 1448 * source must not be clipped, or an exception is thrown. 1449 * 1450 * <p> An {@code ImageWriteParam} may optionally be supplied 1451 * to control the writing process. If {@code param} is 1452 * {@code null}, a default write param will be used. 1453 * 1454 * <p> If the supplied {@code ImageWriteParam} contains 1455 * optional setting values not supported by this writer (<i>e.g.</i> 1456 * progressive encoding or any format-specific settings), they 1457 * will be ignored. 1458 * 1459 * <p> This method may only be called after a call to 1460 * {@code prepareReplacePixels}, or else an 1461 * {@code IllegalStateException} will be thrown. 1462 * 1463 * <p> The default implementation throws an 1464 * {@code IllegalStateException} if the output is 1465 * {@code null}, and otherwise throws an 1466 * {@code UnsupportedOperationException}. 1467 * 1468 * @param image a {@code RenderedImage} containing source 1469 * pixels. 1470 * @param param an {@code ImageWriteParam}, or 1471 * {@code null} to use a default 1472 * {@code ImageWriteParam}. 1473 * 1474 * @exception IllegalStateException if the output has not 1475 * been set. 1476 * @exception UnsupportedOperationException if 1477 * {@code canReplacePixels(imageIndex)} returns 1478 * {@code false}. 1479 * @exception IllegalStateException if there is no previous call to 1480 * {@code prepareReplacePixels} without a matching call to 1481 * {@code endReplacePixels}. 1482 * @exception IllegalArgumentException if any of the following are true: 1483 * <ul> 1484 * <li> {@code image} is {@code null}. 1485 * <li> the intersected region does not contain at least one pixel. 1486 * <li> the layout of {@code image} does not match, or this 1487 * writer cannot convert it to, the existing image layout. 1488 * </ul> 1489 * @exception IOException if an I/O error occurs during writing. 1490 */ 1491 public void replacePixels(RenderedImage image, ImageWriteParam param) 1492 throws IOException { 1493 unsupported(); 1494 } 1495 1496 /** 1497 * Replaces a portion of an image already present in the output 1498 * with a portion of the given {@code Raster}. The image 1499 * data must match, or be convertible to, the image layout of the 1500 * existing image. 1501 * 1502 * <p> An {@code ImageWriteParam} may optionally be supplied 1503 * to control the writing process. If {@code param} is 1504 * {@code null}, a default write param will be used. 1505 * 1506 * <p> The destination region is specified in the 1507 * {@code param} argument, and will be clipped to the image 1508 * boundaries and the region supplied to 1509 * {@code prepareReplacePixels}. At least one pixel of the 1510 * source must not be clipped, or an exception is thrown. 1511 * 1512 * <p> If the supplied {@code ImageWriteParam} contains 1513 * optional setting values not supported by this writer (<i>e.g.</i> 1514 * progressive encoding or any format-specific settings), they 1515 * will be ignored. 1516 * 1517 * <p> This method may only be called after a call to 1518 * {@code prepareReplacePixels}, or else an 1519 * {@code IllegalStateException} will be thrown. 1520 * 1521 * <p> The default implementation throws an 1522 * {@code IllegalStateException} if the output is 1523 * {@code null}, and otherwise throws an 1524 * {@code UnsupportedOperationException}. 1525 * 1526 * @param raster a {@code Raster} containing source 1527 * pixels. 1528 * @param param an {@code ImageWriteParam}, or 1529 * {@code null} to use a default 1530 * {@code ImageWriteParam}. 1531 * 1532 * @exception IllegalStateException if the output has not 1533 * been set. 1534 * @exception UnsupportedOperationException if 1535 * {@code canReplacePixels(imageIndex)} returns 1536 * {@code false}. 1537 * @exception IllegalStateException if there is no previous call to 1538 * {@code prepareReplacePixels} without a matching call to 1539 * {@code endReplacePixels}. 1540 * @exception UnsupportedOperationException if 1541 * {@code canWriteRasters} returns {@code false}. 1542 * @exception IllegalArgumentException if any of the following are true: 1543 * <ul> 1544 * <li> {@code raster} is {@code null}. 1545 * <li> the intersected region does not contain at least one pixel. 1546 * <li> the layout of {@code raster} does not match, or this 1547 * writer cannot convert it to, the existing image layout. 1548 * </ul> 1549 * @exception IOException if an I/O error occurs during writing. 1550 */ 1551 public void replacePixels(Raster raster, ImageWriteParam param) 1552 throws IOException { 1553 unsupported(); 1554 } 1555 1556 /** 1557 * Terminates a sequence of calls to {@code replacePixels}. 1558 * 1559 * <p> If {@code canReplacePixels} returns 1560 * {@code false}, and 1561 * {@code UnsupportedOperationException} will be thrown. 1562 * 1563 * <p> The default implementation throws an 1564 * {@code IllegalStateException} if the output is 1565 * {@code null}, and otherwise throws an 1566 * {@code UnsupportedOperationException}. 1567 * 1568 * @exception IllegalStateException if the output has not 1569 * been set. 1570 * @exception UnsupportedOperationException if 1571 * {@code canReplacePixels(imageIndex)} returns 1572 * {@code false}. 1573 * @exception IllegalStateException if there is no previous call 1574 * to {@code prepareReplacePixels} without a matching call to 1575 * {@code endReplacePixels}. 1576 * @exception IOException if an I/O error occurs during writing. 1577 */ 1578 public void endReplacePixels() throws IOException { 1579 unsupported(); 1580 } 1581 1582 // Abort 1583 1584 /** 1585 * Requests that any current write operation be aborted. The 1586 * contents of the output following the abort will be undefined. 1587 * 1588 * <p> Writers should call {@code clearAbortRequest} at the 1589 * beginning of each write operation, and poll the value of 1590 * {@code abortRequested} regularly during the write. 1591 */ 1592 public synchronized void abort() { 1593 this.abortFlag = true; 1594 } 1595 1596 /** 1597 * Returns {@code true} if a request to abort the current 1598 * write operation has been made since the writer was instantiated or 1599 * {@code clearAbortRequest} was called. 1600 * 1601 * @return {@code true} if the current write operation should 1602 * be aborted. 1603 * 1604 * @see #abort 1605 * @see #clearAbortRequest 1606 */ 1607 protected synchronized boolean abortRequested() { 1608 return this.abortFlag; 1609 } 1610 1611 /** 1612 * Clears any previous abort request. After this method has been 1613 * called, {@code abortRequested} will return 1614 * {@code false}. 1615 * 1616 * @see #abort 1617 * @see #abortRequested 1618 */ 1619 protected synchronized void clearAbortRequest() { 1620 this.abortFlag = false; 1621 } 1622 1623 // Listeners 1624 1625 /** 1626 * Adds an {@code IIOWriteWarningListener} to the list of 1627 * registered warning listeners. If {@code listener} is 1628 * {@code null}, no exception will be thrown and no action 1629 * will be taken. Messages sent to the given listener will be 1630 * localized, if possible, to match the current 1631 * {@code Locale}. If no {@code Locale} has been set, 1632 * warning messages may be localized as the writer sees fit. 1633 * 1634 * @param listener an {@code IIOWriteWarningListener} to be 1635 * registered. 1636 * 1637 * @see #removeIIOWriteWarningListener 1638 */ 1639 public void addIIOWriteWarningListener(IIOWriteWarningListener listener) { 1640 if (listener == null) { 1641 return; 1642 } 1643 warningListeners = ImageReader.addToList(warningListeners, listener); 1644 warningLocales = ImageReader.addToList(warningLocales, getLocale()); 1645 } 1646 1647 /** 1648 * Removes an {@code IIOWriteWarningListener} from the list 1649 * of registered warning listeners. If the listener was not 1650 * previously registered, or if {@code listener} is 1651 * {@code null}, no exception will be thrown and no action 1652 * will be taken. 1653 * 1654 * @param listener an {@code IIOWriteWarningListener} to be 1655 * deregistered. 1656 * 1657 * @see #addIIOWriteWarningListener 1658 */ 1659 public 1660 void removeIIOWriteWarningListener(IIOWriteWarningListener listener) { 1661 if (listener == null || warningListeners == null) { 1662 return; 1663 } 1664 int index = warningListeners.indexOf(listener); 1665 if (index != -1) { 1666 warningListeners.remove(index); 1667 warningLocales.remove(index); 1668 if (warningListeners.size() == 0) { 1669 warningListeners = null; 1670 warningLocales = null; 1671 } 1672 } 1673 } 1674 1675 /** 1676 * Removes all currently registered 1677 * {@code IIOWriteWarningListener} objects. 1678 * 1679 * <p> The default implementation sets the 1680 * {@code warningListeners} and {@code warningLocales} 1681 * instance variables to {@code null}. 1682 */ 1683 public void removeAllIIOWriteWarningListeners() { 1684 this.warningListeners = null; 1685 this.warningLocales = null; 1686 } 1687 1688 /** 1689 * Adds an {@code IIOWriteProgressListener} to the list of 1690 * registered progress listeners. If {@code listener} is 1691 * {@code null}, no exception will be thrown and no action 1692 * will be taken. 1693 * 1694 * @param listener an {@code IIOWriteProgressListener} to be 1695 * registered. 1696 * 1697 * @see #removeIIOWriteProgressListener 1698 */ 1699 public void 1700 addIIOWriteProgressListener(IIOWriteProgressListener listener) { 1701 if (listener == null) { 1702 return; 1703 } 1704 progressListeners = ImageReader.addToList(progressListeners, listener); 1705 } 1706 1707 /** 1708 * Removes an {@code IIOWriteProgressListener} from the list 1709 * of registered progress listeners. If the listener was not 1710 * previously registered, or if {@code listener} is 1711 * {@code null}, no exception will be thrown and no action 1712 * will be taken. 1713 * 1714 * @param listener an {@code IIOWriteProgressListener} to be 1715 * deregistered. 1716 * 1717 * @see #addIIOWriteProgressListener 1718 */ 1719 public void 1720 removeIIOWriteProgressListener(IIOWriteProgressListener listener) { 1721 if (listener == null || progressListeners == null) { 1722 return; 1723 } 1724 progressListeners = 1725 ImageReader.removeFromList(progressListeners, listener); 1726 } 1727 1728 /** 1729 * Removes all currently registered 1730 * {@code IIOWriteProgressListener} objects. 1731 * 1732 * <p> The default implementation sets the 1733 * {@code progressListeners} instance variable to 1734 * {@code null}. 1735 */ 1736 public void removeAllIIOWriteProgressListeners() { 1737 this.progressListeners = null; 1738 } 1739 1740 /** 1741 * Broadcasts the start of an image write to all registered 1742 * {@code IIOWriteProgressListener}s by calling their 1743 * {@code imageStarted} method. Subclasses may use this 1744 * method as a convenience. 1745 * 1746 * @param imageIndex the index of the image about to be written. 1747 */ 1748 protected void processImageStarted(int imageIndex) { 1749 if (progressListeners == null) { 1750 return; 1751 } 1752 int numListeners = progressListeners.size(); 1753 for (int i = 0; i < numListeners; i++) { 1754 IIOWriteProgressListener listener = 1755 progressListeners.get(i); 1756 listener.imageStarted(this, imageIndex); 1757 } 1758 } 1759 1760 /** 1761 * Broadcasts the current percentage of image completion to all 1762 * registered {@code IIOWriteProgressListener}s by calling 1763 * their {@code imageProgress} method. Subclasses may use 1764 * this method as a convenience. 1765 * 1766 * @param percentageDone the current percentage of completion, 1767 * as a {@code float}. 1768 */ 1769 protected void processImageProgress(float percentageDone) { 1770 if (progressListeners == null) { 1771 return; 1772 } 1773 int numListeners = progressListeners.size(); 1774 for (int i = 0; i < numListeners; i++) { 1775 IIOWriteProgressListener listener = 1776 progressListeners.get(i); 1777 listener.imageProgress(this, percentageDone); 1778 } 1779 } 1780 1781 /** 1782 * Broadcasts the completion of an image write to all registered 1783 * {@code IIOWriteProgressListener}s by calling their 1784 * {@code imageComplete} method. Subclasses may use this 1785 * method as a convenience. 1786 */ 1787 protected void processImageComplete() { 1788 if (progressListeners == null) { 1789 return; 1790 } 1791 int numListeners = progressListeners.size(); 1792 for (int i = 0; i < numListeners; i++) { 1793 IIOWriteProgressListener listener = 1794 progressListeners.get(i); 1795 listener.imageComplete(this); 1796 } 1797 } 1798 1799 /** 1800 * Broadcasts the start of a thumbnail write to all registered 1801 * {@code IIOWriteProgressListener}s by calling their 1802 * {@code thumbnailStarted} method. Subclasses may use this 1803 * method as a convenience. 1804 * 1805 * @param imageIndex the index of the image associated with the 1806 * thumbnail. 1807 * @param thumbnailIndex the index of the thumbnail. 1808 */ 1809 protected void processThumbnailStarted(int imageIndex, 1810 int thumbnailIndex) { 1811 if (progressListeners == null) { 1812 return; 1813 } 1814 int numListeners = progressListeners.size(); 1815 for (int i = 0; i < numListeners; i++) { 1816 IIOWriteProgressListener listener = 1817 progressListeners.get(i); 1818 listener.thumbnailStarted(this, imageIndex, thumbnailIndex); 1819 } 1820 } 1821 1822 /** 1823 * Broadcasts the current percentage of thumbnail completion to 1824 * all registered {@code IIOWriteProgressListener}s by calling 1825 * their {@code thumbnailProgress} method. Subclasses may 1826 * use this method as a convenience. 1827 * 1828 * @param percentageDone the current percentage of completion, 1829 * as a {@code float}. 1830 */ 1831 protected void processThumbnailProgress(float percentageDone) { 1832 if (progressListeners == null) { 1833 return; 1834 } 1835 int numListeners = progressListeners.size(); 1836 for (int i = 0; i < numListeners; i++) { 1837 IIOWriteProgressListener listener = 1838 progressListeners.get(i); 1839 listener.thumbnailProgress(this, percentageDone); 1840 } 1841 } 1842 1843 /** 1844 * Broadcasts the completion of a thumbnail write to all registered 1845 * {@code IIOWriteProgressListener}s by calling their 1846 * {@code thumbnailComplete} method. Subclasses may use this 1847 * method as a convenience. 1848 */ 1849 protected void processThumbnailComplete() { 1850 if (progressListeners == null) { 1851 return; 1852 } 1853 int numListeners = progressListeners.size(); 1854 for (int i = 0; i < numListeners; i++) { 1855 IIOWriteProgressListener listener = 1856 progressListeners.get(i); 1857 listener.thumbnailComplete(this); 1858 } 1859 } 1860 1861 /** 1862 * Broadcasts that the write has been aborted to all registered 1863 * {@code IIOWriteProgressListener}s by calling their 1864 * {@code writeAborted} method. Subclasses may use this 1865 * method as a convenience. 1866 */ 1867 protected void processWriteAborted() { 1868 if (progressListeners == null) { 1869 return; 1870 } 1871 int numListeners = progressListeners.size(); 1872 for (int i = 0; i < numListeners; i++) { 1873 IIOWriteProgressListener listener = 1874 progressListeners.get(i); 1875 listener.writeAborted(this); 1876 } 1877 } 1878 1879 /** 1880 * Broadcasts a warning message to all registered 1881 * {@code IIOWriteWarningListener}s by calling their 1882 * {@code warningOccurred} method. Subclasses may use this 1883 * method as a convenience. 1884 * 1885 * @param imageIndex the index of the image on which the warning 1886 * occurred. 1887 * @param warning the warning message. 1888 * 1889 * @exception IllegalArgumentException if {@code warning} 1890 * is {@code null}. 1891 */ 1892 protected void processWarningOccurred(int imageIndex, 1893 String warning) { 1894 if (warningListeners == null) { 1895 return; 1896 } 1897 if (warning == null) { 1898 throw new IllegalArgumentException("warning == null!"); 1899 } 1900 int numListeners = warningListeners.size(); 1901 for (int i = 0; i < numListeners; i++) { 1902 IIOWriteWarningListener listener = 1903 warningListeners.get(i); 1904 1905 listener.warningOccurred(this, imageIndex, warning); 1906 } 1907 } 1908 1909 /** 1910 * Broadcasts a localized warning message to all registered 1911 * {@code IIOWriteWarningListener}s by calling their 1912 * {@code warningOccurred} method with a string taken 1913 * from a {@code ResourceBundle}. Subclasses may use this 1914 * method as a convenience. 1915 * 1916 * @param imageIndex the index of the image on which the warning 1917 * occurred. 1918 * @param baseName the base name of a set of 1919 * {@code ResourceBundle}s containing localized warning 1920 * messages. 1921 * @param keyword the keyword used to index the warning message 1922 * within the set of {@code ResourceBundle}s. 1923 * 1924 * @exception IllegalArgumentException if {@code baseName} 1925 * is {@code null}. 1926 * @exception IllegalArgumentException if {@code keyword} 1927 * is {@code null}. 1928 * @exception IllegalArgumentException if no appropriate 1929 * {@code ResourceBundle} may be located. 1930 * @exception IllegalArgumentException if the named resource is 1931 * not found in the located {@code ResourceBundle}. 1932 * @exception IllegalArgumentException if the object retrieved 1933 * from the {@code ResourceBundle} is not a 1934 * {@code String}. 1935 */ 1936 protected void processWarningOccurred(int imageIndex, 1937 String baseName, 1938 String keyword) { 1939 if (warningListeners == null) { 1940 return; 1941 } 1942 if (baseName == null) { 1943 throw new IllegalArgumentException("baseName == null!"); 1944 } 1945 if (keyword == null) { 1946 throw new IllegalArgumentException("keyword == null!"); 1947 } 1948 int numListeners = warningListeners.size(); 1949 for (int i = 0; i < numListeners; i++) { 1950 IIOWriteWarningListener listener = 1951 warningListeners.get(i); 1952 Locale locale = warningLocales.get(i); 1953 if (locale == null) { 1954 locale = Locale.getDefault(); 1955 } 1956 1957 /* 1958 * Only the plugin knows the messages that are provided, so we 1959 * can always locate the resource bundles from the same loader 1960 * as that for the plugin code itself. 1961 */ 1962 ResourceBundle bundle = null; 1963 try { 1964 bundle = ResourceBundle.getBundle(baseName, locale, this.getClass().getModule()); 1965 } catch (MissingResourceException mre) { 1966 throw new IllegalArgumentException("Bundle not found!", mre); 1967 } 1968 1969 String warning = null; 1970 try { 1971 warning = bundle.getString(keyword); 1972 } catch (ClassCastException cce) { 1973 throw new IllegalArgumentException("Resource is not a String!", cce); 1974 } catch (MissingResourceException mre) { 1975 throw new IllegalArgumentException("Resource is missing!", mre); 1976 } 1977 1978 listener.warningOccurred(this, imageIndex, warning); 1979 } 1980 } 1981 1982 // State management 1983 1984 /** 1985 * Restores the {@code ImageWriter} to its initial state. 1986 * 1987 * <p> The default implementation calls 1988 * {@code setOutput(null)}, {@code setLocale(null)}, 1989 * {@code removeAllIIOWriteWarningListeners()}, 1990 * {@code removeAllIIOWriteProgressListeners()}, and 1991 * {@code clearAbortRequest}. 1992 */ 1993 public void reset() { 1994 setOutput(null); 1995 setLocale(null); 1996 removeAllIIOWriteWarningListeners(); 1997 removeAllIIOWriteProgressListeners(); 1998 clearAbortRequest(); 1999 } 2000 2001 /** 2002 * Allows any resources held by this object to be released. The 2003 * result of calling any other method (other than 2004 * {@code finalize}) subsequent to a call to this method 2005 * is undefined. 2006 * 2007 * <p>It is important for applications to call this method when they 2008 * know they will no longer be using this {@code ImageWriter}. 2009 * Otherwise, the writer may continue to hold on to resources 2010 * indefinitely. 2011 * 2012 * <p>The default implementation of this method in the superclass does 2013 * nothing. Subclass implementations should ensure that all resources, 2014 * especially native resources, are released. 2015 */ 2016 public void dispose() { 2017 } 2018} 2019