1 /*
2 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javax.imageio;
27
28 import java.awt.Dimension;
29 import java.awt.Rectangle;
30 import java.awt.image.BufferedImage;
31 import java.awt.image.RenderedImage;
32 import java.awt.image.Raster;
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Locale;
37 import java.util.MissingResourceException;
38 import java.util.ResourceBundle;
39 import javax.imageio.event.IIOWriteWarningListener;
40 import javax.imageio.event.IIOWriteProgressListener;
41 import javax.imageio.metadata.IIOMetadata;
42 import javax.imageio.stream.ImageOutputStream;
43 import 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 */
62 public 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