/*
 * 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 {@code ImageWriter}.
 *
 * <p> A plug-in for a specific image format may define a subclass of
 * this class, and return objects of that class from the
 * {@code getDefaultWriteParam} method of its
 * {@code ImageWriter} implementation.  For example, the built-in
 * JPEG writer plug-in will return instances of
 * {@code javax.imageio.plugins.jpeg.JPEGImageWriteParam}.
 *
 * <p> The region of the image to be written is determined by first
 * intersecting the actual bounds of the image with the rectangle
 * specified by {@code IIOParam.setSourceRegion}, if any.  If the
 * resulting rectangle has a width or height of zero, the writer will
 * throw an {@code 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}.
 *
 * <p> Individual features such as tiling, progressive encoding, and
 * compression may be set in one of four modes.
 * {@code MODE_DISABLED} disables the features;
 * {@code MODE_DEFAULT} enables the feature with
 * writer-controlled parameter values; {@code MODE_EXPLICIT}
 * enables the feature and allows the use of a {@code set} method
 * to provide additional parameters; and
 * {@code 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
 * {@code MODE_COPY_FROM_METADATA}.  Non-standard features
 * supplied in subclasses are encouraged, but not required to use a
 * similar scheme.
 *
 * <p> Plug-in writers may extend the functionality of
 * {@code 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
 * {@code ImageWriteParam} subclass of which they are not aware.
 * Also, they may ignore any optional features that they normally
 * disable when creating their own {@code ImageWriteParam}
 * instances via {@code getDefaultWriteParam}.
 *
 * <p> Note that unless a query method exists for a capability, it must
 * be supported by all {@code ImageWriter} implementations
 * (<i>e.g.</i> 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
     * {@code setTilingMode}, {@code setProgressiveMode},
     * and {@code setCompressionMode} to disable a feature for
     * future writes.  That is, when this mode is set the stream will
     * <b>not</b> be tiled, progressive, or compressed, and the
     * relevant accessor methods will throw an
     * {@code 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
     * {@code setTilingMode},
     * {@code setProgressiveMode}, and
     * {@code 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 {@code 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
     * {@code setTilingMode} or {@code 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
     * {@code set} methods in this class and retrievable from the
     * corresponding {@code 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
     * {@code setTilingMode}, {@code setProgressiveMode}, or
     * {@code 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
     * {@code IllegalStateException}.
     *
     * <p> 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 {@code boolean} that is {@code true} if this
     * {@code ImageWriteParam} allows tile width and tile height
     * parameters to be set.  By default, the value is
     * {@code false}.  Subclasses must set the value manually.
     *
     * <p> Subclasses that do not support writing tiles should ensure
     * that this value is set to {@code false}.
     */
    protected boolean canWriteTiles = false;

    /**
     * The mode controlling tiling settings, which Must be
     * set to one of the four {@code MODE_*} values.  The default
     * is {@code MODE_COPY_FROM_METADATA}.
     *
     * <p> 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 {@code null}, which indicates that there are no
     * preferred sizes.  If the value is non-{@code null}, it
     * must have an even length of at least two.
     *
     * <p> Subclasses that do not support writing tiles may ignore
     * this value.
     *
     * @see #getPreferredTileSizes
     */
    protected Dimension[] preferredTileSizes = null;

    /**
     * A {@code boolean} that is {@code true} if tiling
     * parameters have been specified.
     *
     * <p> 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.
     *
     * <p> 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 {@code 0}.
     *
     * <p> Subclasses that do not support tiling may ignore this
     * value.
     */
    protected int tileHeight = 0;

    /**
     * A {@code boolean} that is {@code true} if this
     * {@code ImageWriteParam} allows tiling grid offset
     * parameters to be set.  By default, the value is
     * {@code false}.  Subclasses must set the value manually.
     *
     * <p> Subclasses that do not support writing tiles, or that
     * support writing but not offsetting tiles must ensure that this
     * value is set to {@code 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 {@code 0}.
     *
     * <p> 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 {@code 0}.
     *
     * <p> Subclasses that do not support offsetting tiles may ignore
     * this value.
     */
    protected int tileGridYOffset = 0;

    /**
     * A {@code boolean} that is {@code true} if this
     * {@code ImageWriteParam} allows images to be written as a
     * progressive sequence of increasing quality passes.  By default,
     * the value is {@code false}.  Subclasses must set the value
     * manually.
     *
     * <p> Subclasses that do not support progressive encoding must
     * ensure that this value is set to {@code false}.
     */
    protected boolean canWriteProgressive = false;

    /**
     * The mode controlling progressive encoding, which must be set to
     * one of the four {@code MODE_*} values, except
     * {@code MODE_EXPLICIT}.  The default is
     * {@code MODE_COPY_FROM_METADATA}.
     *
     * <p> 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 {@code boolean} that is {@code true} if this writer
     * can write images using compression. By default, the value is
     * {@code false}.  Subclasses must set the value manually.
     *
     * <p> Subclasses that do not support compression must ensure that
     * this value is set to {@code false}.
     */
    protected boolean canWriteCompressed = false;

    /**
     * The mode controlling compression settings, which must be set to
     * one of the four {@code MODE_*} values.  The default is
     * {@code MODE_COPY_FROM_METADATA}.
     *
     * <p> 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 {@code String}s containing the names of the
     * available compression types.  Subclasses must set the value
     * manually.
     *
     * <p> Subclasses that do not support compression may ignore this
     * value.
     */
    protected String[] compressionTypes = null;

    /**
     * A {@code String} containing the name of the current
     * compression type, or {@code null} if none is set.
     *
     * <p> Subclasses that do not support compression may ignore this
     * value.
     */
    protected String compressionType = null;

    /**
     * A {@code float} containing the current compression quality
     * setting.  The initial value is {@code 1.0F}.
     *
     * <p> Subclasses that do not support compression may ignore this
     * value.
     */
    protected float compressionQuality = 1.0F;

    /**
     * A {@code Locale} to be used to localize compression type
     * names and quality descriptions, or {@code null} to use a
     * default {@code Locale}.  Subclasses must set the value
     * manually.
     */
    protected Locale locale = null;

    /**
     * Constructs an empty {@code ImageWriteParam}.  It is up to
     * the subclass to set up the instance variables properly.
     */
    protected ImageWriteParam() {}

    /**
     * Constructs an {@code ImageWriteParam} set to use a
     * given {@code Locale}.
     *
     * @param locale a {@code Locale} to be used to localize
     * compression type names and quality descriptions, or
     * {@code 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 {@code Locale}, or
     * {@code null} if only a default {@code Locale} is
     * supported.
     *
     * @return the current {@code Locale}, or {@code null}.
     */
    public Locale getLocale() {
        return locale;
    }

    /**
     * Returns {@code true} if the writer can perform tiling
     * while writing.  If this method returns {@code false}, then
     * {@code setTiling} will throw an
     * {@code UnsupportedOperationException}.
     *
     * @return {@code true} if the writer supports tiling.
     *
     * @see #canOffsetTiles()
     * @see #setTiling(int, int, int, int)
     */
    public boolean canWriteTiles() {
        return canWriteTiles;
    }

    /**
     * Returns {@code true} if the writer can perform tiling with
     * non-zero grid offsets while writing.  If this method returns
     * {@code false}, then {@code setTiling} will throw an
     * {@code UnsupportedOperationException} if the grid offset
     * arguments are not both zero.  If {@code canWriteTiles}
     * returns {@code false}, this method will return
     * {@code false} as well.
     *
     * @return {@code 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:
     *
     * <ul>
     *
     * <li>{@code MODE_DISABLED} - The image will not be tiled.
     * {@code setTiling} will throw an
     * {@code IllegalStateException}.
     *
     * <li>{@code MODE_DEFAULT} - The image will be tiled using
     * default parameters.  {@code setTiling} will throw an
     * {@code IllegalStateException}.
     *
     * <li>{@code MODE_EXPLICIT} - The image will be tiled
     * according to parameters given in the {@link #setTiling setTiling}
     * method.  Any previously set tiling parameters are discarded.
     *
     * <li>{@code MODE_COPY_FROM_METADATA} - The image will
     * conform to the metadata object passed in to a write.
     * {@code setTiling} will throw an
     * {@code IllegalStateException}.
     *
     * </ul>
     *
     * @param mode The mode to use for tiling.
     *
     * @throws UnsupportedOperationException if
     * {@code canWriteTiles} returns {@code false}.
     * @throws IllegalArgumentException if {@code 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 {@code UnsupportedOperationException}.
     *
     * @return the current tiling mode.
     *
     * @throws UnsupportedOperationException if
     * {@code canWriteTiles} returns {@code false}.
     *
     * @see #setTilingMode
     */
    public int getTilingMode() {
        if (!canWriteTiles()) {
            throw new UnsupportedOperationException("Tiling not supported");
        }
        return tilingMode;
    }

    /**
     * Returns an array of {@code 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.
     *
     * <p> 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
     * {@code null} is used in place of an actual array of
     * {@code Dimension}s.
     *
     * <p> If no array is specified on the constructor, but tiling is
     * allowed, then this method returns {@code null}.
     *
     * @throws UnsupportedOperationException if the plug-in does
     * not support tiling.
     *
     * @return an array of {@code Dimension}s with an even length
     * of at least two, or {@code 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 {@code tileWidth} and {@code 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.
     *
     * <p> If {@code canOffsetTiles} returns {@code false},
     * then the {@code tileGridXOffset} and
     * {@code 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.
     *
     * @throws UnsupportedOperationException if the plug-in does not
     * support tiling.
     * @throws IllegalStateException if the tiling mode is not
     * {@code MODE_EXPLICIT}.
     * @throws UnsupportedOperationException if the plug-in does not
     * support grid offsets, and the grid offsets are not both zero.
     * @throws IllegalArgumentException if the tile size is not
     * within one of the allowable ranges returned by
     * {@code getPreferredTileSizes}.
     * @throws IllegalArgumentException if {@code tileWidth}
     * or {@code 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
     * {@code setTiling}.
     *
     * <p> The default implementation sets the instance variables
     * {@code tileWidth}, {@code tileHeight},
     * {@code tileGridXOffset}, and
     * {@code tileGridYOffset} to {@code 0}.
     *
     * @throws UnsupportedOperationException if the plug-in does not
     * support tiling.
     * @throws IllegalStateException if the tiling mode is not
     * {@code 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 {@code IllegalStateException} is thrown.
     *
     * @return the tile width to be used for encoding.
     *
     * @throws UnsupportedOperationException if the plug-in does not
     * support tiling.
     * @throws IllegalStateException if the tiling mode is not
     * {@code MODE_EXPLICIT}.
     * @throws 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 {@code IllegalStateException} is thrown.
     *
     * @return the tile height to be used for encoding.
     *
     * @throws UnsupportedOperationException if the plug-in does not
     * support tiling.
     * @throws IllegalStateException if the tiling mode is not
     * {@code MODE_EXPLICIT}.
     * @throws 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 {@code IllegalStateException} is thrown.
     *
     * @return the tile grid X offset to be used for encoding.
     *
     * @throws UnsupportedOperationException if the plug-in does not
     * support tiling.
     * @throws IllegalStateException if the tiling mode is not
     * {@code MODE_EXPLICIT}.
     * @throws 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 {@code IllegalStateException} is thrown.
     *
     * @return the tile grid Y offset to be used for encoding.
     *
     * @throws UnsupportedOperationException if the plug-in does not
     * support tiling.
     * @throws IllegalStateException if the tiling mode is not
     * {@code MODE_EXPLICIT}.
     * @throws 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 {@code true} if the writer can write out images
     * as a series of passes of progressively increasing quality.
     *
     * @return {@code 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 {@code UnsupportedOperationException} will
     * be thrown.
     *
     * <p>  The mode argument determines how
     * the progression parameters are chosen, and must be either
     * {@code MODE_DISABLED},
     * {@code MODE_COPY_FROM_METADATA}, or
     * {@code MODE_DEFAULT}.  Otherwise an
     * {@code IllegalArgumentException} is thrown.
     *
     * <p> The modes are interpreted as follows:
     *
     * <ul>
     *   <li>{@code MODE_DISABLED} - No progression.  Use this to
     *   turn off progression.
     *
     *   <li>{@code MODE_COPY_FROM_METADATA} - The output image
     *   will use whatever progression parameters are found in the
     *   metadata objects passed into the writer.
     *
     *   <li>{@code MODE_DEFAULT} - The image will be written
     *   progressively, with parameters chosen by the writer.
     * </ul>
     *
     * <p> The default is {@code MODE_COPY_FROM_METADATA}.
     *
     * @param mode The mode for setting progression in the output
     * stream.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support progressive encoding.
     * @throws IllegalArgumentException if {@code 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.
     *
     * @throws 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 {@code true} if this writer supports compression.
     *
     * @return {@code 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 {@code mode}
     * argument must be one of the four modes, interpreted as follows:
     *
     * <ul>
     *   <li>{@code MODE_DISABLED} - If the mode is set to
     *   {@code MODE_DISABLED}, methods that query or modify the
     *   compression type or parameters will throw an
     *   {@code 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 {@code MODE_DISABLED} will throw an
     *   {@code UnsupportedOperationException} and the mode will not be
     *   changed.
     *
     *   <li>{@code MODE_EXPLICIT} - Compress using the
     *   compression type and quality settings specified in this
     *   {@code ImageWriteParam}.  Any previously set compression
     *   parameters are discarded.
     *
     *   <li>{@code MODE_COPY_FROM_METADATA} - Use whatever
     *   compression parameters are specified in metadata objects
     *   passed in to the writer.
     *
     *   <li>{@code MODE_DEFAULT} - Use default compression
     *   parameters.
     * </ul>
     *
     * <p> The default is {@code MODE_COPY_FROM_METADATA}.
     *
     * @param mode The mode for setting compression in the output
     * stream.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support compression, or does not support the requested mode.
     * @throws IllegalArgumentException if {@code 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.
     *
     * @throws 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
     * {@code String}s, or {@code null} if a compression
     * type may not be chosen using these interfaces.  The array
     * returned is a copy.
     *
     * <p> 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.
     *
     * <p> The default implementation checks if compression is
     * supported and throws an
     * {@code UnsupportedOperationException} if not.  Otherwise,
     * it returns a clone of the {@code compressionTypes}
     * instance variable if it is non-{@code null}, or else
     * returns {@code null}.
     *
     * @return an array of {@code String}s containing the
     * (non-localized) names of available compression types, or
     * {@code null}.
     *
     * @throws 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
     * {@code getCompressionTypes}.  If a value of
     * {@code null} is passed in, any previous setting is
     * removed.
     *
     * <p> The default implementation checks whether compression is
     * supported and the compression mode is
     * {@code MODE_EXPLICIT}.  If so, it calls
     * {@code getCompressionTypes} and checks if
     * {@code compressionType} is one of the legal values.  If it
     * is, the {@code compressionType} instance variable is set.
     * If {@code compressionType} is {@code null}, the
     * instance variable is set without performing any checking.
     *
     * @param compressionType one of the {@code String}s returned
     * by {@code getCompressionTypes}, or {@code null} to
     * remove any previous setting.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support compression.
     * @throws IllegalStateException if the compression mode is not
     * {@code MODE_EXPLICIT}.
     * @throws UnsupportedOperationException if there are no
     * settable compression types.
     * @throws IllegalArgumentException if
     * {@code compressionType} is non-{@code null} but is not
     * one of the values returned by {@code 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
     * {@code null} if none has been set.  The type is returned
     * as a {@code String} from among those returned by
     * {@code getCompressionTypes}.
     * If no compression type has been set, {@code null} is
     * returned.
     *
     * <p> The default implementation checks whether compression is
     * supported and the compression mode is
     * {@code MODE_EXPLICIT}.  If so, it returns the value of the
     * {@code compressionType} instance variable.
     *
     * @return the current compression type as a {@code String},
     * or {@code null} if no type is set.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support compression.
     * @throws IllegalStateException if the compression mode is not
     * {@code 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.
     *
     * <p> The default implementation sets the instance variable
     * {@code compressionType} to {@code null}, and the
     * instance variable {@code compressionQuality} to
     * {@code 1.0F}.
     *
     * @throws UnsupportedOperationException if the plug-in does not
     * support compression.
     * @throws IllegalStateException if the compression mode is not
     * {@code 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 {@code Locale} returned by
     * {@code getLocale}.
     *
     * <p> The default implementation checks whether compression is
     * supported and the compression mode is
     * {@code MODE_EXPLICIT}.  If so, if
     * {@code compressionType} is {@code non-null} the value
     * of {@code getCompressionType} is returned as a
     * convenience.
     *
     * @return a {@code String} containing a localized version of
     * the name of the current compression type.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support compression.
     * @throws IllegalStateException if the compression mode is not
     * {@code MODE_EXPLICIT}.
     * @throws 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 {@code 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 {@code setCompressionType} first.
     *
     * <p> If there are multiple compression types but none has
     * been set, an {@code IllegalStateException} is thrown.
     *
     * <p> The default implementation checks whether compression is
     * supported and the compression mode is
     * {@code MODE_EXPLICIT}.  If so, if
     * {@code getCompressionTypes()} is {@code null} or
     * {@code getCompressionType()} is non-{@code null}
     * {@code true} is returned as a convenience.
     *
     * @return {@code true} if the current compression type is
     * lossless.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support compression.
     * @throws IllegalStateException if the compression mode is not
     * {@code MODE_EXPLICIT}.
     * @throws IllegalStateException if the set of legal
     * compression types is non-{@code null} and the current
     * compression type is {@code 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 {@code 0}
     * and {@code 1}.  Only a single compression quality setting
     * is supported by default; writers can provide extended versions
     * of {@code 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).
     *
     * <p> 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."
     *
     * <p> If there are multiple compression types but none has been
     * set, an {@code IllegalStateException} is thrown.
     *
     * <p> The default implementation checks that compression is
     * supported, and that the compression mode is
     * {@code MODE_EXPLICIT}.  If so, if
     * {@code getCompressionTypes()} returns {@code null} or
     * {@code compressionType} is non-{@code null} it sets
     * the {@code compressionQuality} instance variable.
     *
     * @param quality a {@code float} between {@code 0} and
     * {@code 1} indicating the desired quality level.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support compression.
     * @throws IllegalStateException if the compression mode is not
     * {@code MODE_EXPLICIT}.
     * @throws IllegalStateException if the set of legal
     * compression types is non-{@code null} and the current
     * compression type is {@code null}.
     * @throws IllegalArgumentException if {@code quality} is
     * not between {@code 0} and {@code 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.
     *
     * <p> If there are multiple compression types but none has been
     * set, an {@code IllegalStateException} is thrown.
     *
     * <p> The default implementation checks that compression is
     * supported and that the compression mode is
     * {@code MODE_EXPLICIT}.  If so, if
     * {@code getCompressionTypes()} is {@code null} or
     * {@code getCompressionType()} is non-{@code null}, it
     * returns the value of the {@code compressionQuality}
     * instance variable.
     *
     * @return the current compression quality setting.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support compression.
     * @throws IllegalStateException if the compression mode is not
     * {@code MODE_EXPLICIT}.
     * @throws IllegalStateException if the set of legal
     * compression types is non-{@code null} and the current
     * compression type is {@code 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 {@code 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 {@code 0} and {@code 1}, with smaller values
     * indicating more compression.  A special value of
     * {@code -1.0F} is used to indicate that no estimate is
     * available.
     *
     * <p> If there are multiple compression types but none has been set,
     * an {@code IllegalStateException} is thrown.
     *
     * <p> The default implementation checks that compression is
     * supported and the compression mode is
     * {@code MODE_EXPLICIT}.  If so, if
     * {@code getCompressionTypes()} is {@code null} or
     * {@code getCompressionType()} is non-{@code null}, and
     * {@code quality} is within bounds, it returns
     * {@code -1.0}.
     *
     * @param quality the quality setting whose bit rate is to be
     * queried.
     *
     * @return an estimate of the compressed bit rate, or
     * {@code -1.0F} if no estimate is available.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support compression.
     * @throws IllegalStateException if the compression mode is not
     * {@code MODE_EXPLICIT}.
     * @throws IllegalStateException if the set of legal
     * compression types is non-{@code null} and the current
     * compression type is {@code null}.
     * @throws IllegalArgumentException if {@code quality} is
     * not between {@code 0} and {@code 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 {@code String}s that may be used along
     * with {@code getCompressionQualityValues} as part of a user
     * interface for setting or displaying the compression quality
     * level.  The {@code String} with index {@code i}
     * provides a description of the range of quality levels between
     * {@code getCompressionQualityValues[i]} and
     * {@code getCompressionQualityValues[i + 1]}.  Note that the
     * length of the array returned from
     * {@code getCompressionQualityValues} will always be one
     * greater than that returned from
     * {@code getCompressionQualityDescriptions}.
     *
     * <p> As an example, the strings "Good", "Better", and "Best"
     * could be associated with the ranges {@code [0, .33)},
     * {@code [.33, .66)}, and {@code [.66, 1.0]}.  In this
     * case, {@code getCompressionQualityDescriptions} would
     * return {@code { "Good", "Better", "Best" }} and
     * {@code getCompressionQualityValues} would return
     * {@code { 0.0F, .33F, .66F, 1.0F }}.
     *
     * <p> If no descriptions are available, {@code null} is
     * returned.  If {@code null} is returned from
     * {@code getCompressionQualityValues}, this method must also
     * return {@code null}.
     *
     * <p> The descriptions should be localized for the
     * {@code Locale} returned by {@code getLocale}, if it
     * is non-{@code null}.
     *
     * <p> If there are multiple compression types but none has been set,
     * an {@code IllegalStateException} is thrown.
     *
     * <p> The default implementation checks that compression is
     * supported and that the compression mode is
     * {@code MODE_EXPLICIT}.  If so, if
     * {@code getCompressionTypes()} is {@code null} or
     * {@code getCompressionType()} is non-{@code null}, it
     * returns {@code null}.
     *
     * @return an array of {@code String}s containing localized
     * descriptions of the compression quality levels.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support compression.
     * @throws IllegalStateException if the compression mode is not
     * {@code MODE_EXPLICIT}.
     * @throws IllegalStateException if the set of legal
     * compression types is non-{@code null} and the current
     * compression type is {@code 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 {@code float}s that may be used along
     * with {@code getCompressionQualityDescriptions} as part of a user
     * interface for setting or displaying the compression quality
     * level.  See {@link #getCompressionQualityDescriptions
     * getCompressionQualityDescriptions} for more information.
     *
     * <p> If no descriptions are available, {@code null} is
     * returned.  If {@code null} is returned from
     * {@code getCompressionQualityDescriptions}, this method
     * must also return {@code null}.
     *
     * <p> If there are multiple compression types but none has been set,
     * an {@code IllegalStateException} is thrown.
     *
     * <p> The default implementation checks that compression is
     * supported and that the compression mode is
     * {@code MODE_EXPLICIT}.  If so, if
     * {@code getCompressionTypes()} is {@code null} or
     * {@code getCompressionType()} is non-{@code null}, it
     * returns {@code null}.
     *
     * @return an array of {@code float}s indicating the
     * boundaries between the compression quality levels as described
     * by the {@code String}s from
     * {@code getCompressionQualityDescriptions}.
     *
     * @throws UnsupportedOperationException if the writer does not
     * support compression.
     * @throws IllegalStateException if the compression mode is not
     * {@code MODE_EXPLICIT}.
     * @throws IllegalStateException if the set of legal
     * compression types is non-{@code null} and the current
     * compression type is {@code 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;
    }
}
