diff -r 836adbf7a2cd -r 3317bb8137f4 jdk/src/java.desktop/share/classes/javax/imageio/ImageWriteParam.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageWriteParam.java Sun Aug 17 15:54:13 2014 +0100
@@ -0,0 +1,1470 @@
+/*
+ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.imageio;
+
+import java.awt.Dimension;
+import java.util.Locale;
+
+/**
+ * A class describing how a stream is to be encoded. Instances of
+ * this class or its subclasses are used to supply prescriptive
+ * "how-to" information to instances of ImageWriter
.
+ *
+ *
A plug-in for a specific image format may define a subclass of
+ * this class, and return objects of that class from the
+ * getDefaultWriteParam
method of its
+ * ImageWriter
implementation. For example, the built-in
+ * JPEG writer plug-in will return instances of
+ * javax.imageio.plugins.jpeg.JPEGImageWriteParam
.
+ *
+ *
The region of the image to be written is determined by first
+ * intersecting the actual bounds of the image with the rectangle
+ * specified by IIOParam.setSourceRegion
, if any. If the
+ * resulting rectangle has a width or height of zero, the writer will
+ * throw an IIOException
. If the intersection is
+ * non-empty, writing will commence with the first subsampled pixel
+ * and include additional pixels within the intersected bounds
+ * according to the horizontal and vertical subsampling factors
+ * specified by {@link IIOParam#setSourceSubsampling
+ * IIOParam.setSourceSubsampling}.
+ *
+ *
Individual features such as tiling, progressive encoding, and
+ * compression may be set in one of four modes.
+ * MODE_DISABLED
disables the features;
+ * MODE_DEFAULT
enables the feature with
+ * writer-controlled parameter values; MODE_EXPLICIT
+ * enables the feature and allows the use of a set
method
+ * to provide additional parameters; and
+ * MODE_COPY_FROM_METADATA
copies relevant parameter
+ * values from the stream and image metadata objects passed to the
+ * writer. The default for all features is
+ * MODE_COPY_FROM_METADATA
. Non-standard features
+ * supplied in subclasses are encouraged, but not required to use a
+ * similar scheme.
+ *
+ *
Plug-in writers may extend the functionality of
+ * ImageWriteParam
by providing a subclass that implements
+ * additional, plug-in specific interfaces. It is up to the plug-in
+ * to document what interfaces are available and how they are to be
+ * used. Writers will silently ignore any extended features of an
+ * ImageWriteParam
subclass of which they are not aware.
+ * Also, they may ignore any optional features that they normally
+ * disable when creating their own ImageWriteParam
+ * instances via getDefaultWriteParam
.
+ *
+ *
Note that unless a query method exists for a capability, it must
+ * be supported by all ImageWriter
implementations
+ * (e.g. progressive encoding is optional, but subsampling must be
+ * supported).
+ *
+ *
+ * @see ImageReadParam
+ */
+public class ImageWriteParam extends IIOParam {
+
+ /**
+ * A constant value that may be passed into methods such as
+ * setTilingMode
, setProgressiveMode
,
+ * and setCompressionMode
to disable a feature for
+ * future writes. That is, when this mode is set the stream will
+ * not be tiled, progressive, or compressed, and the
+ * relevant accessor methods will throw an
+ * IllegalStateException
.
+ *
+ * @see #MODE_EXPLICIT
+ * @see #MODE_COPY_FROM_METADATA
+ * @see #MODE_DEFAULT
+ * @see #setProgressiveMode
+ * @see #getProgressiveMode
+ * @see #setTilingMode
+ * @see #getTilingMode
+ * @see #setCompressionMode
+ * @see #getCompressionMode
+ */
+ public static final int MODE_DISABLED = 0;
+
+ /**
+ * A constant value that may be passed into methods such as
+ * setTilingMode
,
+ * setProgressiveMode
, and
+ * setCompressionMode
to enable that feature for
+ * future writes. That is, when this mode is enabled the stream
+ * will be tiled, progressive, or compressed according to a
+ * sensible default chosen internally by the writer in a plug-in
+ * dependent way, and the relevant accessor methods will
+ * throw an IllegalStateException
.
+ *
+ * @see #MODE_DISABLED
+ * @see #MODE_EXPLICIT
+ * @see #MODE_COPY_FROM_METADATA
+ * @see #setProgressiveMode
+ * @see #getProgressiveMode
+ * @see #setTilingMode
+ * @see #getTilingMode
+ * @see #setCompressionMode
+ * @see #getCompressionMode
+ */
+ public static final int MODE_DEFAULT = 1;
+
+ /**
+ * A constant value that may be passed into methods such as
+ * setTilingMode
or setCompressionMode
+ * to enable a feature for future writes. That is, when this mode
+ * is set the stream will be tiled or compressed according to
+ * additional information supplied to the corresponding
+ * set
methods in this class and retrievable from the
+ * corresponding get
methods. Note that this mode is
+ * not supported for progressive output.
+ *
+ * @see #MODE_DISABLED
+ * @see #MODE_COPY_FROM_METADATA
+ * @see #MODE_DEFAULT
+ * @see #setProgressiveMode
+ * @see #getProgressiveMode
+ * @see #setTilingMode
+ * @see #getTilingMode
+ * @see #setCompressionMode
+ * @see #getCompressionMode
+ */
+ public static final int MODE_EXPLICIT = 2;
+
+ /**
+ * A constant value that may be passed into methods such as
+ * setTilingMode
, setProgressiveMode
, or
+ * setCompressionMode
to enable that feature for
+ * future writes. That is, when this mode is enabled the stream
+ * will be tiled, progressive, or compressed based on the contents
+ * of stream and/or image metadata passed into the write
+ * operation, and any relevant accessor methods will throw an
+ * IllegalStateException
.
+ *
+ *
This is the default mode for all features, so that a read
+ * including metadata followed by a write including metadata will
+ * preserve as much information as possible.
+ *
+ * @see #MODE_DISABLED
+ * @see #MODE_EXPLICIT
+ * @see #MODE_DEFAULT
+ * @see #setProgressiveMode
+ * @see #getProgressiveMode
+ * @see #setTilingMode
+ * @see #getTilingMode
+ * @see #setCompressionMode
+ * @see #getCompressionMode
+ */
+ public static final int MODE_COPY_FROM_METADATA = 3;
+
+ // If more modes are added, this should be updated.
+ private static final int MAX_MODE = MODE_COPY_FROM_METADATA;
+
+ /**
+ * A boolean
that is true
if this
+ * ImageWriteParam
allows tile width and tile height
+ * parameters to be set. By default, the value is
+ * false
. Subclasses must set the value manually.
+ *
+ *
Subclasses that do not support writing tiles should ensure
+ * that this value is set to false
.
+ */
+ protected boolean canWriteTiles = false;
+
+ /**
+ * The mode controlling tiling settings, which Must be
+ * set to one of the four MODE_*
values. The default
+ * is MODE_COPY_FROM_METADATA
.
+ *
+ *
Subclasses that do not writing tiles may ignore this value.
+ *
+ * @see #MODE_DISABLED
+ * @see #MODE_EXPLICIT
+ * @see #MODE_COPY_FROM_METADATA
+ * @see #MODE_DEFAULT
+ * @see #setTilingMode
+ * @see #getTilingMode
+ */
+ protected int tilingMode = MODE_COPY_FROM_METADATA;
+
+ /**
+ * An array of preferred tile size range pairs. The default value
+ * is null
, which indicates that there are no
+ * preferred sizes. If the value is non-null
, it
+ * must have an even length of at least two.
+ *
+ *
Subclasses that do not support writing tiles may ignore
+ * this value.
+ *
+ * @see #getPreferredTileSizes
+ */
+ protected Dimension[] preferredTileSizes = null;
+
+ /**
+ * A boolean
that is true
if tiling
+ * parameters have been specified.
+ *
+ *
Subclasses that do not support writing tiles may ignore + * this value. + */ + protected boolean tilingSet = false; + + /** + * The width of each tile if tiling has been set, or 0 otherwise. + * + *
Subclasses that do not support tiling may ignore this
+ * value.
+ */
+ protected int tileWidth = 0;
+
+ /**
+ * The height of each tile if tiling has been set, or 0 otherwise.
+ * The initial value is 0
.
+ *
+ *
Subclasses that do not support tiling may ignore this
+ * value.
+ */
+ protected int tileHeight = 0;
+
+ /**
+ * A boolean
that is true
if this
+ * ImageWriteParam
allows tiling grid offset
+ * parameters to be set. By default, the value is
+ * false
. Subclasses must set the value manually.
+ *
+ *
Subclasses that do not support writing tiles, or that
+ * support writing but not offsetting tiles must ensure that this
+ * value is set to false
.
+ */
+ protected boolean canOffsetTiles = false;
+
+ /**
+ * The amount by which the tile grid origin should be offset
+ * horizontally from the image origin if tiling has been set,
+ * or 0 otherwise. The initial value is 0
.
+ *
+ *
Subclasses that do not support offsetting tiles may ignore
+ * this value.
+ */
+ protected int tileGridXOffset = 0;
+
+ /**
+ * The amount by which the tile grid origin should be offset
+ * vertically from the image origin if tiling has been set,
+ * or 0 otherwise. The initial value is 0
.
+ *
+ *
Subclasses that do not support offsetting tiles may ignore
+ * this value.
+ */
+ protected int tileGridYOffset = 0;
+
+ /**
+ * A boolean
that is true
if this
+ * ImageWriteParam
allows images to be written as a
+ * progressive sequence of increasing quality passes. By default,
+ * the value is false
. Subclasses must set the value
+ * manually.
+ *
+ *
Subclasses that do not support progressive encoding must
+ * ensure that this value is set to false
.
+ */
+ protected boolean canWriteProgressive = false;
+
+ /**
+ * The mode controlling progressive encoding, which must be set to
+ * one of the four MODE_*
values, except
+ * MODE_EXPLICIT
. The default is
+ * MODE_COPY_FROM_METADATA
.
+ *
+ *
Subclasses that do not support progressive encoding may
+ * ignore this value.
+ *
+ * @see #MODE_DISABLED
+ * @see #MODE_EXPLICIT
+ * @see #MODE_COPY_FROM_METADATA
+ * @see #MODE_DEFAULT
+ * @see #setProgressiveMode
+ * @see #getProgressiveMode
+ */
+ protected int progressiveMode = MODE_COPY_FROM_METADATA;
+
+ /**
+ * A boolean
that is true
if this writer
+ * can write images using compression. By default, the value is
+ * false
. Subclasses must set the value manually.
+ *
+ *
Subclasses that do not support compression must ensure that
+ * this value is set to false
.
+ */
+ protected boolean canWriteCompressed = false;
+
+ /**
+ * The mode controlling compression settings, which must be set to
+ * one of the four MODE_*
values. The default is
+ * MODE_COPY_FROM_METADATA
.
+ *
+ *
Subclasses that do not support compression may ignore this
+ * value.
+ *
+ * @see #MODE_DISABLED
+ * @see #MODE_EXPLICIT
+ * @see #MODE_COPY_FROM_METADATA
+ * @see #MODE_DEFAULT
+ * @see #setCompressionMode
+ * @see #getCompressionMode
+ */
+ protected int compressionMode = MODE_COPY_FROM_METADATA;
+
+ /**
+ * An array of String
s containing the names of the
+ * available compression types. Subclasses must set the value
+ * manually.
+ *
+ *
Subclasses that do not support compression may ignore this
+ * value.
+ */
+ protected String[] compressionTypes = null;
+
+ /**
+ * A String
containing the name of the current
+ * compression type, or null
if none is set.
+ *
+ *
Subclasses that do not support compression may ignore this
+ * value.
+ */
+ protected String compressionType = null;
+
+ /**
+ * A float
containing the current compression quality
+ * setting. The initial value is 1.0F
.
+ *
+ *
Subclasses that do not support compression may ignore this
+ * value.
+ */
+ protected float compressionQuality = 1.0F;
+
+ /**
+ * A Locale
to be used to localize compression type
+ * names and quality descriptions, or null
to use a
+ * default Locale
. Subclasses must set the value
+ * manually.
+ */
+ protected Locale locale = null;
+
+ /**
+ * Constructs an empty ImageWriteParam
. It is up to
+ * the subclass to set up the instance variables properly.
+ */
+ protected ImageWriteParam() {}
+
+ /**
+ * Constructs an ImageWriteParam
set to use a
+ * given Locale
.
+ *
+ * @param locale a Locale
to be used to localize
+ * compression type names and quality descriptions, or
+ * null
.
+ */
+ public ImageWriteParam(Locale locale) {
+ this.locale = locale;
+ }
+
+ // Return a deep copy of the array
+ private static Dimension[] clonePreferredTileSizes(Dimension[] sizes) {
+ if (sizes == null) {
+ return null;
+ }
+ Dimension[] temp = new Dimension[sizes.length];
+ for (int i = 0; i < sizes.length; i++) {
+ temp[i] = new Dimension(sizes[i]);
+ }
+ return temp;
+ }
+
+ /**
+ * Returns the currently set Locale
, or
+ * null
if only a default Locale
is
+ * supported.
+ *
+ * @return the current Locale
, or null
.
+ */
+ public Locale getLocale() {
+ return locale;
+ }
+
+ /**
+ * Returns true
if the writer can perform tiling
+ * while writing. If this method returns false
, then
+ * setTiling
will throw an
+ * UnsupportedOperationException
.
+ *
+ * @return true
if the writer supports tiling.
+ *
+ * @see #canOffsetTiles()
+ * @see #setTiling(int, int, int, int)
+ */
+ public boolean canWriteTiles() {
+ return canWriteTiles;
+ }
+
+ /**
+ * Returns true
if the writer can perform tiling with
+ * non-zero grid offsets while writing. If this method returns
+ * false
, then setTiling
will throw an
+ * UnsupportedOperationException
if the grid offset
+ * arguments are not both zero. If canWriteTiles
+ * returns false
, this method will return
+ * false
as well.
+ *
+ * @return true
if the writer supports non-zero tile
+ * offsets.
+ *
+ * @see #canWriteTiles()
+ * @see #setTiling(int, int, int, int)
+ */
+ public boolean canOffsetTiles() {
+ return canOffsetTiles;
+ }
+
+ /**
+ * Determines whether the image will be tiled in the output
+ * stream and, if it will, how the tiling parameters will be
+ * determined. The modes are interpreted as follows:
+ *
+ *
MODE_DISABLED
- The image will not be tiled.
+ * setTiling
will throw an
+ * IllegalStateException
.
+ *
+ * MODE_DEFAULT
- The image will be tiled using
+ * default parameters. setTiling
will throw an
+ * IllegalStateException
.
+ *
+ * MODE_EXPLICIT
- The image will be tiled
+ * according to parameters given in the {@link #setTiling setTiling}
+ * method. Any previously set tiling parameters are discarded.
+ *
+ * MODE_COPY_FROM_METADATA
- The image will
+ * conform to the metadata object passed in to a write.
+ * setTiling
will throw an
+ * IllegalStateException
.
+ *
+ * canWriteTiles
returns false
.
+ * @exception IllegalArgumentException if mode
is not
+ * one of the modes listed above.
+ *
+ * @see #setTiling
+ * @see #getTilingMode
+ */
+ public void setTilingMode(int mode) {
+ if (canWriteTiles() == false) {
+ throw new UnsupportedOperationException("Tiling not supported!");
+ }
+ if (mode < MODE_DISABLED || mode > MAX_MODE) {
+ throw new IllegalArgumentException("Illegal value for mode!");
+ }
+ this.tilingMode = mode;
+ if (mode == MODE_EXPLICIT) {
+ unsetTiling();
+ }
+ }
+
+ /**
+ * Returns the current tiling mode, if tiling is supported.
+ * Otherwise throws an UnsupportedOperationException
.
+ *
+ * @return the current tiling mode.
+ *
+ * @exception UnsupportedOperationException if
+ * canWriteTiles
returns false
.
+ *
+ * @see #setTilingMode
+ */
+ public int getTilingMode() {
+ if (!canWriteTiles()) {
+ throw new UnsupportedOperationException("Tiling not supported");
+ }
+ return tilingMode;
+ }
+
+ /**
+ * Returns an array of Dimension
s indicating the
+ * legal size ranges for tiles as they will be encoded in the
+ * output file or stream. The returned array is a copy.
+ *
+ * The information is returned as a set of pairs; the first
+ * element of a pair contains an (inclusive) minimum width and
+ * height, and the second element contains an (inclusive) maximum
+ * width and height. Together, each pair defines a valid range of
+ * sizes. To specify a fixed size, use the same width and height
+ * for both elements. To specify an arbitrary range, a value of
+ * null
is used in place of an actual array of
+ * Dimension
s.
+ *
+ *
If no array is specified on the constructor, but tiling is
+ * allowed, then this method returns null
.
+ *
+ * @exception UnsupportedOperationException if the plug-in does
+ * not support tiling.
+ *
+ * @return an array of Dimension
s with an even length
+ * of at least two, or null
.
+ */
+ public Dimension[] getPreferredTileSizes() {
+ if (!canWriteTiles()) {
+ throw new UnsupportedOperationException("Tiling not supported");
+ }
+ return clonePreferredTileSizes(preferredTileSizes);
+ }
+
+ /**
+ * Specifies that the image should be tiled in the output stream.
+ * The tileWidth
and tileHeight
+ * parameters specify the width and height of the tiles in the
+ * file. If the tile width or height is greater than the width or
+ * height of the image, the image is not tiled in that dimension.
+ *
+ *
If canOffsetTiles
returns false
,
+ * then the tileGridXOffset
and
+ * tileGridYOffset
parameters must be zero.
+ *
+ * @param tileWidth the width of each tile.
+ * @param tileHeight the height of each tile.
+ * @param tileGridXOffset the horizontal offset of the tile grid.
+ * @param tileGridYOffset the vertical offset of the tile grid.
+ *
+ * @exception UnsupportedOperationException if the plug-in does not
+ * support tiling.
+ * @exception IllegalStateException if the tiling mode is not
+ * MODE_EXPLICIT
.
+ * @exception UnsupportedOperationException if the plug-in does not
+ * support grid offsets, and the grid offsets are not both zero.
+ * @exception IllegalArgumentException if the tile size is not
+ * within one of the allowable ranges returned by
+ * getPreferredTileSizes
.
+ * @exception IllegalArgumentException if tileWidth
+ * or tileHeight
is less than or equal to 0.
+ *
+ * @see #canWriteTiles
+ * @see #canOffsetTiles
+ * @see #getTileWidth()
+ * @see #getTileHeight()
+ * @see #getTileGridXOffset()
+ * @see #getTileGridYOffset()
+ */
+ public void setTiling(int tileWidth,
+ int tileHeight,
+ int tileGridXOffset,
+ int tileGridYOffset) {
+ if (!canWriteTiles()) {
+ throw new UnsupportedOperationException("Tiling not supported!");
+ }
+ if (getTilingMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
+ }
+ if (tileWidth <= 0 || tileHeight <= 0) {
+ throw new IllegalArgumentException
+ ("tile dimensions are non-positive!");
+ }
+ boolean tilesOffset = (tileGridXOffset != 0) || (tileGridYOffset != 0);
+ if (!canOffsetTiles() && tilesOffset) {
+ throw new UnsupportedOperationException("Can't offset tiles!");
+ }
+ if (preferredTileSizes != null) {
+ boolean ok = true;
+ for (int i = 0; i < preferredTileSizes.length; i += 2) {
+ Dimension min = preferredTileSizes[i];
+ Dimension max = preferredTileSizes[i+1];
+ if ((tileWidth < min.width) ||
+ (tileWidth > max.width) ||
+ (tileHeight < min.height) ||
+ (tileHeight > max.height)) {
+ ok = false;
+ break;
+ }
+ }
+ if (!ok) {
+ throw new IllegalArgumentException("Illegal tile size!");
+ }
+ }
+
+ this.tilingSet = true;
+ this.tileWidth = tileWidth;
+ this.tileHeight = tileHeight;
+ this.tileGridXOffset = tileGridXOffset;
+ this.tileGridYOffset = tileGridYOffset;
+ }
+
+ /**
+ * Removes any previous tile grid parameters specified by calls to
+ * setTiling
.
+ *
+ *
The default implementation sets the instance variables
+ * tileWidth
, tileHeight
,
+ * tileGridXOffset
, and
+ * tileGridYOffset
to 0
.
+ *
+ * @exception UnsupportedOperationException if the plug-in does not
+ * support tiling.
+ * @exception IllegalStateException if the tiling mode is not
+ * MODE_EXPLICIT
.
+ *
+ * @see #setTiling(int, int, int, int)
+ */
+ public void unsetTiling() {
+ if (!canWriteTiles()) {
+ throw new UnsupportedOperationException("Tiling not supported!");
+ }
+ if (getTilingMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
+ }
+ this.tilingSet = false;
+ this.tileWidth = 0;
+ this.tileHeight = 0;
+ this.tileGridXOffset = 0;
+ this.tileGridYOffset = 0;
+ }
+
+ /**
+ * Returns the width of each tile in an image as it will be
+ * written to the output stream. If tiling parameters have not
+ * been set, an IllegalStateException
is thrown.
+ *
+ * @return the tile width to be used for encoding.
+ *
+ * @exception UnsupportedOperationException if the plug-in does not
+ * support tiling.
+ * @exception IllegalStateException if the tiling mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if the tiling parameters have
+ * not been set.
+ *
+ * @see #setTiling(int, int, int, int)
+ * @see #getTileHeight()
+ */
+ public int getTileWidth() {
+ if (!canWriteTiles()) {
+ throw new UnsupportedOperationException("Tiling not supported!");
+ }
+ if (getTilingMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
+ }
+ if (!tilingSet) {
+ throw new IllegalStateException("Tiling parameters not set!");
+ }
+ return tileWidth;
+ }
+
+ /**
+ * Returns the height of each tile in an image as it will be written to
+ * the output stream. If tiling parameters have not
+ * been set, an IllegalStateException
is thrown.
+ *
+ * @return the tile height to be used for encoding.
+ *
+ * @exception UnsupportedOperationException if the plug-in does not
+ * support tiling.
+ * @exception IllegalStateException if the tiling mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if the tiling parameters have
+ * not been set.
+ *
+ * @see #setTiling(int, int, int, int)
+ * @see #getTileWidth()
+ */
+ public int getTileHeight() {
+ if (!canWriteTiles()) {
+ throw new UnsupportedOperationException("Tiling not supported!");
+ }
+ if (getTilingMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
+ }
+ if (!tilingSet) {
+ throw new IllegalStateException("Tiling parameters not set!");
+ }
+ return tileHeight;
+ }
+
+ /**
+ * Returns the horizontal tile grid offset of an image as it will
+ * be written to the output stream. If tiling parameters have not
+ * been set, an IllegalStateException
is thrown.
+ *
+ * @return the tile grid X offset to be used for encoding.
+ *
+ * @exception UnsupportedOperationException if the plug-in does not
+ * support tiling.
+ * @exception IllegalStateException if the tiling mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if the tiling parameters have
+ * not been set.
+ *
+ * @see #setTiling(int, int, int, int)
+ * @see #getTileGridYOffset()
+ */
+ public int getTileGridXOffset() {
+ if (!canWriteTiles()) {
+ throw new UnsupportedOperationException("Tiling not supported!");
+ }
+ if (getTilingMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
+ }
+ if (!tilingSet) {
+ throw new IllegalStateException("Tiling parameters not set!");
+ }
+ return tileGridXOffset;
+ }
+
+ /**
+ * Returns the vertical tile grid offset of an image as it will
+ * be written to the output stream. If tiling parameters have not
+ * been set, an IllegalStateException
is thrown.
+ *
+ * @return the tile grid Y offset to be used for encoding.
+ *
+ * @exception UnsupportedOperationException if the plug-in does not
+ * support tiling.
+ * @exception IllegalStateException if the tiling mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if the tiling parameters have
+ * not been set.
+ *
+ * @see #setTiling(int, int, int, int)
+ * @see #getTileGridXOffset()
+ */
+ public int getTileGridYOffset() {
+ if (!canWriteTiles()) {
+ throw new UnsupportedOperationException("Tiling not supported!");
+ }
+ if (getTilingMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
+ }
+ if (!tilingSet) {
+ throw new IllegalStateException("Tiling parameters not set!");
+ }
+ return tileGridYOffset;
+ }
+
+ /**
+ * Returns true
if the writer can write out images
+ * as a series of passes of progressively increasing quality.
+ *
+ * @return true
if the writer supports progressive
+ * encoding.
+ *
+ * @see #setProgressiveMode
+ * @see #getProgressiveMode
+ */
+ public boolean canWriteProgressive() {
+ return canWriteProgressive;
+ }
+
+ /**
+ * Specifies that the writer is to write the image out in a
+ * progressive mode such that the stream will contain a series of
+ * scans of increasing quality. If progressive encoding is not
+ * supported, an UnsupportedOperationException
will
+ * be thrown.
+ *
+ *
The mode argument determines how
+ * the progression parameters are chosen, and must be either
+ * MODE_DISABLED
,
+ * MODE_COPY_FROM_METADATA
, or
+ * MODE_DEFAULT
. Otherwise an
+ * IllegalArgumentException
is thrown.
+ *
+ *
The modes are interpreted as follows: + * + *
MODE_DISABLED
- No progression. Use this to
+ * turn off progression.
+ *
+ * MODE_COPY_FROM_METADATA
- The output image
+ * will use whatever progression parameters are found in the
+ * metadata objects passed into the writer.
+ *
+ * MODE_DEFAULT
- The image will be written
+ * progressively, with parameters chosen by the writer.
+ * The default is MODE_COPY_FROM_METADATA
.
+ *
+ * @param mode The mode for setting progression in the output
+ * stream.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support progressive encoding.
+ * @exception IllegalArgumentException if mode
is not
+ * one of the modes listed above.
+ *
+ * @see #getProgressiveMode
+ */
+ public void setProgressiveMode(int mode) {
+ if (!canWriteProgressive()) {
+ throw new UnsupportedOperationException(
+ "Progressive output not supported");
+ }
+ if (mode < MODE_DISABLED || mode > MAX_MODE) {
+ throw new IllegalArgumentException("Illegal value for mode!");
+ }
+ if (mode == MODE_EXPLICIT) {
+ throw new IllegalArgumentException(
+ "MODE_EXPLICIT not supported for progressive output");
+ }
+ this.progressiveMode = mode;
+ }
+
+ /**
+ * Returns the current mode for writing the stream in a
+ * progressive manner.
+ *
+ * @return the current mode for progressive encoding.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support progressive encoding.
+ *
+ * @see #setProgressiveMode
+ */
+ public int getProgressiveMode() {
+ if (!canWriteProgressive()) {
+ throw new UnsupportedOperationException
+ ("Progressive output not supported");
+ }
+ return progressiveMode;
+ }
+
+ /**
+ * Returns true
if this writer supports compression.
+ *
+ * @return true
if the writer supports compression.
+ */
+ public boolean canWriteCompressed() {
+ return canWriteCompressed;
+ }
+
+ /**
+ * Specifies whether compression is to be performed, and if so how
+ * compression parameters are to be determined. The mode
+ * argument must be one of the four modes, interpreted as follows:
+ *
+ *
MODE_DISABLED
- If the mode is set to
+ * MODE_DISABLED
, methods that query or modify the
+ * compression type or parameters will throw an
+ * IllegalStateException
(if compression is
+ * normally supported by the plug-in). Some writers, such as JPEG,
+ * do not normally offer uncompressed output. In this case, attempting
+ * to set the mode to MODE_DISABLED
will throw an
+ * UnsupportedOperationException
and the mode will not be
+ * changed.
+ *
+ * MODE_EXPLICIT
- Compress using the
+ * compression type and quality settings specified in this
+ * ImageWriteParam
. Any previously set compression
+ * parameters are discarded.
+ *
+ * MODE_COPY_FROM_METADATA
- Use whatever
+ * compression parameters are specified in metadata objects
+ * passed in to the writer.
+ *
+ * MODE_DEFAULT
- Use default compression
+ * parameters.
+ * The default is MODE_COPY_FROM_METADATA
.
+ *
+ * @param mode The mode for setting compression in the output
+ * stream.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression, or does not support the requested mode.
+ * @exception IllegalArgumentException if mode
is not
+ * one of the modes listed above.
+ *
+ * @see #getCompressionMode
+ */
+ public void setCompressionMode(int mode) {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported.");
+ }
+ if (mode < MODE_DISABLED || mode > MAX_MODE) {
+ throw new IllegalArgumentException("Illegal value for mode!");
+ }
+ this.compressionMode = mode;
+ if (mode == MODE_EXPLICIT) {
+ unsetCompression();
+ }
+ }
+
+ /**
+ * Returns the current compression mode, if compression is
+ * supported.
+ *
+ * @return the current compression mode.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ *
+ * @see #setCompressionMode
+ */
+ public int getCompressionMode() {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported.");
+ }
+ return compressionMode;
+ }
+
+ /**
+ * Returns a list of available compression types, as an array or
+ * String
s, or null
if a compression
+ * type may not be chosen using these interfaces. The array
+ * returned is a copy.
+ *
+ *
If the writer only offers a single, mandatory form of + * compression, it is not necessary to provide any named + * compression types. Named compression types should only be + * used where the user is able to make a meaningful choice + * between different schemes. + * + *
The default implementation checks if compression is
+ * supported and throws an
+ * UnsupportedOperationException
if not. Otherwise,
+ * it returns a clone of the compressionTypes
+ * instance variable if it is non-null
, or else
+ * returns null
.
+ *
+ * @return an array of String
s containing the
+ * (non-localized) names of available compression types, or
+ * null
.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ */
+ public String[] getCompressionTypes() {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported");
+ }
+ if (compressionTypes == null) {
+ return null;
+ }
+ return compressionTypes.clone();
+ }
+
+ /**
+ * Sets the compression type to one of the values indicated by
+ * getCompressionTypes
. If a value of
+ * null
is passed in, any previous setting is
+ * removed.
+ *
+ *
The default implementation checks whether compression is
+ * supported and the compression mode is
+ * MODE_EXPLICIT
. If so, it calls
+ * getCompressionTypes
and checks if
+ * compressionType
is one of the legal values. If it
+ * is, the compressionType
instance variable is set.
+ * If compressionType
is null
, the
+ * instance variable is set without performing any checking.
+ *
+ * @param compressionType one of the String
s returned
+ * by getCompressionTypes
, or null
to
+ * remove any previous setting.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ * @exception IllegalStateException if the compression mode is not
+ * MODE_EXPLICIT
.
+ * @exception UnsupportedOperationException if there are no
+ * settable compression types.
+ * @exception IllegalArgumentException if
+ * compressionType
is non-null
but is not
+ * one of the values returned by getCompressionTypes
.
+ *
+ * @see #getCompressionTypes
+ * @see #getCompressionType
+ * @see #unsetCompression
+ */
+ public void setCompressionType(String compressionType) {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported");
+ }
+ if (getCompressionMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException
+ ("Compression mode not MODE_EXPLICIT!");
+ }
+ String[] legalTypes = getCompressionTypes();
+ if (legalTypes == null) {
+ throw new UnsupportedOperationException(
+ "No settable compression types");
+ }
+ if (compressionType != null) {
+ boolean found = false;
+ if (legalTypes != null) {
+ for (int i = 0; i < legalTypes.length; i++) {
+ if (compressionType.equals(legalTypes[i])) {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ throw new IllegalArgumentException("Unknown compression type!");
+ }
+ }
+ this.compressionType = compressionType;
+ }
+
+ /**
+ * Returns the currently set compression type, or
+ * null
if none has been set. The type is returned
+ * as a String
from among those returned by
+ * getCompressionTypes
.
+ * If no compression type has been set, null
is
+ * returned.
+ *
+ *
The default implementation checks whether compression is
+ * supported and the compression mode is
+ * MODE_EXPLICIT
. If so, it returns the value of the
+ * compressionType
instance variable.
+ *
+ * @return the current compression type as a String
,
+ * or null
if no type is set.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ * @exception IllegalStateException if the compression mode is not
+ * MODE_EXPLICIT
.
+ *
+ * @see #setCompressionType
+ */
+ public String getCompressionType() {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported.");
+ }
+ if (getCompressionMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException
+ ("Compression mode not MODE_EXPLICIT!");
+ }
+ return compressionType;
+ }
+
+ /**
+ * Removes any previous compression type and quality settings.
+ *
+ *
The default implementation sets the instance variable
+ * compressionType
to null
, and the
+ * instance variable compressionQuality
to
+ * 1.0F
.
+ *
+ * @exception UnsupportedOperationException if the plug-in does not
+ * support compression.
+ * @exception IllegalStateException if the compression mode is not
+ * MODE_EXPLICIT
.
+ *
+ * @see #setCompressionType
+ * @see #setCompressionQuality
+ */
+ public void unsetCompression() {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported");
+ }
+ if (getCompressionMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException
+ ("Compression mode not MODE_EXPLICIT!");
+ }
+ this.compressionType = null;
+ this.compressionQuality = 1.0F;
+ }
+
+ /**
+ * Returns a localized version of the name of the current
+ * compression type, using the Locale
returned by
+ * getLocale
.
+ *
+ *
The default implementation checks whether compression is
+ * supported and the compression mode is
+ * MODE_EXPLICIT
. If so, if
+ * compressionType
is non-null
the value
+ * of getCompressionType
is returned as a
+ * convenience.
+ *
+ * @return a String
containing a localized version of
+ * the name of the current compression type.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ * @exception IllegalStateException if the compression mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if no compression type is set.
+ */
+ public String getLocalizedCompressionTypeName() {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported.");
+ }
+ if (getCompressionMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException
+ ("Compression mode not MODE_EXPLICIT!");
+ }
+ if (getCompressionType() == null) {
+ throw new IllegalStateException("No compression type set!");
+ }
+ return getCompressionType();
+ }
+
+ /**
+ * Returns true
if the current compression type
+ * provides lossless compression. If a plug-in provides only
+ * one mandatory compression type, then this method may be
+ * called without calling setCompressionType
first.
+ *
+ *
If there are multiple compression types but none has
+ * been set, an IllegalStateException
is thrown.
+ *
+ *
The default implementation checks whether compression is
+ * supported and the compression mode is
+ * MODE_EXPLICIT
. If so, if
+ * getCompressionTypes()
is null
or
+ * getCompressionType()
is non-null
+ * true
is returned as a convenience.
+ *
+ * @return true
if the current compression type is
+ * lossless.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ * @exception IllegalStateException if the compression mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if the set of legal
+ * compression types is non-null
and the current
+ * compression type is null
.
+ */
+ public boolean isCompressionLossless() {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported");
+ }
+ if (getCompressionMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException
+ ("Compression mode not MODE_EXPLICIT!");
+ }
+ if ((getCompressionTypes() != null) &&
+ (getCompressionType() == null)) {
+ throw new IllegalStateException("No compression type set!");
+ }
+ return true;
+ }
+
+ /**
+ * Sets the compression quality to a value between 0
+ * and 1
. Only a single compression quality setting
+ * is supported by default; writers can provide extended versions
+ * of ImageWriteParam
that offer more control. For
+ * lossy compression schemes, the compression quality should
+ * control the tradeoff between file size and image quality (for
+ * example, by choosing quantization tables when writing JPEG
+ * images). For lossless schemes, the compression quality may be
+ * used to control the tradeoff between file size and time taken
+ * to perform the compression (for example, by optimizing row
+ * filters and setting the ZLIB compression level when writing
+ * PNG images).
+ *
+ *
A compression quality setting of 0.0 is most generically + * interpreted as "high compression is important," while a setting of + * 1.0 is most generically interpreted as "high image quality is + * important." + * + *
If there are multiple compression types but none has been
+ * set, an IllegalStateException
is thrown.
+ *
+ *
The default implementation checks that compression is
+ * supported, and that the compression mode is
+ * MODE_EXPLICIT
. If so, if
+ * getCompressionTypes()
returns null
or
+ * compressionType
is non-null
it sets
+ * the compressionQuality
instance variable.
+ *
+ * @param quality a float
between 0
and
+ * 1
indicating the desired quality level.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ * @exception IllegalStateException if the compression mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if the set of legal
+ * compression types is non-null
and the current
+ * compression type is null
.
+ * @exception IllegalArgumentException if quality
is
+ * not between 0
and 1
, inclusive.
+ *
+ * @see #getCompressionQuality
+ */
+ public void setCompressionQuality(float quality) {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported");
+ }
+ if (getCompressionMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException
+ ("Compression mode not MODE_EXPLICIT!");
+ }
+ if (getCompressionTypes() != null && getCompressionType() == null) {
+ throw new IllegalStateException("No compression type set!");
+ }
+ if (quality < 0.0F || quality > 1.0F) {
+ throw new IllegalArgumentException("Quality out-of-bounds!");
+ }
+ this.compressionQuality = quality;
+ }
+
+ /**
+ * Returns the current compression quality setting.
+ *
+ *
If there are multiple compression types but none has been
+ * set, an IllegalStateException
is thrown.
+ *
+ *
The default implementation checks that compression is
+ * supported and that the compression mode is
+ * MODE_EXPLICIT
. If so, if
+ * getCompressionTypes()
is null
or
+ * getCompressionType()
is non-null
, it
+ * returns the value of the compressionQuality
+ * instance variable.
+ *
+ * @return the current compression quality setting.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ * @exception IllegalStateException if the compression mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if the set of legal
+ * compression types is non-null
and the current
+ * compression type is null
.
+ *
+ * @see #setCompressionQuality
+ */
+ public float getCompressionQuality() {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported.");
+ }
+ if (getCompressionMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException
+ ("Compression mode not MODE_EXPLICIT!");
+ }
+ if ((getCompressionTypes() != null) &&
+ (getCompressionType() == null)) {
+ throw new IllegalStateException("No compression type set!");
+ }
+ return compressionQuality;
+ }
+
+
+ /**
+ * Returns a float
indicating an estimate of the
+ * number of bits of output data for each bit of input image data
+ * at the given quality level. The value will typically lie
+ * between 0
and 1
, with smaller values
+ * indicating more compression. A special value of
+ * -1.0F
is used to indicate that no estimate is
+ * available.
+ *
+ *
If there are multiple compression types but none has been set,
+ * an IllegalStateException
is thrown.
+ *
+ *
The default implementation checks that compression is
+ * supported and the compression mode is
+ * MODE_EXPLICIT
. If so, if
+ * getCompressionTypes()
is null
or
+ * getCompressionType()
is non-null
, and
+ * quality
is within bounds, it returns
+ * -1.0
.
+ *
+ * @param quality the quality setting whose bit rate is to be
+ * queried.
+ *
+ * @return an estimate of the compressed bit rate, or
+ * -1.0F
if no estimate is available.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ * @exception IllegalStateException if the compression mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if the set of legal
+ * compression types is non-null
and the current
+ * compression type is null
.
+ * @exception IllegalArgumentException if quality
is
+ * not between 0
and 1
, inclusive.
+ */
+ public float getBitRate(float quality) {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported.");
+ }
+ if (getCompressionMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException
+ ("Compression mode not MODE_EXPLICIT!");
+ }
+ if ((getCompressionTypes() != null) &&
+ (getCompressionType() == null)) {
+ throw new IllegalStateException("No compression type set!");
+ }
+ if (quality < 0.0F || quality > 1.0F) {
+ throw new IllegalArgumentException("Quality out-of-bounds!");
+ }
+ return -1.0F;
+ }
+
+ /**
+ * Returns an array of String
s that may be used along
+ * with getCompressionQualityValues
as part of a user
+ * interface for setting or displaying the compression quality
+ * level. The String
with index i
+ * provides a description of the range of quality levels between
+ * getCompressionQualityValues[i]
and
+ * getCompressionQualityValues[i + 1]
. Note that the
+ * length of the array returned from
+ * getCompressionQualityValues
will always be one
+ * greater than that returned from
+ * getCompressionQualityDescriptions
.
+ *
+ *
As an example, the strings "Good", "Better", and "Best"
+ * could be associated with the ranges [0, .33)
,
+ * [.33, .66)
, and [.66, 1.0]
. In this
+ * case, getCompressionQualityDescriptions
would
+ * return { "Good", "Better", "Best" }
and
+ * getCompressionQualityValues
would return
+ * { 0.0F, .33F, .66F, 1.0F }
.
+ *
+ *
If no descriptions are available, null
is
+ * returned. If null
is returned from
+ * getCompressionQualityValues
, this method must also
+ * return null
.
+ *
+ *
The descriptions should be localized for the
+ * Locale
returned by getLocale
, if it
+ * is non-null
.
+ *
+ *
If there are multiple compression types but none has been set,
+ * an IllegalStateException
is thrown.
+ *
+ *
The default implementation checks that compression is
+ * supported and that the compression mode is
+ * MODE_EXPLICIT
. If so, if
+ * getCompressionTypes()
is null
or
+ * getCompressionType()
is non-null
, it
+ * returns null
.
+ *
+ * @return an array of String
s containing localized
+ * descriptions of the compression quality levels.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ * @exception IllegalStateException if the compression mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if the set of legal
+ * compression types is non-null
and the current
+ * compression type is null
.
+ *
+ * @see #getCompressionQualityValues
+ */
+ public String[] getCompressionQualityDescriptions() {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported.");
+ }
+ if (getCompressionMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException
+ ("Compression mode not MODE_EXPLICIT!");
+ }
+ if ((getCompressionTypes() != null) &&
+ (getCompressionType() == null)) {
+ throw new IllegalStateException("No compression type set!");
+ }
+ return null;
+ }
+
+ /**
+ * Returns an array of float
s that may be used along
+ * with getCompressionQualityDescriptions
as part of a user
+ * interface for setting or displaying the compression quality
+ * level. See {@link #getCompressionQualityDescriptions
+ * getCompressionQualityDescriptions} for more information.
+ *
+ *
If no descriptions are available, null
is
+ * returned. If null
is returned from
+ * getCompressionQualityDescriptions
, this method
+ * must also return null
.
+ *
+ *
If there are multiple compression types but none has been set,
+ * an IllegalStateException
is thrown.
+ *
+ *
The default implementation checks that compression is
+ * supported and that the compression mode is
+ * MODE_EXPLICIT
. If so, if
+ * getCompressionTypes()
is null
or
+ * getCompressionType()
is non-null
, it
+ * returns null
.
+ *
+ * @return an array of float
s indicating the
+ * boundaries between the compression quality levels as described
+ * by the String
s from
+ * getCompressionQualityDescriptions
.
+ *
+ * @exception UnsupportedOperationException if the writer does not
+ * support compression.
+ * @exception IllegalStateException if the compression mode is not
+ * MODE_EXPLICIT
.
+ * @exception IllegalStateException if the set of legal
+ * compression types is non-null
and the current
+ * compression type is null
.
+ *
+ * @see #getCompressionQualityDescriptions
+ */
+ public float[] getCompressionQualityValues() {
+ if (!canWriteCompressed()) {
+ throw new UnsupportedOperationException(
+ "Compression not supported.");
+ }
+ if (getCompressionMode() != MODE_EXPLICIT) {
+ throw new IllegalStateException
+ ("Compression mode not MODE_EXPLICIT!");
+ }
+ if ((getCompressionTypes() != null) &&
+ (getCompressionType() == null)) {
+ throw new IllegalStateException("No compression type set!");
+ }
+ return null;
+ }
+}