KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > imageio > ImageWriteParam


1 /*
2  * @(#)ImageWriteParam.java 1.62 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.imageio;
9
10 import java.awt.color.ICC_Profile JavaDoc;
11 import java.awt.image.LookupTable JavaDoc;
12 import java.awt.image.RenderedImage JavaDoc;
13 import java.awt.Dimension JavaDoc;
14 import java.util.Locale JavaDoc;
15
16 /**
17  * A class describing how a stream is to be encoded. Instances of
18  * this class or its subclasses are used to supply prescriptive
19  * "how-to" information to instances of <code>ImageWriter</code>.
20  *
21  * <p> A plug-in for a specific image format may define a subclass of
22  * this class, and return objects of that class from the
23  * <code>getDefaultWriteParam</code> method of its
24  * <code>ImageWriter</code> implementation. For example, the built-in
25  * JPEG writer plug-in will return instances of
26  * <code>javax.imageio.plugins.jpeg.JPEGImageWriteParam</code>.
27  *
28  * <p> The region of the image to be written is determined by first
29  * intersecting the actual bounds of the image with the rectangle
30  * specified by <code>IIOParam.setSourceRegion</code>, if any. If the
31  * resulting rectangle has a width or height of zero, the writer will
32  * throw an <code>IIOException</code>. If the intersection is
33  * non-empty, writing will commence with the first subsampled pixel
34  * and include additional pixels within the intersected bounds
35  * according to the horizontal and vertical subsampling factors
36  * specified by {@link IIOParam#setSourceSubsampling
37  * <code>IIOParam.setSourceSubsampling</code>}.
38  *
39  * <p> Individual features such as tiling, progressive encoding, and
40  * compression may be set in one of four modes.
41  * <code>MODE_DISABLED</code> disables the features;
42  * <code>MODE_DEFAULT</code> enables the feature with
43  * writer-controlled parameter values; <code>MODE_EXPLICIT</code>
44  * enables the feature and allows the use of a <code>set</code> method
45  * to provide additional parameters; and
46  * <code>MODE_COPY_FROM_METADATA</code> copies relevant parameter
47  * values from the stream and image metadata objects passed to the
48  * writer. The default for all features is
49  * <code>MODE_COPY_FROM_METADATA</code>. Non-standard features
50  * supplied in subclasses are encouraged, but not required to use a
51  * similar scheme.
52  *
53  * <p> Plug-in writers may extend the functionality of
54  * <code>ImageWriteParam</code> by providing a subclass that implements
55  * additional, plug-in specific interfaces. It is up to the plug-in
56  * to document what interfaces are available and how they are to be
57  * used. Writers will silently ignore any extended features of an
58  * <code>ImageWriteParam</code> subclass of which they are not aware.
59  * Also, they may ignore any optional features that they normally
60  * disable when creating their own <code>ImageWriteParam</code>
61  * instances via <code>getDefaultWriteParam</code>.
62  *
63  * <p> Note that unless a query method exists for a capability, it must
64  * be supported by all <code>ImageWriter</code> implementations
65  * (<i>e.g.</i> progressive encoding is optional, but subsampling must be
66  * supported).
67  *
68  * @version 0.5
69  *
70  * @see ImageReadParam
71  */

72 public class ImageWriteParam extends IIOParam JavaDoc {
73
74     /**
75      * A constant value that may be passed into methods such as
76      * <code>setTilingMode</code>, <code>setProgressiveMode</code>,
77      * and <code>setCompressionMode</code> to disable a feature for
78      * future writes. That is, when this mode is set the stream will
79      * <b>not</b> be tiled, progressive, or compressed, and the
80      * relevant accessor methods will throw an
81      * <code>IllegalStateException</code>.
82      *
83      * @see #MODE_EXPLICIT
84      * @see #MODE_COPY_FROM_METADATA
85      * @see #MODE_DEFAULT
86      * @see #setProgressiveMode
87      * @see #getProgressiveMode
88      * @see #setTilingMode
89      * @see #getTilingMode
90      * @see #setCompressionMode
91      * @see #getCompressionMode
92      */

93     public static final int MODE_DISABLED = 0;
94
95     /**
96      * A constant value that may be passed into methods such as
97      * <code>setTilingMode</code>,
98      * <code>setProgressiveMode</code>, and
99      * <code>setCompressionMode</code> to enable that feature for
100      * future writes. That is, when this mode is enabled the stream
101      * will be tiled, progressive, or compressed according to a
102      * sensible default chosen internally by the writer in a plug-in
103      * dependent way, and the relevant accessor methods will
104      * throw an <code>IllegalStateException</code>.
105      *
106      * @see #MODE_DISABLED
107      * @see #MODE_EXPLICIT
108      * @see #MODE_COPY_FROM_METADATA
109      * @see #setProgressiveMode
110      * @see #getProgressiveMode
111      * @see #setTilingMode
112      * @see #getTilingMode
113      * @see #setCompressionMode
114      * @see #getCompressionMode
115      */

116     public static final int MODE_DEFAULT = 1;
117
118     /**
119      * A constant value that may be passed into methods such as
120      * <code>setTilingMode</code> or <code>setCompressionMode</code>
121      * to enable a feature for future writes. That is, when this mode
122      * is set the stream will be tiled or compressed according to
123      * additional information supplied to the corresponding
124      * <code>set</code> methods in this class and retrievable from the
125      * corresponding <code>get</code> methods. Note that this mode is
126      * not supported for progressive output.
127      *
128      * @see #MODE_DISABLED
129      * @see #MODE_COPY_FROM_METADATA
130      * @see #MODE_DEFAULT
131      * @see #setProgressiveMode
132      * @see #getProgressiveMode
133      * @see #setTilingMode
134      * @see #getTilingMode
135      * @see #setCompressionMode
136      * @see #getCompressionMode
137      */

138     public static final int MODE_EXPLICIT = 2;
139
140     /**
141      * A constant value that may be passed into methods such as
142      * <code>setTilingMode</code>, <code>setProgressiveMode</code>, or
143      * <code>setCompressionMode</code> to enable that feature for
144      * future writes. That is, when this mode is enabled the stream
145      * will be tiled, progressive, or compressed based on the contents
146      * of stream and/or image metadata passed into the write
147      * operation, and any relevant accessor methods will throw an
148      * <code>IllegalStateException</code>.
149      *
150      * <p> This is the default mode for all features, so that a read
151      * including metadata followed by a write including metadata will
152      * preserve as much information as possible.
153      *
154      * @see #MODE_DISABLED
155      * @see #MODE_EXPLICIT
156      * @see #MODE_DEFAULT
157      * @see #setProgressiveMode
158      * @see #getProgressiveMode
159      * @see #setTilingMode
160      * @see #getTilingMode
161      * @see #setCompressionMode
162      * @see #getCompressionMode
163      */

164     public static final int MODE_COPY_FROM_METADATA = 3;
165
166     // If more modes are added, this should be updated.
167
private static final int MAX_MODE = MODE_COPY_FROM_METADATA;
168
169     /**
170      * A <code>boolean</code> that is <code>true</code> if this
171      * <code>ImageWriteParam</code> allows tile width and tile height
172      * parameters to be set. By default, the value is
173      * <code>false</code>. Subclasses must set the value manually.
174      *
175      * <p> Subclasses that do not support writing tiles should ensure
176      * that this value is set to <code>false</code>.
177      */

178     protected boolean canWriteTiles = false;
179
180     /**
181      * The mode controlling tiling settings, which Must be
182      * set to one of the four <code>MODE_*</code> values. The default
183      * is <code>MODE_COPY_FROM_METADATA</code>.
184      *
185      * <p> Subclasses that do not writing tiles may ignore this value.
186      *
187      * @see #MODE_DISABLED
188      * @see #MODE_EXPLICIT
189      * @see #MODE_COPY_FROM_METADATA
190      * @see #MODE_DEFAULT
191      * @see #setTilingMode
192      * @see #getTilingMode
193      */

194     protected int tilingMode = MODE_COPY_FROM_METADATA;
195
196     /**
197      * An array of preferred tile size range pairs. The default value
198      * is <code>null</code>, which indicates that there are no
199      * preferred sizes. If the value is non-<code>null</code>, it
200      * must have an even length of at least two.
201      *
202      * <p> Subclasses that do not support writing tiles may ignore
203      * this value.
204      *
205      * @see #getPreferredTileSizes
206      */

207     protected Dimension JavaDoc[] preferredTileSizes = null;
208
209     /**
210      * A <code>boolean</code> that is <code>true</code> if tiling
211      * parameters have been specified.
212      *
213      * <p> Subclasses that do not support writing tiles may ignore
214      * this value.
215      */

216     protected boolean tilingSet = false;
217
218     /**
219      * The width of each tile if tiling has been set, or 0 otherwise.
220      *
221      * <p> Subclasses that do not support tiling may ignore this
222      * value.
223      */

224     protected int tileWidth = 0;
225
226     /**
227      * The height of each tile if tiling has been set, or 0 otherwise.
228      * The initial value is <code>0</code>.
229      *
230      * <p> Subclasses that do not support tiling may ignore this
231      * value.
232      */

233     protected int tileHeight = 0;
234
235     /**
236      * A <code>boolean</code> that is <code>true</code> if this
237      * <code>ImageWriteParam</code> allows tiling grid offset
238      * parameters to be set. By default, the value is
239      * <code>false</code>. Subclasses must set the value manually.
240      *
241      * <p> Subclasses that do not support writing tiles, or that
242      * supprt writing but not offsetting tiles must ensure that this
243      * value is set to <code>false</code>.
244      */

245     protected boolean canOffsetTiles = false;
246
247     /**
248      * The amount by which the tile grid origin should be offset
249      * horizontally from the image origin if tiling has been set,
250      * or 0 otherwise. The initial value is <code>0</code>.
251      *
252      * <p> Subclasses that do not support offsetting tiles may ignore
253      * this value.
254      */

255     protected int tileGridXOffset = 0;
256
257     /**
258      * The amount by which the tile grid origin should be offset
259      * vertically from the image origin if tiling has been set,
260      * or 0 otherwise. The initial value is <code>0</code>.
261      *
262      * <p> Subclasses that do not support offsetting tiles may ignore
263      * this value.
264      */

265     protected int tileGridYOffset = 0;
266
267     /**
268      * A <code>boolean</code> that is <code>true</code> if this
269      * <code>ImageWriteParam</code> allows images to be written as a
270      * progressive sequence of increasing quality passes. By default,
271      * the value is <code>false</code>. Subclasses must set the value
272      * manually.
273      *
274      * <p> Subclasses that do not support progressive encoding must
275      * ensure that this value is set to <code>false</code>.
276      */

277     protected boolean canWriteProgressive = false;
278
279     /**
280      * The mode controlling progressive encoding, which must be set to
281      * one of the four <code>MODE_*</code> values, except
282      * <code>MODE_EXPLICIT</code>. The default is
283      * <code>MODE_COPY_FROM_METADATA</code>.
284      *
285      * <p> Subclasses that do not support progressive encoding may
286      * ignore this value.
287      *
288      * @see #MODE_DISABLED
289      * @see #MODE_EXPLICIT
290      * @see #MODE_COPY_FROM_METADATA
291      * @see #MODE_DEFAULT
292      * @see #setProgressiveMode
293      * @see #getProgressiveMode
294      */

295     protected int progressiveMode = MODE_COPY_FROM_METADATA;
296
297     /**
298      * A <code>boolean</code> that is <code>true</code> if this writer
299      * can write images using compression. By default, the value is
300      * <code>false</code>. Subclasses must set the value manually.
301      *
302      * <p> Subclasses that do not support compression must ensure that
303      * this value is set to <code>false</code>.
304      */

305     protected boolean canWriteCompressed = false;
306
307     /**
308      * The mode controlling compression settings, which must be set to
309      * one of the four <code>MODE_*</code> values. The default is
310      * <code>MODE_COPY_FROM_METADATA</code>.
311      *
312      * <p> Subclasses that do not support compression may ignore this
313      * value.
314      *
315      * @see #MODE_DISABLED
316      * @see #MODE_EXPLICIT
317      * @see #MODE_COPY_FROM_METADATA
318      * @see #MODE_DEFAULT
319      * @see #setCompressionMode
320      * @see #getCompressionMode
321      */

322     protected int compressionMode = MODE_COPY_FROM_METADATA;
323
324     /**
325      * An array of <code>String</code>s containing the names of the
326      * available compression types. Subclasses must set the value
327      * manually.
328      *
329      * <p> Subclasses that do not support compression may ignore this
330      * value.
331      */

332     protected String JavaDoc[] compressionTypes = null;
333
334     /**
335      * A <code>String</code> containing the name of the current
336      * compression type, or <code>null</code> if none is set.
337      *
338      * <p> Subclasses that do not support compression may ignore this
339      * value.
340      */

341     protected String JavaDoc compressionType = null;
342
343     /**
344      * A <code>float</code> containing the current compression quality
345      * setting. The initial value is <code>1.0F</code>.
346      *
347      * <p> Subclasses that do not support compression may ignore this
348      * value.
349      */

350     protected float compressionQuality = 1.0F;
351
352     /**
353      * A <code>Locale</code> to be used to localize compression type
354      * names and quality descriptions, or <code>null</code> to use a
355      * default <code>Locale</code>. Subclasses must set the value
356      * manually.
357      */

358     protected Locale JavaDoc locale = null;
359
360     /**
361      * Constructs an empty <code>ImageWriteParam</code>. It is up to
362      * the subclass to set up the instance variables properly.
363      */

364     protected ImageWriteParam() {}
365
366     /**
367      * Constructs an <code>ImageWriteParam</code> set to use a
368      * given <code>Locale</code>.
369      *
370      * @param locale a <code>Locale</code> to be used to localize
371      * compression type names and quality descriptions, or
372      * <code>null</code>.
373      */

374     public ImageWriteParam(Locale JavaDoc locale) {
375         this.locale = locale;
376     }
377
378     // Return a deep copy of the array
379
private static Dimension JavaDoc[] clonePreferredTileSizes(Dimension JavaDoc[] sizes) {
380         if (sizes == null) {
381             return null;
382         }
383         Dimension JavaDoc[] temp = new Dimension JavaDoc[sizes.length];
384         for (int i = 0; i < sizes.length; i++) {
385             temp[i] = new Dimension JavaDoc(sizes[i]);
386         }
387         return temp;
388     }
389
390     /**
391      * Returns the currently set <code>Locale</code>, or
392      * <code>null</code> if only a default <code>Locale</code> is
393      * supported.
394      *
395      * @return the current <code>Locale</code>, or <code>null</code>.
396      */

397     public Locale JavaDoc getLocale() {
398         return locale;
399     }
400
401     /**
402      * Returns <code>true</code> if the writer can perform tiling
403      * while writing. If this method returns <code>false</code>, then
404      * <code>setTiling</code> will throw an
405      * <code>UnsupportedOperationException</code>.
406      *
407      * @return <code>true</code> if the writer supports tiling.
408      *
409      * @see #canOffsetTiles()
410      * @see #setTiling(int, int, int, int)
411      */

412     public boolean canWriteTiles() {
413         return canWriteTiles;
414     }
415
416     /**
417      * Returns <code>true</code> if the writer can perform tiling with
418      * non-zero grid offsets while writing. If this method returns
419      * <code>false</code>, then <code>setTiling</code> will throw an
420      * <code>UnsupportedOperationException</code> if the grid offset
421      * arguments are not both zero. If <code>canWriteTiles</code>
422      * returns <code>false</code>, this method will return
423      * <code>false</code> as well.
424      *
425      * @return <code>true</code> if the writer supports non-zero tile
426      * offsets.
427      *
428      * @see #canWriteTiles()
429      * @see #setTiling(int, int, int, int)
430      */

431     public boolean canOffsetTiles() {
432         return canOffsetTiles;
433     }
434
435     /**
436      * Determines whether the image will be tiled in the output
437      * stream and, if it will, how the tiling parameters will be
438      * determined. The modes are interpreted as follows:
439      *
440      * <ul>
441      *
442      * <li><code>MODE_DISABLED</code> - The image will not be tiled.
443      * <code>setTiling</code> will throw an
444      * <code>IllegalStateException</code>.
445      *
446      * <li><code>MODE_DEFAULT</code> - The image will be tiled using
447      * default parameters. <code>setTiling</code> will throw an
448      * <code>IllegalStateException</code>.
449      *
450      * <li><code>MODE_EXPLICIT</code> - The image will be tiled
451      * according to parameters given in the {@link #setTiling
452      * <code>setTiling</code>} method. Any previously set tiling
453      * parameters are discarded.
454      *
455      * <li><code>MODE_COPY_FROM_METADATA</code> - The image will
456      * conform to the metadata object passed in to a write.
457      * <code>setTiling</code> will throw an
458      * <code>IllegalStateException</code>.
459      *
460      * </ul>
461      *
462      * @param mode The mode to use for tiling.
463      *
464      * @exception UnsupportedOperationException if
465      * <code>canWriteTiles</code> returns <code>false</code>.
466      * @exception IllegalArgumentException if <code>mode</code> is not
467      * one of the modes listed above.
468      *
469      * @see #setTiling
470      * @see #getTilingMode
471      */

472     public void setTilingMode(int mode) {
473         if (canWriteTiles() == false) {
474             throw new UnsupportedOperationException JavaDoc("Tiling not supported!");
475         }
476         if (mode < MODE_DISABLED || mode > MAX_MODE) {
477             throw new IllegalArgumentException JavaDoc("Illegal value for mode!");
478         }
479         this.tilingMode = mode;
480         if (mode == MODE_EXPLICIT) {
481             unsetTiling();
482         }
483     }
484
485     /**
486      * Returns the current tiling mode, if tiling is supported.
487      * Otherwise throws an <code>UnsupportedOperationException</code>.
488      *
489      * @return the current tiling mode.
490      *
491      * @exception UnsupportedOperationException if
492      * <code>canWriteTiles</code> returns <code>false</code>.
493      *
494      * @see #setTilingMode
495      */

496     public int getTilingMode() {
497         if (!canWriteTiles()) {
498             throw new UnsupportedOperationException JavaDoc("Tiling not supported");
499         }
500         return tilingMode;
501     }
502
503     /**
504      * Returns an array of <code>Dimension</code>s indicating the
505      * legal size ranges for tiles as they will be encoded in the
506      * output file or stream. The returned array is a copy.
507      *
508      * <p> The information is returned as a set of pairs; the first
509      * element of a pair contains an (inclusive) minimum width and
510      * height, and the second element contains an (inclusive) maximum
511      * width and height. Together, each pair defines a valid range of
512      * sizes. To specify a fixed size, use the same width and height
513      * for both elements. To specify an arbitrary range, a value of
514      * <code>null</code> is used in place of an actual array of
515      * <code>Dimension</code>s.
516      *
517      * <p> If no array is specified on the constructor, but tiling is
518      * allowed, then this method returns <code>null</code>.
519      *
520      * @exception UnsupportedOperationException if the plug-in does
521      * not support tiling.
522      *
523      * @return an array of <code>Dimension</code>s with an even length
524      * of at least two, or <code>null</code>.
525      */

526     public Dimension JavaDoc[] getPreferredTileSizes() {
527         if (!canWriteTiles()) {
528             throw new UnsupportedOperationException JavaDoc("Tiling not supported");
529         }
530         return clonePreferredTileSizes(preferredTileSizes);
531     }
532
533     /**
534      * Specifies that the image should be tiled in the output stream.
535      * The <code>tileWidth</code> and <code>tileHeight</code>
536      * parameters specify the width and height of the tiles in the
537      * file. If the tile width or height is greater than the width or
538      * height of the image, the image is not tiled in that dimension.
539      *
540      * <p> If <code>canOffsetTiles</code> returns <code>false</code>,
541      * then the <code>tileGridXOffset</code> and
542      * <code>tileGridYOffset</code> parameters must be zero.
543      *
544      * @param tileWidth the width of each tile.
545      * @param tileHeight the height of each tile.
546      * @param tileGridXOffset the horizontal offset of the tile grid.
547      * @param tileGridYOffset the vertical offset of the tile grid.
548      *
549      * @exception UnsupportedOperationException if the plug-in does not
550      * support tiling.
551      * @exception IllegalStateException if the tiling mode is not
552      * <code>MODE_EXPLICIT</code>.
553      * @exception UnsupportedOperationException if the plug-in does not
554      * support grid offsets, and the grid offsets are not both zero.
555      * @exception IllegalArgumentException if the tile size is not
556      * within one of the allowable ranges returned by
557      * <code>getPreferredTileSizes</code>.
558      * @exception IllegalArgumentException if <code>tileWidth</code>
559      * or <code>tileHeight</code> is less than or equal to 0.
560      *
561      * @see #canWriteTiles
562      * @see #canOffsetTiles
563      * @see #getTileWidth()
564      * @see #getTileHeight()
565      * @see #getTileGridXOffset()
566      * @see #getTileGridYOffset()
567      */

568     public void setTiling(int tileWidth,
569                           int tileHeight,
570                           int tileGridXOffset,
571                           int tileGridYOffset) {
572         if (!canWriteTiles()) {
573             throw new UnsupportedOperationException JavaDoc("Tiling not supported!");
574         }
575         if (getTilingMode() != MODE_EXPLICIT) {
576             throw new IllegalStateException JavaDoc("Tiling mode not MODE_EXPLICIT!");
577         }
578         if (tileWidth <= 0 || tileHeight <= 0) {
579             throw new IllegalArgumentException JavaDoc
580                 ("tile dimensions are non-positive!");
581         }
582         boolean tilesOffset = (tileGridXOffset != 0) || (tileGridYOffset != 0);
583         if (!canOffsetTiles() && tilesOffset) {
584             throw new UnsupportedOperationException JavaDoc("Can't offset tiles!");
585         }
586         if (preferredTileSizes != null) {
587             boolean ok = true;
588             for (int i = 0; i < preferredTileSizes.length; i += 2) {
589                 Dimension JavaDoc min = preferredTileSizes[i];
590                 Dimension JavaDoc max = preferredTileSizes[i+1];
591                 if ((tileWidth < min.width) ||
592                     (tileWidth > max.width) ||
593                     (tileHeight < min.height) ||
594                     (tileHeight > max.height)) {
595                     ok = false;
596                     break;
597                 }
598             }
599             if (!ok) {
600                 throw new IllegalArgumentException JavaDoc("Illegal tile size!");
601             }
602         }
603         
604         this.tilingSet = true;
605         this.tileWidth = tileWidth;
606         this.tileHeight = tileHeight;
607         this.tileGridXOffset = tileGridXOffset;
608         this.tileGridYOffset = tileGridYOffset;
609     }
610
611     /**
612      * Removes any previous tile grid parameters specified by calls to
613      * <code>setTiling</code>.
614      *
615      * <p> The default implementation sets the instance variables
616      * <code>tileWidth</code>, <code>tileHeight</code>,
617      * <code>tileGridXOffset</code>, and
618      * <code>tileGridYOffset</code> to <code>0</code>.
619      *
620      * @exception UnsupportedOperationException if the plug-in does not
621      * support tiling.
622      * @exception IllegalStateException if the tiling mode is not
623      * <code>MODE_EXPLICIT</code>.
624      *
625      * @see #setTiling(int, int, int, int)
626      */

627     public void unsetTiling() {
628         if (!canWriteTiles()) {
629             throw new UnsupportedOperationException JavaDoc("Tiling not supported!");
630         }
631         if (getTilingMode() != MODE_EXPLICIT) {
632             throw new IllegalStateException JavaDoc("Tiling mode not MODE_EXPLICIT!");
633         }
634         this.tilingSet = false;
635         this.tileWidth = 0;
636         this.tileHeight = 0;
637         this.tileGridXOffset = 0;
638         this.tileGridYOffset = 0;
639     }
640
641     /**
642      * Returns the width of each tile in an image as it will be
643      * written to the output stream. If tiling parameters have not
644      * been set, an <code>IllegalStateException</code> is thrown.
645      *
646      * @return the tile width to be used for encoding.
647      *
648      * @exception UnsupportedOperationException if the plug-in does not
649      * support tiling.
650      * @exception IllegalStateException if the tiling mode is not
651      * <code>MODE_EXPLICIT</code>.
652      * @exception IllegalStateException if the tiling parameters have
653      * not been set.
654      *
655      * @see #setTiling(int, int, int, int)
656      * @see #getTileHeight()
657      */

658     public int getTileWidth() {
659         if (!canWriteTiles()) {
660             throw new UnsupportedOperationException JavaDoc("Tiling not supported!");
661         }
662         if (getTilingMode() != MODE_EXPLICIT) {
663             throw new IllegalStateException JavaDoc("Tiling mode not MODE_EXPLICIT!");
664         }
665         if (!tilingSet) {
666             throw new IllegalStateException JavaDoc("Tiling parameters not set!");
667         }
668         return tileWidth;
669     }
670
671     /**
672      * Returns the height of each tile in an image as it will be written to
673      * the output stream. If tiling parameters have not
674      * been set, an <code>IllegalStateException</code> is thrown.
675      *
676      * @return the tile height to be used for encoding.
677      *
678      * @exception UnsupportedOperationException if the plug-in does not
679      * support tiling.
680      * @exception IllegalStateException if the tiling mode is not
681      * <code>MODE_EXPLICIT</code>.
682      * @exception IllegalStateException if the tiling parameters have
683      * not been set.
684      *
685      * @see #setTiling(int, int, int, int)
686      * @see #getTileWidth()
687      */

688     public int getTileHeight() {
689         if (!canWriteTiles()) {
690             throw new UnsupportedOperationException JavaDoc("Tiling not supported!");
691         }
692         if (getTilingMode() != MODE_EXPLICIT) {
693             throw new IllegalStateException JavaDoc("Tiling mode not MODE_EXPLICIT!");
694         }
695         if (!tilingSet) {
696             throw new IllegalStateException JavaDoc("Tiling parameters not set!");
697         }
698         return tileHeight;
699     }
700
701     /**
702      * Returns the horizontal tile grid offset of an image as it will
703      * be written to the output stream. If tiling parameters have not
704      * been set, an <code>IllegalStateException</code> is thrown.
705      *
706      * @return the tile grid X offset to be used for encoding.
707      *
708      * @exception UnsupportedOperationException if the plug-in does not
709      * support tiling.
710      * @exception IllegalStateException if the tiling mode is not
711      * <code>MODE_EXPLICIT</code>.
712      * @exception IllegalStateException if the tiling parameters have
713      * not been set.
714      *
715      * @see #setTiling(int, int, int, int)
716      * @see #getTileGridYOffset()
717      */

718     public int getTileGridXOffset() {
719         if (!canWriteTiles()) {
720             throw new UnsupportedOperationException JavaDoc("Tiling not supported!");
721         }
722         if (getTilingMode() != MODE_EXPLICIT) {
723             throw new IllegalStateException JavaDoc("Tiling mode not MODE_EXPLICIT!");
724         }
725         if (!tilingSet) {
726             throw new IllegalStateException JavaDoc("Tiling parameters not set!");
727         }
728         return tileGridXOffset;
729     }
730
731     /**
732      * Returns the vertical tile grid offset of an image as it will
733      * be written to the output stream. If tiling parameters have not
734      * been set, an <code>IllegalStateException</code> is thrown.
735      *
736      * @return the tile grid Y offset to be used for encoding.
737      *
738      * @exception UnsupportedOperationException if the plug-in does not
739      * support tiling.
740      * @exception IllegalStateException if the tiling mode is not
741      * <code>MODE_EXPLICIT</code>.
742      * @exception IllegalStateException if the tiling parameters have
743      * not been set.
744      *
745      * @see #setTiling(int, int, int, int)
746      * @see #getTileGridXOffset()
747      */

748     public int getTileGridYOffset() {
749         if (!canWriteTiles()) {
750             throw new UnsupportedOperationException JavaDoc("Tiling not supported!");
751         }
752         if (getTilingMode() != MODE_EXPLICIT) {
753             throw new IllegalStateException JavaDoc("Tiling mode not MODE_EXPLICIT!");
754         }
755         if (!tilingSet) {
756             throw new IllegalStateException JavaDoc("Tiling parameters not set!");
757         }
758         return tileGridYOffset;
759     }
760
761     /**
762      * Returns <code>true</code> if the writer can write out images
763      * as a series of passes of progressively increasing quality.
764      *
765      * @return <code>true</code> if the writer supports progressive
766      * encoding.
767      *
768      * @see #setProgressiveMode
769      * @see #getProgressiveMode
770      */

771     public boolean canWriteProgressive() {
772         return canWriteProgressive;
773     }
774
775     /**
776      * Specifies that the writer is to write the image out in a
777      * progressive mode such that the stream will contain a series of
778      * scans of increasing quality. If progressive encoding is not
779      * supported, an <code>UnsupportedOperationException</code> will
780      * be thrown.
781      *
782      * <p> The mode argument determines how
783      * the progression parameters are chosen, and must be either
784      * <code>MODE_DISABLED</code>,
785      * <code>MODE_COPY_FROM_METADATA</code>, or
786      * <code>MODE_DEFAULT</code>. Otherwise an
787      * <code>IllegalArgumentException</code> is thrown.
788      *
789      * <p> The modes are interpreted as follows:
790      *
791      * <ul>
792      * <li><code>MODE_DISABLED</code> - No progression. Use this to
793      * turn off progession.
794      *
795      * <li><code>MODE_COPY_FROM_METADATA</code> - The output image
796      * will use whatever progression parameters are found in the
797      * metadata objects passed into the writer.
798      *
799      * <li><code>MODE_DEFAULT</code> - The image will be written
800      * progressively, with parameters chosen by the writer.
801      * </ul>
802      *
803      * <p> The default is <code>MODE_COPY_FROM_METADATA</code>.
804      *
805      * @param mode The mode for setting progression in the output
806      * stream.
807      *
808      * @exception UnsupportedOperationException if the writer does not
809      * support progressive encoding.
810      * @exception IllegalArgumentException if <code>mode</code> is not
811      * one of the modes listed above.
812      *
813      * @see #getProgressiveMode
814      */

815     public void setProgressiveMode(int mode) {
816         if (!canWriteProgressive()) {
817             throw new UnsupportedOperationException JavaDoc(
818                 "Progressive output not supported");
819         }
820         if (mode < MODE_DISABLED || mode > MAX_MODE) {
821             throw new IllegalArgumentException JavaDoc("Illegal value for mode!");
822         }
823         if (mode == MODE_EXPLICIT) {
824             throw new IllegalArgumentException JavaDoc(
825                 "MODE_EXPLICIT not supported for progressive output");
826         }
827         this.progressiveMode = mode;
828     }
829     
830     /**
831      * Returns the current mode for writing the stream in a
832      * progressive manner.
833      *
834      * @return the current mode for progressive encoding.
835      *
836      * @exception UnsupportedOperationException if the writer does not
837      * support progressive encoding.
838      *
839      * @see #setProgressiveMode
840      */

841     public int getProgressiveMode() {
842         if (!canWriteProgressive()) {
843             throw new UnsupportedOperationException JavaDoc
844                 ("Progressive output not supported");
845         }
846         return progressiveMode;
847     }
848
849     /**
850      * Returns <code>true</code> if this writer supports compression.
851      *
852      * @return <code>true</code> if the writer supports compression.
853      */

854     public boolean canWriteCompressed() {
855         return canWriteCompressed;
856     }
857
858     /**
859      * Specifies whether compression is to be performed, and if so how
860      * compression parameters are to be determined. The <code>mode</code>
861      * argument must be one of the four modes, interpreted as follows:
862      *
863      * <ul>
864      * <li><code>MODE_DISABLED</code> - Do not compress. This may
865      * not be permitted by some writers, such as JPEG, which do not
866      * normally offer uncompressed output. The corresponding
867      * <code>set</code> and <code>get</code> methods will throw an
868      * <code>IllegalStateException</code>.
869      *
870      * <li><code>MODE_EXPLICIT</code> - Compress using the
871      * compression type and quality settings specified in this
872      * <code>ImageWriteParam</code>. Any previously set compression
873      * parameters are discarded.
874      *
875      * <li><code>MODE_COPY_FROM_METADATA</code> - Use whatever
876      * compression parameters are specified in metadata objects
877      * passed in to the writer.
878      *
879      * <li><code>MODE_DEFAULT</code> - Use default compression
880      * parameters.
881      * </ul>
882      *
883      * <p> The default is <code>MODE_COPY_FROM_METADATA</code>.
884      *
885      * @param mode The mode for setting compression in the output
886      * stream.
887      *
888      * @exception UnsupportedOperationException if the writer does not
889      * support compression, or does not support the requested mode.
890      * @exception IllegalArgumentException if <code>mode</code> is not
891      * one of the modes listed above.
892      *
893      * @see #getCompressionMode
894      */

895     public void setCompressionMode(int mode) {
896         if (!canWriteCompressed()) {
897             throw new UnsupportedOperationException JavaDoc(
898                 "Compression not supported.");
899         }
900         if (mode < MODE_DISABLED || mode > MAX_MODE) {
901             throw new IllegalArgumentException JavaDoc("Illegal value for mode!");
902         }
903         this.compressionMode = mode;
904         if (mode == MODE_EXPLICIT) {
905             unsetCompression();
906         }
907     }
908
909     /**
910      * Returns the current compression mode, if compression is
911      * supported.
912      *
913      * @return the current compression mode.
914      *
915      * @exception UnsupportedOperationException if the writer does not
916      * support compression.
917      *
918      * @see #setCompressionMode
919      */

920     public int getCompressionMode() {
921         if (!canWriteCompressed()) {
922             throw new UnsupportedOperationException JavaDoc(
923                 "Compression not supported.");
924         }
925         return compressionMode;
926     }
927
928     /**
929      * Returns a list of available compression types, as an array or
930      * <code>String</code>s, or <code>null</code> if a compression
931      * type may not be chosen using these interfaces. The array
932      * returned is a copy.
933      *
934      * <p> If the writer only offers a single, mandatory form of
935      * compression, it is not necessary to provide any named
936      * compression types. Named compression types should only be
937      * used where the user is able to make a meaningful choice
938      * between different schemes.
939      *
940      * <p> The default implementation checks if compression is
941      * supported and throws an
942      * <code>UnsupportedOperationException</code> if not. Otherwise,
943      * it returns a clone of the <code>compressionTypes</code>
944      * instance variable if it is non-<code>null</code>, or else
945      * returns <code>null</code>.
946      *
947      * @return an array of <code>String</code>s containing the
948      * (non-localized) names of available compression types, or
949      * <code>null</code>.
950      *
951      * @exception UnsupportedOperationException if the writer does not
952      * support compression.
953      */

954     public String JavaDoc[] getCompressionTypes() {
955         if (!canWriteCompressed()) {
956             throw new UnsupportedOperationException JavaDoc(
957                 "Compression not supported");
958         }
959         if (compressionTypes == null) {
960             return null;
961         }
962         return (String JavaDoc[])compressionTypes.clone();
963     }
964
965     /**
966      * Sets the compression type to one of the values indicated by
967      * <code>getCompressionTypes</code>. If a value of
968      * <code>null</code> is passed in, any previous setting is
969      * removed.
970      *
971      * <p> The default implementation checks whether compression is
972      * supported and the compression mode is
973      * <code>MODE_EXPLICIT</code>. If so, it calls
974      * <code>getCompressionTypes</code> and checks if
975      * <code>compressionType</code> is one of the legal values. If it
976      * is, the <code>compressionType</code> instance variable is set.
977      * If <code>compressionType</code> is <code>null</code>, the
978      * instance variable is set without performing any checking.
979      *
980      * @param compressionType one of the <code>String</code>s returned
981      * by <code>getCompressionTypes</code>, or <code>null</code> to
982      * remove any previous setting.
983      *
984      * @exception UnsupportedOperationException if the writer does not
985      * support compression.
986      * @exception IllegalStateException if the compression mode is not
987      * <code>MODE_EXPLICIT</code>.
988      * @exception UnsupportedOperationException if there are no
989      * settable compression types.
990      * @exception IllegalArgumentException if
991      * <code>compressionType</code> is non-<code>null</code> but is not
992      * one of the values returned by <code>getCompressionTypes</code>.
993      *
994      * @see #getCompressionTypes
995      * @see #getCompressionType
996      * @see #unsetCompression
997      */

998     public void setCompressionType(String JavaDoc compressionType) {
999         if (!canWriteCompressed()) {
1000            throw new UnsupportedOperationException JavaDoc(
1001                "Compression not supported");
1002        }
1003        if (getCompressionMode() != MODE_EXPLICIT) {
1004            throw new IllegalStateException JavaDoc
1005                ("Compression mode not MODE_EXPLICIT!");
1006        }
1007        String JavaDoc[] legalTypes = getCompressionTypes();
1008        if (legalTypes == null) {
1009            throw new UnsupportedOperationException JavaDoc(
1010                "No settable compression types");
1011        }
1012        if (compressionType != null) {
1013            boolean found = false;
1014            if (legalTypes != null) {
1015                for (int i = 0; i < legalTypes.length; i++) {
1016                    if (compressionType.equals(legalTypes[i])) {
1017                        found = true;
1018                        break;
1019                    }
1020                }
1021            }
1022            if (!found) {
1023                throw new IllegalArgumentException JavaDoc("Unknown compression type!");
1024            }
1025        }
1026        this.compressionType = compressionType;
1027    }
1028
1029    /**
1030     * Returns the currently set compression type, or
1031     * <code>null</code> if none has been set. The type is returned
1032     * as a <code>String</code> from among those returned by
1033     * <code>getCompressionTypes</code>.
1034     * If no compression type has been set, <code>null</code> is
1035     * returned.
1036     *
1037     * <p> The default implementation checks whether compression is
1038     * supported and the compression mode is
1039     * <code>MODE_EXPLICIT</code>. If so, it returns the value of the
1040     * <code>compressionType</code> instance variable.
1041     *
1042     * @return the current compression type as a <code>String</code>,
1043     * or <code>null</code> if no type is set.
1044     *
1045     * @exception UnsupportedOperationException if the writer does not
1046     * support compression.
1047     * @exception IllegalStateException if the compression mode is not
1048     * <code>MODE_EXPLICIT</code>.
1049     *
1050     * @see #setCompressionType
1051     */

1052    public String JavaDoc getCompressionType() {
1053        if (!canWriteCompressed()) {
1054            throw new UnsupportedOperationException JavaDoc(
1055                "Compression not supported.");
1056        }
1057        if (getCompressionMode() != MODE_EXPLICIT) {
1058            throw new IllegalStateException JavaDoc
1059                ("Compression mode not MODE_EXPLICIT!");
1060        }
1061        return compressionType;
1062    }
1063
1064    /**
1065     * Removes any previous compression type and quality settings.
1066     *
1067     * <p> The default implementation sets the instance variable
1068     * <code>compressionType</code> to <code>null</code>, and the
1069     * instance variable <code>compressionQuality</code> to
1070     * <code>1.0F</code>.
1071     *
1072     * @exception UnsupportedOperationException if the plug-in does not
1073     * support compression.
1074     * @exception IllegalStateException if the compression mode is not
1075     * <code>MODE_EXPLICIT</code>.
1076     *
1077     * @see #setCompressionType
1078     * @see #setCompressionQuality
1079     */

1080    public void unsetCompression() {
1081        if (!canWriteCompressed()) {
1082            throw new UnsupportedOperationException JavaDoc(
1083                "Compression not supported");
1084        }
1085        if (getCompressionMode() != MODE_EXPLICIT) {
1086            throw new IllegalStateException JavaDoc
1087                ("Compression mode not MODE_EXPLICIT!");
1088        }
1089        this.compressionType = null;
1090        this.compressionQuality = 1.0F;
1091    }
1092
1093    /**
1094     * Returns a localized version of the name of the current
1095     * compression type, using the <code>Locale</code> returned by
1096     * <code>getLocale</code>.
1097     *
1098     * <p> The default implementation checks whether compression is
1099     * supported and the compression mode is
1100     * <code>MODE_EXPLICIT</code>. If so, if
1101     * <code>compressionType</code> is <code>non-null</code> the value
1102     * of <code>getCompressionType</code> is returned as a
1103     * convenience.
1104     *
1105     * @return a <code>String</code> containing a localized version of
1106     * the name of the current compression type.
1107     *
1108     * @exception UnsupportedOperationException if the writer does not
1109     * support compression.
1110     * @exception IllegalStateException if the compression mode is not
1111     * <code>MODE_EXPLICIT</code>.
1112     * @exception IllegalStateException if no compression type is set.
1113     */

1114    public String JavaDoc getLocalizedCompressionTypeName() {
1115        if (!canWriteCompressed()) {
1116            throw new UnsupportedOperationException JavaDoc(
1117                "Compression not supported.");
1118        }
1119        if (getCompressionMode() != MODE_EXPLICIT) {
1120            throw new IllegalStateException JavaDoc
1121                ("Compression mode not MODE_EXPLICIT!");
1122        }
1123        if (getCompressionType() == null) {
1124            throw new IllegalStateException JavaDoc("No compression type set!");
1125        }
1126        return getCompressionType();
1127    }
1128
1129    /**
1130     * Returns <code>true</code> if the current compression type
1131     * provides lossless compression. If a plug-in provides only
1132     * one mandatory compression type, then this method may be
1133     * called without calling <code>setCompressionType</code> first.
1134     *
1135     * <p> If there are multiple compression types but none has
1136     * been set, an <code>IllegalStateException</code> is thrown.
1137     *
1138     * <p> The default implementation checks whether compression is
1139     * supported and the compression mode is
1140     * <code>MODE_EXPLICIT</code>. If so, if
1141     * <code>getCompressionTypes()</code> is <code>null</code> or
1142     * <code>getCompressionType()</code> is non-<code>null</code>
1143     * <code>true</code> is returned as a convenience.
1144     *
1145     * @return <code>true</code> if the current compression type is
1146     * lossless.
1147     *
1148     * @exception UnsupportedOperationException if the writer does not
1149     * support compression.
1150     * @exception IllegalStateException if the compression mode is not
1151     * <code>MODE_EXPLICIT</code>.
1152     * @exception IllegalStateException if the set of legal
1153     * compression types is non-<code>null</code> and the current
1154     * compression type is <code>null</code>.
1155     */

1156    public boolean isCompressionLossless() {
1157        if (!canWriteCompressed()) {
1158            throw new UnsupportedOperationException JavaDoc(
1159                "Compression not supported");
1160        }
1161        if (getCompressionMode() != MODE_EXPLICIT) {
1162            throw new IllegalStateException JavaDoc
1163                ("Compression mode not MODE_EXPLICIT!");
1164        }
1165        if ((getCompressionTypes() != null) &&
1166            (getCompressionType() == null)) {
1167            throw new IllegalStateException JavaDoc("No compression type set!");
1168        }
1169        return true;
1170    }
1171
1172    /**
1173     * Sets the compression quality to a value between <code>0</code>
1174     * and <code>1</code>. Only a single compression quality setting
1175     * is supported by default; writers can provide extended versions
1176     * of <code>ImageWriteParam</code> that offer more control. For
1177     * lossy compression schemes, the compression quality should
1178     * control the tradeoff between file size and image quality (for
1179     * example, by choosing quantization tables when writing JPEG
1180     * images). For lossless schemes, the compression quality may be
1181     * used to control the tradeoff between file size and time taken
1182     * to perform the compression (for example, by optimizing row
1183     * filters and setting the ZLIB compression level when writing
1184     * PNG images).
1185     *
1186     * <p> A compression quality setting of 0.0 is most generically
1187     * interpreted as "high compression is important," while a setting of
1188     * 1.0 is most generically interpreted as "high image quality is
1189     * important."
1190     *
1191     * <p> If there are multiple compression types but none has been
1192     * set, an <code>IllegalStateException</code> is thrown.
1193     *
1194     * <p> The default implementation checks that compression is
1195     * supported, and that the compression mode is
1196     * <code>MODE_EXPLICIT</code>. If so, if
1197     * <code>getCompressionTypes()</code> returns <code>null</code> or
1198     * <code>compressionType</code> is non-<code>null</code> it sets
1199     * the <code>compressionQuality</code> instance variable.
1200     *
1201     * @param quality a <code>float</code> between <code>0</code>and
1202     * <code>1</code> indicating the desired quality level.
1203     *
1204     * @exception UnsupportedOperationException if the writer does not
1205     * support compression.
1206     * @exception IllegalStateException if the compression mode is not
1207     * <code>MODE_EXPLICIT</code>.
1208     * @exception IllegalStateException if the set of legal
1209     * compression types is non-<code>null</code> and the current
1210     * compression type is <code>null</code>.
1211     * @exception IllegalArgumentException if <code>quality</code> is
1212     * not between <code>0</code>and <code>1</code>, inclusive.
1213     *
1214     * @see #getCompressionQuality
1215     */

1216    public void setCompressionQuality(float quality) {
1217        if (!canWriteCompressed()) {
1218            throw new UnsupportedOperationException JavaDoc(
1219                "Compression not supported");
1220        }
1221        if (getCompressionMode() != MODE_EXPLICIT) {
1222            throw new IllegalStateException JavaDoc
1223                ("Compression mode not MODE_EXPLICIT!");
1224        }
1225        if (getCompressionTypes() != null && getCompressionType() == null) {
1226            throw new IllegalStateException JavaDoc("No compression type set!");
1227        }
1228        if (quality < 0.0F || quality > 1.0F) {
1229            throw new IllegalArgumentException JavaDoc("Quality out-of-bounds!");
1230        }
1231        this.compressionQuality = quality;
1232    }
1233
1234    /**
1235     * Returns the current compression quality setting.
1236     *
1237     * <p> If there are multiple compression types but none has been
1238     * set, an <code>IllegalStateException</code> is thrown.
1239     *
1240     * <p> The default implementation checks that compression is
1241     * supported and that the compression mode is
1242     * <code>MODE_EXPLICIT</code>. If so, if
1243     * <code>getCompressionTypes()</code> is <code>null</code> or
1244     * <code>getCompressionType()</code> is non-<code>null</code>, it
1245     * returns the value of the <code>compressionQuality</code>
1246     * instance variable.
1247     *
1248     * @return the current compression quality setting.
1249     *
1250     * @exception UnsupportedOperationException if the writer does not
1251     * support compression.
1252     * @exception IllegalStateException if the compression mode is not
1253     * <code>MODE_EXPLICIT</code>.
1254     * @exception IllegalStateException if the set of legal
1255     * compression types is non-<code>null</code> and the current
1256     * compression type is <code>null</code>.
1257     *
1258     * @see #setCompressionQuality
1259     */

1260    public float getCompressionQuality() {
1261        if (!canWriteCompressed()) {
1262            throw new UnsupportedOperationException JavaDoc(
1263                "Compression not supported.");
1264        }
1265        if (getCompressionMode() != MODE_EXPLICIT) {
1266            throw new IllegalStateException JavaDoc
1267                ("Compression mode not MODE_EXPLICIT!");
1268        }
1269        if ((getCompressionTypes() != null) &&
1270            (getCompressionType() == null)) {
1271            throw new IllegalStateException JavaDoc("No compression type set!");
1272        }
1273        return compressionQuality;
1274    }
1275
1276
1277    /**
1278     * Returns a <code>float</code> indicating an estimate of the
1279     * number of bits of output data for each bit of input image data
1280     * at the given quality level. The value will typically lie
1281     * between <code>0</code> and <code>1</code>, with smaller values
1282     * indicating more compression. A special value of
1283     * <code>-1.0F</code> is used to indicate that no estimate is
1284     * available.
1285     *
1286     * <p> If there are multiple compression types but none has been set,
1287     * an <code>IllegalStateException</code> is thrown.
1288     *
1289     * <p> The default implementation checks that compression is
1290     * supported and the compression mode is
1291     * <code>MODE_EXPLICIT</code>. If so, if
1292     * <code>getCompressionTypes()</code> is <code>null</code> or
1293     * <code>getCompressionType()</code> is non-<code>null</code>, and
1294     * <code>quality</code> is within bounds, it returns
1295     * <code>-1.0</code>.
1296     *
1297     * @param quality the quality setting whose bit rate is to be
1298     * queried.
1299     *
1300     * @return an estimate of the compressed bit rate, or
1301     * <code>-1.0F</code> if no estimate is available.
1302     *
1303     * @exception UnsupportedOperationException if the writer does not
1304     * support compression.
1305     * @exception IllegalStateException if the compression mode is not
1306     * <code>MODE_EXPLICIT</code>.
1307     * @exception IllegalStateException if the set of legal
1308     * compression types is non-<code>null</code> and the current
1309     * compression type is <code>null</code>.
1310     * @exception IllegalArgumentException if <code>quality</code> is
1311     * not between <code>0</code>and <code>1</code>, inclusive.
1312     */

1313    public float getBitRate(float quality) {
1314        if (!canWriteCompressed()) {
1315            throw new UnsupportedOperationException JavaDoc(
1316                "Compression not supported.");
1317        }
1318        if (getCompressionMode() != MODE_EXPLICIT) {
1319            throw new IllegalStateException JavaDoc
1320                ("Compression mode not MODE_EXPLICIT!");
1321        }
1322        if ((getCompressionTypes() != null) &&
1323            (getCompressionType() == null)) {
1324            throw new IllegalStateException JavaDoc("No compression type set!");
1325        }
1326        if (quality < 0.0F || quality > 1.0F) {
1327            throw new IllegalArgumentException JavaDoc("Quality out-of-bounds!");
1328        }
1329        return -1.0F;
1330    }
1331
1332    /**
1333     * Returns an array of <code>String</code>s that may be used along
1334     * with <code>getCompressionQualityValues</code> as part of a user
1335     * interface for setting or displaying the compression quality
1336     * level. The <code>String</code> with index <code>i</code>
1337     * provides a description of the range of quality levels between
1338     * <code>getCompressionQualityValues[i]</code> and
1339     * <code>getCompressionQualityValues[i + 1]</code>. Note that the
1340     * length of the array returned from
1341     * <code>getCompressionQualityValues</code> will always be one
1342     * greater than that returned from
1343     * <code>getCompressionQualityDescriptions</code>.
1344     *
1345     * <p> As an example, the strings "Good", "Better", and "Best"
1346     * could be associated with the ranges <code>[0, .33)</code>,
1347     * <code>[.33, .66)</code>, and <code>[.66, 1.0]</code>. In this
1348     * case, <code>getCompressionQualityDescriptions</code> would
1349     * return <code>{ "Good", "Better", "Best" }</code> and
1350     * <code>getCompressionQualityValues</code> would return
1351     * <code>{ 0.0F, .33F, .66F, 1.0F }</code>.
1352     *
1353     * <p> If no descriptions are available, <code>null</code> is
1354     * returned. If <code>null</code> is returned from
1355     * <code>getCompressionQualityValues</code>, this method must also
1356     * return <code>null</code>.
1357     *
1358     * <p> The descriptions should be localized for the
1359     * <code>Locale</code> returned by <code>getLocale</code>, if it
1360     * is non-<code>null</code>.
1361     *
1362     * <p> If there are multiple compression types but none has been set,
1363     * an <code>IllegalStateException</code> is thrown.
1364     *
1365     * <p> The default implementation checks that compression is
1366     * supported and that the compression mode is
1367     * <code>MODE_EXPLICIT</code>. If so, if
1368     * <code>getCompressionTypes()</code> is <code>null</code> or
1369     * <code>getCompressionType()</code> is non-<code>null</code>, it
1370     * returns <code>null</code>.
1371     *
1372     * @return an array of <code>String</code>s containing localized
1373     * descriptions of the compression quality levels.
1374     *
1375     * @exception UnsupportedOperationException if the writer does not
1376     * support compression.
1377     * @exception IllegalStateException if the compression mode is not
1378     * <code>MODE_EXPLICIT</code>.
1379     * @exception IllegalStateException if the set of legal
1380     * compression types is non-<code>null</code> and the current
1381     * compression type is <code>null</code>.
1382     *
1383     * @see #getCompressionQualityValues
1384     */

1385    public String JavaDoc[] getCompressionQualityDescriptions() {
1386        if (!canWriteCompressed()) {
1387            throw new UnsupportedOperationException JavaDoc(
1388                "Compression not supported.");
1389        }
1390        if (getCompressionMode() != MODE_EXPLICIT) {
1391            throw new IllegalStateException JavaDoc
1392                ("Compression mode not MODE_EXPLICIT!");
1393        }
1394        if ((getCompressionTypes() != null) &&
1395            (getCompressionType() == null)) {
1396            throw new IllegalStateException JavaDoc("No compression type set!");
1397        }
1398        return null;
1399    }
1400
1401    /**
1402     * Returns an array of <code>float</code>s that may be used along
1403     * with <code>getCompressionQualityDescriptions</code> as part of a user
1404     * interface for setting or displaying the compression quality
1405     * level. See {@link #getCompressionQualityDescriptions
1406     * <code>getCompressionQualityDescriptions</code>} for more information.
1407     *
1408     * <p> If no descriptions are available, <code>null</code> is
1409     * returned. If <code>null</code> is returned from
1410     * <code>getCompressionQualityDescriptions</code>, this method
1411     * must also return <code>null</code>.
1412     *
1413     * <p> If there are multiple compression types but none has been set,
1414     * an <code>IllegalStateException</code> is thrown.
1415     *
1416     * <p> The default implementation checks that compression is
1417     * supported and that the compression mode is
1418     * <code>MODE_EXPLICIT</code>. If so, if
1419     * <code>getCompressionTypes()</code> is <code>null</code> or
1420     * <code>getCompressionType()</code> is non-<code>null</code>, it
1421     * returns <code>null</code>.
1422     *
1423     * @return an array of <code>float</code>s indicating the
1424     * boundaries between the compression quality levels as described
1425     * by the <code>String</code>s from
1426     * <code>getCompressionQualityDescriptions</code>.
1427     *
1428     * @exception UnsupportedOperationException if the writer does not
1429     * support compression.
1430     * @exception IllegalStateException if the compression mode is not
1431     * <code>MODE_EXPLICIT</code>.
1432     * @exception IllegalStateException if the set of legal
1433     * compression types is non-<code>null</code> and the current
1434     * compression type is <code>null</code>.
1435     *
1436     * @see #getCompressionQualityDescriptions
1437     */

1438    public float[] getCompressionQualityValues() {
1439        if (!canWriteCompressed()) {
1440            throw new UnsupportedOperationException JavaDoc(
1441                "Compression not supported.");
1442        }
1443        if (getCompressionMode() != MODE_EXPLICIT) {
1444            throw new IllegalStateException JavaDoc
1445                ("Compression mode not MODE_EXPLICIT!");
1446        }
1447        if ((getCompressionTypes() != null) &&
1448            (getCompressionType() == null)) {
1449            throw new IllegalStateException JavaDoc("No compression type set!");
1450        }
1451        return null;
1452    }
1453}
1454
Popular Tags