History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/imageio/ImageWriteParam.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/imageio/ImageWriteParam.java+1471−0
@@ -0,0 +1,1471 @@
1+/*
2+ * Copyright (c) 2000, 2007, 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.util.Locale;
30+
31+/**
32+ * A class describing how a stream is to be encoded. Instances of
33+ * this class or its subclasses are used to supply prescriptive
34+ * "how-to" information to instances of <code>ImageWriter</code>.
35+ *
36+ * <p> A plug-in for a specific image format may define a subclass of
37+ * this class, and return objects of that class from the
38+ * <code>getDefaultWriteParam</code> method of its
39+ * <code>ImageWriter</code> implementation. For example, the built-in
40+ * JPEG writer plug-in will return instances of
41+ * <code>javax.imageio.plugins.jpeg.JPEGImageWriteParam</code>.
42+ *
43+ * <p> The region of the image to be written is determined by first
44+ * intersecting the actual bounds of the image with the rectangle
45+ * specified by <code>IIOParam.setSourceRegion</code>, if any. If the
46+ * resulting rectangle has a width or height of zero, the writer will
47+ * throw an <code>IIOException</code>. If the intersection is
48+ * non-empty, writing will commence with the first subsampled pixel
49+ * and include additional pixels within the intersected bounds
50+ * according to the horizontal and vertical subsampling factors
51+ * specified by {@link IIOParam#setSourceSubsampling
52+ * <code>IIOParam.setSourceSubsampling</code>}.
53+ *
54+ * <p> Individual features such as tiling, progressive encoding, and
55+ * compression may be set in one of four modes.
56+ * <code>MODE_DISABLED</code> disables the features;
57+ * <code>MODE_DEFAULT</code> enables the feature with
58+ * writer-controlled parameter values; <code>MODE_EXPLICIT</code>
59+ * enables the feature and allows the use of a <code>set</code> method
60+ * to provide additional parameters; and
61+ * <code>MODE_COPY_FROM_METADATA</code> copies relevant parameter
62+ * values from the stream and image metadata objects passed to the
63+ * writer. The default for all features is
64+ * <code>MODE_COPY_FROM_METADATA</code>. Non-standard features
65+ * supplied in subclasses are encouraged, but not required to use a
66+ * similar scheme.
67+ *
68+ * <p> Plug-in writers may extend the functionality of
69+ * <code>ImageWriteParam</code> by providing a subclass that implements
70+ * additional, plug-in specific interfaces. It is up to the plug-in
71+ * to document what interfaces are available and how they are to be
72+ * used. Writers will silently ignore any extended features of an
73+ * <code>ImageWriteParam</code> subclass of which they are not aware.
74+ * Also, they may ignore any optional features that they normally
75+ * disable when creating their own <code>ImageWriteParam</code>
76+ * instances via <code>getDefaultWriteParam</code>.
77+ *
78+ * <p> Note that unless a query method exists for a capability, it must
79+ * be supported by all <code>ImageWriter</code> implementations
80+ * (<i>e.g.</i> progressive encoding is optional, but subsampling must be
81+ * supported).
82+ *
83+ *
84+ * @see ImageReadParam
85+ */
86+public class ImageWriteParam extends IIOParam {
87+
88+ /**
89+ * A constant value that may be passed into methods such as
90+ * <code>setTilingMode</code>, <code>setProgressiveMode</code>,
91+ * and <code>setCompressionMode</code> to disable a feature for
92+ * future writes. That is, when this mode is set the stream will
93+ * <b>not</b> be tiled, progressive, or compressed, and the
94+ * relevant accessor methods will throw an
95+ * <code>IllegalStateException</code>.
96+ *
97+ * @see #MODE_EXPLICIT
98+ * @see #MODE_COPY_FROM_METADATA
99+ * @see #MODE_DEFAULT
100+ * @see #setProgressiveMode
101+ * @see #getProgressiveMode
102+ * @see #setTilingMode
103+ * @see #getTilingMode
104+ * @see #setCompressionMode
105+ * @see #getCompressionMode
106+ */
107+ public static final int MODE_DISABLED = 0;
108+
109+ /**
110+ * A constant value that may be passed into methods such as
111+ * <code>setTilingMode</code>,
112+ * <code>setProgressiveMode</code>, and
113+ * <code>setCompressionMode</code> to enable that feature for
114+ * future writes. That is, when this mode is enabled the stream
115+ * will be tiled, progressive, or compressed according to a
116+ * sensible default chosen internally by the writer in a plug-in
117+ * dependent way, and the relevant accessor methods will
118+ * throw an <code>IllegalStateException</code>.
119+ *
120+ * @see #MODE_DISABLED
121+ * @see #MODE_EXPLICIT
122+ * @see #MODE_COPY_FROM_METADATA
123+ * @see #setProgressiveMode
124+ * @see #getProgressiveMode
125+ * @see #setTilingMode
126+ * @see #getTilingMode
127+ * @see #setCompressionMode
128+ * @see #getCompressionMode
129+ */
130+ public static final int MODE_DEFAULT = 1;
131+
132+ /**
133+ * A constant value that may be passed into methods such as
134+ * <code>setTilingMode</code> or <code>setCompressionMode</code>
135+ * to enable a feature for future writes. That is, when this mode
136+ * is set the stream will be tiled or compressed according to
137+ * additional information supplied to the corresponding
138+ * <code>set</code> methods in this class and retrievable from the
139+ * corresponding <code>get</code> methods. Note that this mode is
140+ * not supported for progressive output.
141+ *
142+ * @see #MODE_DISABLED
143+ * @see #MODE_COPY_FROM_METADATA
144+ * @see #MODE_DEFAULT
145+ * @see #setProgressiveMode
146+ * @see #getProgressiveMode
147+ * @see #setTilingMode
148+ * @see #getTilingMode
149+ * @see #setCompressionMode
150+ * @see #getCompressionMode
151+ */
152+ public static final int MODE_EXPLICIT = 2;
153+
154+ /**
155+ * A constant value that may be passed into methods such as
156+ * <code>setTilingMode</code>, <code>setProgressiveMode</code>, or
157+ * <code>setCompressionMode</code> to enable that feature for
158+ * future writes. That is, when this mode is enabled the stream
159+ * will be tiled, progressive, or compressed based on the contents
160+ * of stream and/or image metadata passed into the write
161+ * operation, and any relevant accessor methods will throw an
162+ * <code>IllegalStateException</code>.
163+ *
164+ * <p> This is the default mode for all features, so that a read
165+ * including metadata followed by a write including metadata will
166+ * preserve as much information as possible.
167+ *
168+ * @see #MODE_DISABLED
169+ * @see #MODE_EXPLICIT
170+ * @see #MODE_DEFAULT
171+ * @see #setProgressiveMode
172+ * @see #getProgressiveMode
173+ * @see #setTilingMode
174+ * @see #getTilingMode
175+ * @see #setCompressionMode
176+ * @see #getCompressionMode
177+ */
178+ public static final int MODE_COPY_FROM_METADATA = 3;
179+
180+ // If more modes are added, this should be updated.
181+ private static final int MAX_MODE = MODE_COPY_FROM_METADATA;
182+
183+ /**
184+ * A <code>boolean</code> that is <code>true</code> if this
185+ * <code>ImageWriteParam</code> allows tile width and tile height
186+ * parameters to be set. By default, the value is
187+ * <code>false</code>. Subclasses must set the value manually.
188+ *
189+ * <p> Subclasses that do not support writing tiles should ensure
190+ * that this value is set to <code>false</code>.
191+ */
192+ protected boolean canWriteTiles = false;
193+
194+ /**
195+ * The mode controlling tiling settings, which Must be
196+ * set to one of the four <code>MODE_*</code> values. The default
197+ * is <code>MODE_COPY_FROM_METADATA</code>.
198+ *
199+ * <p> Subclasses that do not writing tiles may ignore this value.
200+ *
201+ * @see #MODE_DISABLED
202+ * @see #MODE_EXPLICIT
203+ * @see #MODE_COPY_FROM_METADATA
204+ * @see #MODE_DEFAULT
205+ * @see #setTilingMode
206+ * @see #getTilingMode
207+ */
208+ protected int tilingMode = MODE_COPY_FROM_METADATA;
209+
210+ /**
211+ * An array of preferred tile size range pairs. The default value
212+ * is <code>null</code>, which indicates that there are no
213+ * preferred sizes. If the value is non-<code>null</code>, it
214+ * must have an even length of at least two.
215+ *
216+ * <p> Subclasses that do not support writing tiles may ignore
217+ * this value.
218+ *
219+ * @see #getPreferredTileSizes
220+ */
221+ protected Dimension[] preferredTileSizes = null;
222+
223+ /**
224+ * A <code>boolean</code> that is <code>true</code> if tiling
225+ * parameters have been specified.
226+ *
227+ * <p> Subclasses that do not support writing tiles may ignore
228+ * this value.
229+ */
230+ protected boolean tilingSet = false;
231+
232+ /**
233+ * The width of each tile if tiling has been set, or 0 otherwise.
234+ *
235+ * <p> Subclasses that do not support tiling may ignore this
236+ * value.
237+ */
238+ protected int tileWidth = 0;
239+
240+ /**
241+ * The height of each tile if tiling has been set, or 0 otherwise.
242+ * The initial value is <code>0</code>.
243+ *
244+ * <p> Subclasses that do not support tiling may ignore this
245+ * value.
246+ */
247+ protected int tileHeight = 0;
248+
249+ /**
250+ * A <code>boolean</code> that is <code>true</code> if this
251+ * <code>ImageWriteParam</code> allows tiling grid offset
252+ * parameters to be set. By default, the value is
253+ * <code>false</code>. Subclasses must set the value manually.
254+ *
255+ * <p> Subclasses that do not support writing tiles, or that
256+ * supprt writing but not offsetting tiles must ensure that this
257+ * value is set to <code>false</code>.
258+ */
259+ protected boolean canOffsetTiles = false;
260+
261+ /**
262+ * The amount by which the tile grid origin should be offset
263+ * horizontally from the image origin if tiling has been set,
264+ * or 0 otherwise. The initial value is <code>0</code>.
265+ *
266+ * <p> Subclasses that do not support offsetting tiles may ignore
267+ * this value.
268+ */
269+ protected int tileGridXOffset = 0;
270+
271+ /**
272+ * The amount by which the tile grid origin should be offset
273+ * vertically from the image origin if tiling has been set,
274+ * or 0 otherwise. The initial value is <code>0</code>.
275+ *
276+ * <p> Subclasses that do not support offsetting tiles may ignore
277+ * this value.
278+ */
279+ protected int tileGridYOffset = 0;
280+
281+ /**
282+ * A <code>boolean</code> that is <code>true</code> if this
283+ * <code>ImageWriteParam</code> allows images to be written as a
284+ * progressive sequence of increasing quality passes. By default,
285+ * the value is <code>false</code>. Subclasses must set the value
286+ * manually.
287+ *
288+ * <p> Subclasses that do not support progressive encoding must
289+ * ensure that this value is set to <code>false</code>.
290+ */
291+ protected boolean canWriteProgressive = false;
292+
293+ /**
294+ * The mode controlling progressive encoding, which must be set to
295+ * one of the four <code>MODE_*</code> values, except
296+ * <code>MODE_EXPLICIT</code>. The default is
297+ * <code>MODE_COPY_FROM_METADATA</code>.
298+ *
299+ * <p> Subclasses that do not support progressive encoding may
300+ * ignore this value.
301+ *
302+ * @see #MODE_DISABLED
303+ * @see #MODE_EXPLICIT
304+ * @see #MODE_COPY_FROM_METADATA
305+ * @see #MODE_DEFAULT
306+ * @see #setProgressiveMode
307+ * @see #getProgressiveMode
308+ */
309+ protected int progressiveMode = MODE_COPY_FROM_METADATA;
310+
311+ /**
312+ * A <code>boolean</code> that is <code>true</code> if this writer
313+ * can write images using compression. By default, the value is
314+ * <code>false</code>. Subclasses must set the value manually.
315+ *
316+ * <p> Subclasses that do not support compression must ensure that
317+ * this value is set to <code>false</code>.
318+ */
319+ protected boolean canWriteCompressed = false;
320+
321+ /**
322+ * The mode controlling compression settings, which must be set to
323+ * one of the four <code>MODE_*</code> values. The default is
324+ * <code>MODE_COPY_FROM_METADATA</code>.
325+ *
326+ * <p> Subclasses that do not support compression may ignore this
327+ * value.
328+ *
329+ * @see #MODE_DISABLED
330+ * @see #MODE_EXPLICIT
331+ * @see #MODE_COPY_FROM_METADATA
332+ * @see #MODE_DEFAULT
333+ * @see #setCompressionMode
334+ * @see #getCompressionMode
335+ */
336+ protected int compressionMode = MODE_COPY_FROM_METADATA;
337+
338+ /**
339+ * An array of <code>String</code>s containing the names of the
340+ * available compression types. Subclasses must set the value
341+ * manually.
342+ *
343+ * <p> Subclasses that do not support compression may ignore this
344+ * value.
345+ */
346+ protected String[] compressionTypes = null;
347+
348+ /**
349+ * A <code>String</code> containing the name of the current
350+ * compression type, or <code>null</code> if none is set.
351+ *
352+ * <p> Subclasses that do not support compression may ignore this
353+ * value.
354+ */
355+ protected String compressionType = null;
356+
357+ /**
358+ * A <code>float</code> containing the current compression quality
359+ * setting. The initial value is <code>1.0F</code>.
360+ *
361+ * <p> Subclasses that do not support compression may ignore this
362+ * value.
363+ */
364+ protected float compressionQuality = 1.0F;
365+
366+ /**
367+ * A <code>Locale</code> to be used to localize compression type
368+ * names and quality descriptions, or <code>null</code> to use a
369+ * default <code>Locale</code>. Subclasses must set the value
370+ * manually.
371+ */
372+ protected Locale locale = null;
373+
374+ /**
375+ * Constructs an empty <code>ImageWriteParam</code>. It is up to
376+ * the subclass to set up the instance variables properly.
377+ */
378+ protected ImageWriteParam() {}
379+
380+ /**
381+ * Constructs an <code>ImageWriteParam</code> set to use a
382+ * given <code>Locale</code>.
383+ *
384+ * @param locale a <code>Locale</code> to be used to localize
385+ * compression type names and quality descriptions, or
386+ * <code>null</code>.
387+ */
388+ public ImageWriteParam(Locale locale) {
389+ this.locale = locale;
390+ }
391+
392+ // Return a deep copy of the array
393+ private static Dimension[] clonePreferredTileSizes(Dimension[] sizes) {
394+ if (sizes == null) {
395+ return null;
396+ }
397+ Dimension[] temp = new Dimension[sizes.length];
398+ for (int i = 0; i < sizes.length; i++) {
399+ temp[i] = new Dimension(sizes[i]);
400+ }
401+ return temp;
402+ }
403+
404+ /**
405+ * Returns the currently set <code>Locale</code>, or
406+ * <code>null</code> if only a default <code>Locale</code> is
407+ * supported.
408+ *
409+ * @return the current <code>Locale</code>, or <code>null</code>.
410+ */
411+ public Locale getLocale() {
412+ return locale;
413+ }
414+
415+ /**
416+ * Returns <code>true</code> if the writer can perform tiling
417+ * while writing. If this method returns <code>false</code>, then
418+ * <code>setTiling</code> will throw an
419+ * <code>UnsupportedOperationException</code>.
420+ *
421+ * @return <code>true</code> if the writer supports tiling.
422+ *
423+ * @see #canOffsetTiles()
424+ * @see #setTiling(int, int, int, int)
425+ */
426+ public boolean canWriteTiles() {
427+ return canWriteTiles;
428+ }
429+
430+ /**
431+ * Returns <code>true</code> if the writer can perform tiling with
432+ * non-zero grid offsets while writing. If this method returns
433+ * <code>false</code>, then <code>setTiling</code> will throw an
434+ * <code>UnsupportedOperationException</code> if the grid offset
435+ * arguments are not both zero. If <code>canWriteTiles</code>
436+ * returns <code>false</code>, this method will return
437+ * <code>false</code> as well.
438+ *
439+ * @return <code>true</code> if the writer supports non-zero tile
440+ * offsets.
441+ *
442+ * @see #canWriteTiles()
443+ * @see #setTiling(int, int, int, int)
444+ */
445+ public boolean canOffsetTiles() {
446+ return canOffsetTiles;
447+ }
448+
449+ /**
450+ * Determines whether the image will be tiled in the output
451+ * stream and, if it will, how the tiling parameters will be
452+ * determined. The modes are interpreted as follows:
453+ *
454+ * <ul>
455+ *
456+ * <li><code>MODE_DISABLED</code> - The image will not be tiled.
457+ * <code>setTiling</code> will throw an
458+ * <code>IllegalStateException</code>.
459+ *
460+ * <li><code>MODE_DEFAULT</code> - The image will be tiled using
461+ * default parameters. <code>setTiling</code> will throw an
462+ * <code>IllegalStateException</code>.
463+ *
464+ * <li><code>MODE_EXPLICIT</code> - The image will be tiled
465+ * according to parameters given in the {@link #setTiling
466+ * <code>setTiling</code>} method. Any previously set tiling
467+ * parameters are discarded.
468+ *
469+ * <li><code>MODE_COPY_FROM_METADATA</code> - The image will
470+ * conform to the metadata object passed in to a write.
471+ * <code>setTiling</code> will throw an
472+ * <code>IllegalStateException</code>.
473+ *
474+ * </ul>
475+ *
476+ * @param mode The mode to use for tiling.
477+ *
478+ * @exception UnsupportedOperationException if
479+ * <code>canWriteTiles</code> returns <code>false</code>.
480+ * @exception IllegalArgumentException if <code>mode</code> is not
481+ * one of the modes listed above.
482+ *
483+ * @see #setTiling
484+ * @see #getTilingMode
485+ */
486+ public void setTilingMode(int mode) {
487+ if (canWriteTiles() == false) {
488+ throw new UnsupportedOperationException("Tiling not supported!");
489+ }
490+ if (mode < MODE_DISABLED || mode > MAX_MODE) {
491+ throw new IllegalArgumentException("Illegal value for mode!");
492+ }
493+ this.tilingMode = mode;
494+ if (mode == MODE_EXPLICIT) {
495+ unsetTiling();
496+ }
497+ }
498+
499+ /**
500+ * Returns the current tiling mode, if tiling is supported.
501+ * Otherwise throws an <code>UnsupportedOperationException</code>.
502+ *
503+ * @return the current tiling mode.
504+ *
505+ * @exception UnsupportedOperationException if
506+ * <code>canWriteTiles</code> returns <code>false</code>.
507+ *
508+ * @see #setTilingMode
509+ */
510+ public int getTilingMode() {
511+ if (!canWriteTiles()) {
512+ throw new UnsupportedOperationException("Tiling not supported");
513+ }
514+ return tilingMode;
515+ }
516+
517+ /**
518+ * Returns an array of <code>Dimension</code>s indicating the
519+ * legal size ranges for tiles as they will be encoded in the
520+ * output file or stream. The returned array is a copy.
521+ *
522+ * <p> The information is returned as a set of pairs; the first
523+ * element of a pair contains an (inclusive) minimum width and
524+ * height, and the second element contains an (inclusive) maximum
525+ * width and height. Together, each pair defines a valid range of
526+ * sizes. To specify a fixed size, use the same width and height
527+ * for both elements. To specify an arbitrary range, a value of
528+ * <code>null</code> is used in place of an actual array of
529+ * <code>Dimension</code>s.
530+ *
531+ * <p> If no array is specified on the constructor, but tiling is
532+ * allowed, then this method returns <code>null</code>.
533+ *
534+ * @exception UnsupportedOperationException if the plug-in does
535+ * not support tiling.
536+ *
537+ * @return an array of <code>Dimension</code>s with an even length
538+ * of at least two, or <code>null</code>.
539+ */
540+ public Dimension[] getPreferredTileSizes() {
541+ if (!canWriteTiles()) {
542+ throw new UnsupportedOperationException("Tiling not supported");
543+ }
544+ return clonePreferredTileSizes(preferredTileSizes);
545+ }
546+
547+ /**
548+ * Specifies that the image should be tiled in the output stream.
549+ * The <code>tileWidth</code> and <code>tileHeight</code>
550+ * parameters specify the width and height of the tiles in the
551+ * file. If the tile width or height is greater than the width or
552+ * height of the image, the image is not tiled in that dimension.
553+ *
554+ * <p> If <code>canOffsetTiles</code> returns <code>false</code>,
555+ * then the <code>tileGridXOffset</code> and
556+ * <code>tileGridYOffset</code> parameters must be zero.
557+ *
558+ * @param tileWidth the width of each tile.
559+ * @param tileHeight the height of each tile.
560+ * @param tileGridXOffset the horizontal offset of the tile grid.
561+ * @param tileGridYOffset the vertical offset of the tile grid.
562+ *
563+ * @exception UnsupportedOperationException if the plug-in does not
564+ * support tiling.
565+ * @exception IllegalStateException if the tiling mode is not
566+ * <code>MODE_EXPLICIT</code>.
567+ * @exception UnsupportedOperationException if the plug-in does not
568+ * support grid offsets, and the grid offsets are not both zero.
569+ * @exception IllegalArgumentException if the tile size is not
570+ * within one of the allowable ranges returned by
571+ * <code>getPreferredTileSizes</code>.
572+ * @exception IllegalArgumentException if <code>tileWidth</code>
573+ * or <code>tileHeight</code> is less than or equal to 0.
574+ *
575+ * @see #canWriteTiles
576+ * @see #canOffsetTiles
577+ * @see #getTileWidth()
578+ * @see #getTileHeight()
579+ * @see #getTileGridXOffset()
580+ * @see #getTileGridYOffset()
581+ */
582+ public void setTiling(int tileWidth,
583+ int tileHeight,
584+ int tileGridXOffset,
585+ int tileGridYOffset) {
586+ if (!canWriteTiles()) {
587+ throw new UnsupportedOperationException("Tiling not supported!");
588+ }
589+ if (getTilingMode() != MODE_EXPLICIT) {
590+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
591+ }
592+ if (tileWidth <= 0 || tileHeight <= 0) {
593+ throw new IllegalArgumentException
594+ ("tile dimensions are non-positive!");
595+ }
596+ boolean tilesOffset = (tileGridXOffset != 0) || (tileGridYOffset != 0);
597+ if (!canOffsetTiles() && tilesOffset) {
598+ throw new UnsupportedOperationException("Can't offset tiles!");
599+ }
600+ if (preferredTileSizes != null) {
601+ boolean ok = true;
602+ for (int i = 0; i < preferredTileSizes.length; i += 2) {
603+ Dimension min = preferredTileSizes[i];
604+ Dimension max = preferredTileSizes[i+1];
605+ if ((tileWidth < min.width) ||
606+ (tileWidth > max.width) ||
607+ (tileHeight < min.height) ||
608+ (tileHeight > max.height)) {
609+ ok = false;
610+ break;
611+ }
612+ }
613+ if (!ok) {
614+ throw new IllegalArgumentException("Illegal tile size!");
615+ }
616+ }
617+
618+ this.tilingSet = true;
619+ this.tileWidth = tileWidth;
620+ this.tileHeight = tileHeight;
621+ this.tileGridXOffset = tileGridXOffset;
622+ this.tileGridYOffset = tileGridYOffset;
623+ }
624+
625+ /**
626+ * Removes any previous tile grid parameters specified by calls to
627+ * <code>setTiling</code>.
628+ *
629+ * <p> The default implementation sets the instance variables
630+ * <code>tileWidth</code>, <code>tileHeight</code>,
631+ * <code>tileGridXOffset</code>, and
632+ * <code>tileGridYOffset</code> to <code>0</code>.
633+ *
634+ * @exception UnsupportedOperationException if the plug-in does not
635+ * support tiling.
636+ * @exception IllegalStateException if the tiling mode is not
637+ * <code>MODE_EXPLICIT</code>.
638+ *
639+ * @see #setTiling(int, int, int, int)
640+ */
641+ public void unsetTiling() {
642+ if (!canWriteTiles()) {
643+ throw new UnsupportedOperationException("Tiling not supported!");
644+ }
645+ if (getTilingMode() != MODE_EXPLICIT) {
646+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
647+ }
648+ this.tilingSet = false;
649+ this.tileWidth = 0;
650+ this.tileHeight = 0;
651+ this.tileGridXOffset = 0;
652+ this.tileGridYOffset = 0;
653+ }
654+
655+ /**
656+ * Returns the width of each tile in an image as it will be
657+ * written to the output stream. If tiling parameters have not
658+ * been set, an <code>IllegalStateException</code> is thrown.
659+ *
660+ * @return the tile width to be used for encoding.
661+ *
662+ * @exception UnsupportedOperationException if the plug-in does not
663+ * support tiling.
664+ * @exception IllegalStateException if the tiling mode is not
665+ * <code>MODE_EXPLICIT</code>.
666+ * @exception IllegalStateException if the tiling parameters have
667+ * not been set.
668+ *
669+ * @see #setTiling(int, int, int, int)
670+ * @see #getTileHeight()
671+ */
672+ public int getTileWidth() {
673+ if (!canWriteTiles()) {
674+ throw new UnsupportedOperationException("Tiling not supported!");
675+ }
676+ if (getTilingMode() != MODE_EXPLICIT) {
677+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
678+ }
679+ if (!tilingSet) {
680+ throw new IllegalStateException("Tiling parameters not set!");
681+ }
682+ return tileWidth;
683+ }
684+
685+ /**
686+ * Returns the height of each tile in an image as it will be written to
687+ * the output stream. If tiling parameters have not
688+ * been set, an <code>IllegalStateException</code> is thrown.
689+ *
690+ * @return the tile height to be used for encoding.
691+ *
692+ * @exception UnsupportedOperationException if the plug-in does not
693+ * support tiling.
694+ * @exception IllegalStateException if the tiling mode is not
695+ * <code>MODE_EXPLICIT</code>.
696+ * @exception IllegalStateException if the tiling parameters have
697+ * not been set.
698+ *
699+ * @see #setTiling(int, int, int, int)
700+ * @see #getTileWidth()
701+ */
702+ public int getTileHeight() {
703+ if (!canWriteTiles()) {
704+ throw new UnsupportedOperationException("Tiling not supported!");
705+ }
706+ if (getTilingMode() != MODE_EXPLICIT) {
707+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
708+ }
709+ if (!tilingSet) {
710+ throw new IllegalStateException("Tiling parameters not set!");
711+ }
712+ return tileHeight;
713+ }
714+
715+ /**
716+ * Returns the horizontal tile grid offset of an image as it will
717+ * be written to the output stream. If tiling parameters have not
718+ * been set, an <code>IllegalStateException</code> is thrown.
719+ *
720+ * @return the tile grid X offset to be used for encoding.
721+ *
722+ * @exception UnsupportedOperationException if the plug-in does not
723+ * support tiling.
724+ * @exception IllegalStateException if the tiling mode is not
725+ * <code>MODE_EXPLICIT</code>.
726+ * @exception IllegalStateException if the tiling parameters have
727+ * not been set.
728+ *
729+ * @see #setTiling(int, int, int, int)
730+ * @see #getTileGridYOffset()
731+ */
732+ public int getTileGridXOffset() {
733+ if (!canWriteTiles()) {
734+ throw new UnsupportedOperationException("Tiling not supported!");
735+ }
736+ if (getTilingMode() != MODE_EXPLICIT) {
737+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
738+ }
739+ if (!tilingSet) {
740+ throw new IllegalStateException("Tiling parameters not set!");
741+ }
742+ return tileGridXOffset;
743+ }
744+
745+ /**
746+ * Returns the vertical tile grid offset of an image as it will
747+ * be written to the output stream. If tiling parameters have not
748+ * been set, an <code>IllegalStateException</code> is thrown.
749+ *
750+ * @return the tile grid Y offset to be used for encoding.
751+ *
752+ * @exception UnsupportedOperationException if the plug-in does not
753+ * support tiling.
754+ * @exception IllegalStateException if the tiling mode is not
755+ * <code>MODE_EXPLICIT</code>.
756+ * @exception IllegalStateException if the tiling parameters have
757+ * not been set.
758+ *
759+ * @see #setTiling(int, int, int, int)
760+ * @see #getTileGridXOffset()
761+ */
762+ public int getTileGridYOffset() {
763+ if (!canWriteTiles()) {
764+ throw new UnsupportedOperationException("Tiling not supported!");
765+ }
766+ if (getTilingMode() != MODE_EXPLICIT) {
767+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
768+ }
769+ if (!tilingSet) {
770+ throw new IllegalStateException("Tiling parameters not set!");
771+ }
772+ return tileGridYOffset;
773+ }
774+
775+ /**
776+ * Returns <code>true</code> if the writer can write out images
777+ * as a series of passes of progressively increasing quality.
778+ *
779+ * @return <code>true</code> if the writer supports progressive
780+ * encoding.
781+ *
782+ * @see #setProgressiveMode
783+ * @see #getProgressiveMode
784+ */
785+ public boolean canWriteProgressive() {
786+ return canWriteProgressive;
787+ }
788+
789+ /**
790+ * Specifies that the writer is to write the image out in a
791+ * progressive mode such that the stream will contain a series of
792+ * scans of increasing quality. If progressive encoding is not
793+ * supported, an <code>UnsupportedOperationException</code> will
794+ * be thrown.
795+ *
796+ * <p> The mode argument determines how
797+ * the progression parameters are chosen, and must be either
798+ * <code>MODE_DISABLED</code>,
799+ * <code>MODE_COPY_FROM_METADATA</code>, or
800+ * <code>MODE_DEFAULT</code>. Otherwise an
801+ * <code>IllegalArgumentException</code> is thrown.
802+ *
803+ * <p> The modes are interpreted as follows:
804+ *
805+ * <ul>
806+ * <li><code>MODE_DISABLED</code> - No progression. Use this to
807+ * turn off progession.
808+ *
809+ * <li><code>MODE_COPY_FROM_METADATA</code> - The output image
810+ * will use whatever progression parameters are found in the
811+ * metadata objects passed into the writer.
812+ *
813+ * <li><code>MODE_DEFAULT</code> - The image will be written
814+ * progressively, with parameters chosen by the writer.
815+ * </ul>
816+ *
817+ * <p> The default is <code>MODE_COPY_FROM_METADATA</code>.
818+ *
819+ * @param mode The mode for setting progression in the output
820+ * stream.
821+ *
822+ * @exception UnsupportedOperationException if the writer does not
823+ * support progressive encoding.
824+ * @exception IllegalArgumentException if <code>mode</code> is not
825+ * one of the modes listed above.
826+ *
827+ * @see #getProgressiveMode
828+ */
829+ public void setProgressiveMode(int mode) {
830+ if (!canWriteProgressive()) {
831+ throw new UnsupportedOperationException(
832+ "Progressive output not supported");
833+ }
834+ if (mode < MODE_DISABLED || mode > MAX_MODE) {
835+ throw new IllegalArgumentException("Illegal value for mode!");
836+ }
837+ if (mode == MODE_EXPLICIT) {
838+ throw new IllegalArgumentException(
839+ "MODE_EXPLICIT not supported for progressive output");
840+ }
841+ this.progressiveMode = mode;
842+ }
843+
844+ /**
845+ * Returns the current mode for writing the stream in a
846+ * progressive manner.
847+ *
848+ * @return the current mode for progressive encoding.
849+ *
850+ * @exception UnsupportedOperationException if the writer does not
851+ * support progressive encoding.
852+ *
853+ * @see #setProgressiveMode
854+ */
855+ public int getProgressiveMode() {
856+ if (!canWriteProgressive()) {
857+ throw new UnsupportedOperationException
858+ ("Progressive output not supported");
859+ }
860+ return progressiveMode;
861+ }
862+
863+ /**
864+ * Returns <code>true</code> if this writer supports compression.
865+ *
866+ * @return <code>true</code> if the writer supports compression.
867+ */
868+ public boolean canWriteCompressed() {
869+ return canWriteCompressed;
870+ }
871+
872+ /**
873+ * Specifies whether compression is to be performed, and if so how
874+ * compression parameters are to be determined. The <code>mode</code>
875+ * argument must be one of the four modes, interpreted as follows:
876+ *
877+ * <ul>
878+ * <li><code>MODE_DISABLED</code> - If the mode is set to
879+ * <code>MODE_DISABLED</code>, methods that query or modify the
880+ * compression type or parameters will throw an
881+ * <code>IllegalStateException</code> (if compression is
882+ * normally supported by the plug-in). Some writers, such as JPEG,
883+ * do not normally offer uncompressed output. In this case, attempting
884+ * to set the mode to <code>MODE_DISABLED</code> will throw an
885+ * <code>UnsupportedOperationException</code> and the mode will not be
886+ * changed.
887+ *
888+ * <li><code>MODE_EXPLICIT</code> - Compress using the
889+ * compression type and quality settings specified in this
890+ * <code>ImageWriteParam</code>. Any previously set compression
891+ * parameters are discarded.
892+ *
893+ * <li><code>MODE_COPY_FROM_METADATA</code> - Use whatever
894+ * compression parameters are specified in metadata objects
895+ * passed in to the writer.
896+ *
897+ * <li><code>MODE_DEFAULT</code> - Use default compression
898+ * parameters.
899+ * </ul>
900+ *
901+ * <p> The default is <code>MODE_COPY_FROM_METADATA</code>.
902+ *
903+ * @param mode The mode for setting compression in the output
904+ * stream.
905+ *
906+ * @exception UnsupportedOperationException if the writer does not
907+ * support compression, or does not support the requested mode.
908+ * @exception IllegalArgumentException if <code>mode</code> is not
909+ * one of the modes listed above.
910+ *
911+ * @see #getCompressionMode
912+ */
913+ public void setCompressionMode(int mode) {
914+ if (!canWriteCompressed()) {
915+ throw new UnsupportedOperationException(
916+ "Compression not supported.");
917+ }
918+ if (mode < MODE_DISABLED || mode > MAX_MODE) {
919+ throw new IllegalArgumentException("Illegal value for mode!");
920+ }
921+ this.compressionMode = mode;
922+ if (mode == MODE_EXPLICIT) {
923+ unsetCompression();
924+ }
925+ }
926+
927+ /**
928+ * Returns the current compression mode, if compression is
929+ * supported.
930+ *
931+ * @return the current compression mode.
932+ *
933+ * @exception UnsupportedOperationException if the writer does not
934+ * support compression.
935+ *
936+ * @see #setCompressionMode
937+ */
938+ public int getCompressionMode() {
939+ if (!canWriteCompressed()) {
940+ throw new UnsupportedOperationException(
941+ "Compression not supported.");
942+ }
943+ return compressionMode;
944+ }
945+
946+ /**
947+ * Returns a list of available compression types, as an array or
948+ * <code>String</code>s, or <code>null</code> if a compression
949+ * type may not be chosen using these interfaces. The array
950+ * returned is a copy.
951+ *
952+ * <p> If the writer only offers a single, mandatory form of
953+ * compression, it is not necessary to provide any named
954+ * compression types. Named compression types should only be
955+ * used where the user is able to make a meaningful choice
956+ * between different schemes.
957+ *
958+ * <p> The default implementation checks if compression is
959+ * supported and throws an
960+ * <code>UnsupportedOperationException</code> if not. Otherwise,
961+ * it returns a clone of the <code>compressionTypes</code>
962+ * instance variable if it is non-<code>null</code>, or else
963+ * returns <code>null</code>.
964+ *
965+ * @return an array of <code>String</code>s containing the
966+ * (non-localized) names of available compression types, or
967+ * <code>null</code>.
968+ *
969+ * @exception UnsupportedOperationException if the writer does not
970+ * support compression.
971+ */
972+ public String[] getCompressionTypes() {
973+ if (!canWriteCompressed()) {
974+ throw new UnsupportedOperationException(
975+ "Compression not supported");
976+ }
977+ if (compressionTypes == null) {
978+ return null;
979+ }
980+ return (String[])compressionTypes.clone();
981+ }
982+
983+ /**
984+ * Sets the compression type to one of the values indicated by
985+ * <code>getCompressionTypes</code>. If a value of
986+ * <code>null</code> is passed in, any previous setting is
987+ * removed.
988+ *
989+ * <p> The default implementation checks whether compression is
990+ * supported and the compression mode is
991+ * <code>MODE_EXPLICIT</code>. If so, it calls
992+ * <code>getCompressionTypes</code> and checks if
993+ * <code>compressionType</code> is one of the legal values. If it
994+ * is, the <code>compressionType</code> instance variable is set.
995+ * If <code>compressionType</code> is <code>null</code>, the
996+ * instance variable is set without performing any checking.
997+ *
998+ * @param compressionType one of the <code>String</code>s returned
999+ * by <code>getCompressionTypes</code>, or <code>null</code> to
1000+ * remove any previous setting.
1001+ *
1002+ * @exception UnsupportedOperationException if the writer does not
1003+ * support compression.
1004+ * @exception IllegalStateException if the compression mode is not
1005+ * <code>MODE_EXPLICIT</code>.
1006+ * @exception UnsupportedOperationException if there are no
1007+ * settable compression types.
1008+ * @exception IllegalArgumentException if
1009+ * <code>compressionType</code> is non-<code>null</code> but is not
1010+ * one of the values returned by <code>getCompressionTypes</code>.
1011+ *
1012+ * @see #getCompressionTypes
1013+ * @see #getCompressionType
1014+ * @see #unsetCompression
1015+ */
1016+ public void setCompressionType(String compressionType) {
1017+ if (!canWriteCompressed()) {
1018+ throw new UnsupportedOperationException(
1019+ "Compression not supported");
1020+ }
1021+ if (getCompressionMode() != MODE_EXPLICIT) {
1022+ throw new IllegalStateException
1023+ ("Compression mode not MODE_EXPLICIT!");
1024+ }
1025+ String[] legalTypes = getCompressionTypes();
1026+ if (legalTypes == null) {
1027+ throw new UnsupportedOperationException(
1028+ "No settable compression types");
1029+ }
1030+ if (compressionType != null) {
1031+ boolean found = false;
1032+ if (legalTypes != null) {
1033+ for (int i = 0; i < legalTypes.length; i++) {
1034+ if (compressionType.equals(legalTypes[i])) {
1035+ found = true;
1036+ break;
1037+ }
1038+ }
1039+ }
1040+ if (!found) {
1041+ throw new IllegalArgumentException("Unknown compression type!");
1042+ }
1043+ }
1044+ this.compressionType = compressionType;
1045+ }
1046+
1047+ /**
1048+ * Returns the currently set compression type, or
1049+ * <code>null</code> if none has been set. The type is returned
1050+ * as a <code>String</code> from among those returned by
1051+ * <code>getCompressionTypes</code>.
1052+ * If no compression type has been set, <code>null</code> is
1053+ * returned.
1054+ *
1055+ * <p> The default implementation checks whether compression is
1056+ * supported and the compression mode is
1057+ * <code>MODE_EXPLICIT</code>. If so, it returns the value of the
1058+ * <code>compressionType</code> instance variable.
1059+ *
1060+ * @return the current compression type as a <code>String</code>,
1061+ * or <code>null</code> if no type is set.
1062+ *
1063+ * @exception UnsupportedOperationException if the writer does not
1064+ * support compression.
1065+ * @exception IllegalStateException if the compression mode is not
1066+ * <code>MODE_EXPLICIT</code>.
1067+ *
1068+ * @see #setCompressionType
1069+ */
1070+ public String getCompressionType() {
1071+ if (!canWriteCompressed()) {
1072+ throw new UnsupportedOperationException(
1073+ "Compression not supported.");
1074+ }
1075+ if (getCompressionMode() != MODE_EXPLICIT) {
1076+ throw new IllegalStateException
1077+ ("Compression mode not MODE_EXPLICIT!");
1078+ }
1079+ return compressionType;
1080+ }
1081+
1082+ /**
1083+ * Removes any previous compression type and quality settings.
1084+ *
1085+ * <p> The default implementation sets the instance variable
1086+ * <code>compressionType</code> to <code>null</code>, and the
1087+ * instance variable <code>compressionQuality</code> to
1088+ * <code>1.0F</code>.
1089+ *
1090+ * @exception UnsupportedOperationException if the plug-in does not
1091+ * support compression.
1092+ * @exception IllegalStateException if the compression mode is not
1093+ * <code>MODE_EXPLICIT</code>.
1094+ *
1095+ * @see #setCompressionType
1096+ * @see #setCompressionQuality
1097+ */
1098+ public void unsetCompression() {
1099+ if (!canWriteCompressed()) {
1100+ throw new UnsupportedOperationException(
1101+ "Compression not supported");
1102+ }
1103+ if (getCompressionMode() != MODE_EXPLICIT) {
1104+ throw new IllegalStateException
1105+ ("Compression mode not MODE_EXPLICIT!");
1106+ }
1107+ this.compressionType = null;
1108+ this.compressionQuality = 1.0F;
1109+ }
1110+
1111+ /**
1112+ * Returns a localized version of the name of the current
1113+ * compression type, using the <code>Locale</code> returned by
1114+ * <code>getLocale</code>.
1115+ *
1116+ * <p> The default implementation checks whether compression is
1117+ * supported and the compression mode is
1118+ * <code>MODE_EXPLICIT</code>. If so, if
1119+ * <code>compressionType</code> is <code>non-null</code> the value
1120+ * of <code>getCompressionType</code> is returned as a
1121+ * convenience.
1122+ *
1123+ * @return a <code>String</code> containing a localized version of
1124+ * the name of the current compression type.
1125+ *
1126+ * @exception UnsupportedOperationException if the writer does not
1127+ * support compression.
1128+ * @exception IllegalStateException if the compression mode is not
1129+ * <code>MODE_EXPLICIT</code>.
1130+ * @exception IllegalStateException if no compression type is set.
1131+ */
1132+ public String getLocalizedCompressionTypeName() {
1133+ if (!canWriteCompressed()) {
1134+ throw new UnsupportedOperationException(
1135+ "Compression not supported.");
1136+ }
1137+ if (getCompressionMode() != MODE_EXPLICIT) {
1138+ throw new IllegalStateException
1139+ ("Compression mode not MODE_EXPLICIT!");
1140+ }
1141+ if (getCompressionType() == null) {
1142+ throw new IllegalStateException("No compression type set!");
1143+ }
1144+ return getCompressionType();
1145+ }
1146+
1147+ /**
1148+ * Returns <code>true</code> if the current compression type
1149+ * provides lossless compression. If a plug-in provides only
1150+ * one mandatory compression type, then this method may be
1151+ * called without calling <code>setCompressionType</code> first.
1152+ *
1153+ * <p> If there are multiple compression types but none has
1154+ * been set, an <code>IllegalStateException</code> is thrown.
1155+ *
1156+ * <p> The default implementation checks whether compression is
1157+ * supported and the compression mode is
1158+ * <code>MODE_EXPLICIT</code>. If so, if
1159+ * <code>getCompressionTypes()</code> is <code>null</code> or
1160+ * <code>getCompressionType()</code> is non-<code>null</code>
1161+ * <code>true</code> is returned as a convenience.
1162+ *
1163+ * @return <code>true</code> if the current compression type is
1164+ * lossless.
1165+ *
1166+ * @exception UnsupportedOperationException if the writer does not
1167+ * support compression.
1168+ * @exception IllegalStateException if the compression mode is not
1169+ * <code>MODE_EXPLICIT</code>.
1170+ * @exception IllegalStateException if the set of legal
1171+ * compression types is non-<code>null</code> and the current
1172+ * compression type is <code>null</code>.
1173+ */
1174+ public boolean isCompressionLossless() {
1175+ if (!canWriteCompressed()) {
1176+ throw new UnsupportedOperationException(
1177+ "Compression not supported");
1178+ }
1179+ if (getCompressionMode() != MODE_EXPLICIT) {
1180+ throw new IllegalStateException
1181+ ("Compression mode not MODE_EXPLICIT!");
1182+ }
1183+ if ((getCompressionTypes() != null) &&
1184+ (getCompressionType() == null)) {
1185+ throw new IllegalStateException("No compression type set!");
1186+ }
1187+ return true;
1188+ }
1189+
1190+ /**
1191+ * Sets the compression quality to a value between <code>0</code>
1192+ * and <code>1</code>. Only a single compression quality setting
1193+ * is supported by default; writers can provide extended versions
1194+ * of <code>ImageWriteParam</code> that offer more control. For
1195+ * lossy compression schemes, the compression quality should
1196+ * control the tradeoff between file size and image quality (for
1197+ * example, by choosing quantization tables when writing JPEG
1198+ * images). For lossless schemes, the compression quality may be
1199+ * used to control the tradeoff between file size and time taken
1200+ * to perform the compression (for example, by optimizing row
1201+ * filters and setting the ZLIB compression level when writing
1202+ * PNG images).
1203+ *
1204+ * <p> A compression quality setting of 0.0 is most generically
1205+ * interpreted as "high compression is important," while a setting of
1206+ * 1.0 is most generically interpreted as "high image quality is
1207+ * important."
1208+ *
1209+ * <p> If there are multiple compression types but none has been
1210+ * set, an <code>IllegalStateException</code> is thrown.
1211+ *
1212+ * <p> The default implementation checks that compression is
1213+ * supported, and that the compression mode is
1214+ * <code>MODE_EXPLICIT</code>. If so, if
1215+ * <code>getCompressionTypes()</code> returns <code>null</code> or
1216+ * <code>compressionType</code> is non-<code>null</code> it sets
1217+ * the <code>compressionQuality</code> instance variable.
1218+ *
1219+ * @param quality a <code>float</code> between <code>0</code>and
1220+ * <code>1</code> indicating the desired quality level.
1221+ *
1222+ * @exception UnsupportedOperationException if the writer does not
1223+ * support compression.
1224+ * @exception IllegalStateException if the compression mode is not
1225+ * <code>MODE_EXPLICIT</code>.
1226+ * @exception IllegalStateException if the set of legal
1227+ * compression types is non-<code>null</code> and the current
1228+ * compression type is <code>null</code>.
1229+ * @exception IllegalArgumentException if <code>quality</code> is
1230+ * not between <code>0</code>and <code>1</code>, inclusive.
1231+ *
1232+ * @see #getCompressionQuality
1233+ */
1234+ public void setCompressionQuality(float quality) {
1235+ if (!canWriteCompressed()) {
1236+ throw new UnsupportedOperationException(
1237+ "Compression not supported");
1238+ }
1239+ if (getCompressionMode() != MODE_EXPLICIT) {
1240+ throw new IllegalStateException
1241+ ("Compression mode not MODE_EXPLICIT!");
1242+ }
1243+ if (getCompressionTypes() != null && getCompressionType() == null) {
1244+ throw new IllegalStateException("No compression type set!");
1245+ }
1246+ if (quality < 0.0F || quality > 1.0F) {
1247+ throw new IllegalArgumentException("Quality out-of-bounds!");
1248+ }
1249+ this.compressionQuality = quality;
1250+ }
1251+
1252+ /**
1253+ * Returns the current compression quality setting.
1254+ *
1255+ * <p> If there are multiple compression types but none has been
1256+ * set, an <code>IllegalStateException</code> is thrown.
1257+ *
1258+ * <p> The default implementation checks that compression is
1259+ * supported and that the compression mode is
1260+ * <code>MODE_EXPLICIT</code>. If so, if
1261+ * <code>getCompressionTypes()</code> is <code>null</code> or
1262+ * <code>getCompressionType()</code> is non-<code>null</code>, it
1263+ * returns the value of the <code>compressionQuality</code>
1264+ * instance variable.
1265+ *
1266+ * @return the current compression quality setting.
1267+ *
1268+ * @exception UnsupportedOperationException if the writer does not
1269+ * support compression.
1270+ * @exception IllegalStateException if the compression mode is not
1271+ * <code>MODE_EXPLICIT</code>.
1272+ * @exception IllegalStateException if the set of legal
1273+ * compression types is non-<code>null</code> and the current
1274+ * compression type is <code>null</code>.
1275+ *
1276+ * @see #setCompressionQuality
1277+ */
1278+ public float getCompressionQuality() {
1279+ if (!canWriteCompressed()) {
1280+ throw new UnsupportedOperationException(
1281+ "Compression not supported.");
1282+ }
1283+ if (getCompressionMode() != MODE_EXPLICIT) {
1284+ throw new IllegalStateException
1285+ ("Compression mode not MODE_EXPLICIT!");
1286+ }
1287+ if ((getCompressionTypes() != null) &&
1288+ (getCompressionType() == null)) {
1289+ throw new IllegalStateException("No compression type set!");
1290+ }
1291+ return compressionQuality;
1292+ }
1293+
1294+
1295+ /**
1296+ * Returns a <code>float</code> indicating an estimate of the
1297+ * number of bits of output data for each bit of input image data
1298+ * at the given quality level. The value will typically lie
1299+ * between <code>0</code> and <code>1</code>, with smaller values
1300+ * indicating more compression. A special value of
1301+ * <code>-1.0F</code> is used to indicate that no estimate is
1302+ * available.
1303+ *
1304+ * <p> If there are multiple compression types but none has been set,
1305+ * an <code>IllegalStateException</code> is thrown.
1306+ *
1307+ * <p> The default implementation checks that compression is
1308+ * supported and the compression mode is
1309+ * <code>MODE_EXPLICIT</code>. If so, if
1310+ * <code>getCompressionTypes()</code> is <code>null</code> or
1311+ * <code>getCompressionType()</code> is non-<code>null</code>, and
1312+ * <code>quality</code> is within bounds, it returns
1313+ * <code>-1.0</code>.
1314+ *
1315+ * @param quality the quality setting whose bit rate is to be
1316+ * queried.
1317+ *
1318+ * @return an estimate of the compressed bit rate, or
1319+ * <code>-1.0F</code> if no estimate is available.
1320+ *
1321+ * @exception UnsupportedOperationException if the writer does not
1322+ * support compression.
1323+ * @exception IllegalStateException if the compression mode is not
1324+ * <code>MODE_EXPLICIT</code>.
1325+ * @exception IllegalStateException if the set of legal
1326+ * compression types is non-<code>null</code> and the current
1327+ * compression type is <code>null</code>.
1328+ * @exception IllegalArgumentException if <code>quality</code> is
1329+ * not between <code>0</code>and <code>1</code>, inclusive.
1330+ */
1331+ public float getBitRate(float quality) {
1332+ if (!canWriteCompressed()) {
1333+ throw new UnsupportedOperationException(
1334+ "Compression not supported.");
1335+ }
1336+ if (getCompressionMode() != MODE_EXPLICIT) {
1337+ throw new IllegalStateException
1338+ ("Compression mode not MODE_EXPLICIT!");
1339+ }
1340+ if ((getCompressionTypes() != null) &&
1341+ (getCompressionType() == null)) {
1342+ throw new IllegalStateException("No compression type set!");
1343+ }
1344+ if (quality < 0.0F || quality > 1.0F) {
1345+ throw new IllegalArgumentException("Quality out-of-bounds!");
1346+ }
1347+ return -1.0F;
1348+ }
1349+
1350+ /**
1351+ * Returns an array of <code>String</code>s that may be used along
1352+ * with <code>getCompressionQualityValues</code> as part of a user
1353+ * interface for setting or displaying the compression quality
1354+ * level. The <code>String</code> with index <code>i</code>
1355+ * provides a description of the range of quality levels between
1356+ * <code>getCompressionQualityValues[i]</code> and
1357+ * <code>getCompressionQualityValues[i + 1]</code>. Note that the
1358+ * length of the array returned from
1359+ * <code>getCompressionQualityValues</code> will always be one
1360+ * greater than that returned from
1361+ * <code>getCompressionQualityDescriptions</code>.
1362+ *
1363+ * <p> As an example, the strings "Good", "Better", and "Best"
1364+ * could be associated with the ranges <code>[0, .33)</code>,
1365+ * <code>[.33, .66)</code>, and <code>[.66, 1.0]</code>. In this
1366+ * case, <code>getCompressionQualityDescriptions</code> would
1367+ * return <code>{ "Good", "Better", "Best" }</code> and
1368+ * <code>getCompressionQualityValues</code> would return
1369+ * <code>{ 0.0F, .33F, .66F, 1.0F }</code>.
1370+ *
1371+ * <p> If no descriptions are available, <code>null</code> is
1372+ * returned. If <code>null</code> is returned from
1373+ * <code>getCompressionQualityValues</code>, this method must also
1374+ * return <code>null</code>.
1375+ *
1376+ * <p> The descriptions should be localized for the
1377+ * <code>Locale</code> returned by <code>getLocale</code>, if it
1378+ * is non-<code>null</code>.
1379+ *
1380+ * <p> If there are multiple compression types but none has been set,
1381+ * an <code>IllegalStateException</code> is thrown.
1382+ *
1383+ * <p> The default implementation checks that compression is
1384+ * supported and that the compression mode is
1385+ * <code>MODE_EXPLICIT</code>. If so, if
1386+ * <code>getCompressionTypes()</code> is <code>null</code> or
1387+ * <code>getCompressionType()</code> is non-<code>null</code>, it
1388+ * returns <code>null</code>.
1389+ *
1390+ * @return an array of <code>String</code>s containing localized
1391+ * descriptions of the compression quality levels.
1392+ *
1393+ * @exception UnsupportedOperationException if the writer does not
1394+ * support compression.
1395+ * @exception IllegalStateException if the compression mode is not
1396+ * <code>MODE_EXPLICIT</code>.
1397+ * @exception IllegalStateException if the set of legal
1398+ * compression types is non-<code>null</code> and the current
1399+ * compression type is <code>null</code>.
1400+ *
1401+ * @see #getCompressionQualityValues
1402+ */
1403+ public String[] getCompressionQualityDescriptions() {
1404+ if (!canWriteCompressed()) {
1405+ throw new UnsupportedOperationException(
1406+ "Compression not supported.");
1407+ }
1408+ if (getCompressionMode() != MODE_EXPLICIT) {
1409+ throw new IllegalStateException
1410+ ("Compression mode not MODE_EXPLICIT!");
1411+ }
1412+ if ((getCompressionTypes() != null) &&
1413+ (getCompressionType() == null)) {
1414+ throw new IllegalStateException("No compression type set!");
1415+ }
1416+ return null;
1417+ }
1418+
1419+ /**
1420+ * Returns an array of <code>float</code>s that may be used along
1421+ * with <code>getCompressionQualityDescriptions</code> as part of a user
1422+ * interface for setting or displaying the compression quality
1423+ * level. See {@link #getCompressionQualityDescriptions
1424+ * <code>getCompressionQualityDescriptions</code>} for more information.
1425+ *
1426+ * <p> If no descriptions are available, <code>null</code> is
1427+ * returned. If <code>null</code> is returned from
1428+ * <code>getCompressionQualityDescriptions</code>, this method
1429+ * must also return <code>null</code>.
1430+ *
1431+ * <p> If there are multiple compression types but none has been set,
1432+ * an <code>IllegalStateException</code> is thrown.
1433+ *
1434+ * <p> The default implementation checks that compression is
1435+ * supported and that the compression mode is
1436+ * <code>MODE_EXPLICIT</code>. If so, if
1437+ * <code>getCompressionTypes()</code> is <code>null</code> or
1438+ * <code>getCompressionType()</code> is non-<code>null</code>, it
1439+ * returns <code>null</code>.
1440+ *
1441+ * @return an array of <code>float</code>s indicating the
1442+ * boundaries between the compression quality levels as described
1443+ * by the <code>String</code>s from
1444+ * <code>getCompressionQualityDescriptions</code>.
1445+ *
1446+ * @exception UnsupportedOperationException if the writer does not
1447+ * support compression.
1448+ * @exception IllegalStateException if the compression mode is not
1449+ * <code>MODE_EXPLICIT</code>.
1450+ * @exception IllegalStateException if the set of legal
1451+ * compression types is non-<code>null</code> and the current
1452+ * compression type is <code>null</code>.
1453+ *
1454+ * @see #getCompressionQualityDescriptions
1455+ */
1456+ public float[] getCompressionQualityValues() {
1457+ if (!canWriteCompressed()) {
1458+ throw new UnsupportedOperationException(
1459+ "Compression not supported.");
1460+ }
1461+ if (getCompressionMode() != MODE_EXPLICIT) {
1462+ throw new IllegalStateException
1463+ ("Compression mode not MODE_EXPLICIT!");
1464+ }
1465+ if ((getCompressionTypes() != null) &&
1466+ (getCompressionType() == null)) {
1467+ throw new IllegalStateException("No compression type set!");
1468+ }
1469+ return null;
1470+ }
1471+}