blob: d32fa591d411aef9a4c942f8812796bcb74ef3d6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Rustem V. Rafikov
* @version $Revision: 1.3 $
*/
package javax.imageio;
import java.util.Locale;
import java.awt.*;
/**
* The ImageWriteParam class provides information to an ImageWriter
* about how an image is to be encoded.
*/
public class ImageWriteParam extends IIOParam {
/**
* The Constant MODE_DISABLED indicates that
* stream is not tiled, progressive, or compressed.
*/
public static final int MODE_DISABLED = 0;
/**
* The Constant MODE_DEFAULT indicates that the stream will be tiled,
* progressive, or compressed according to the plug-in's default.
*/
public static final int MODE_DEFAULT = 1;
/**
* The Constant MODE_EXPLICIT indicates that the stream will be tiled,
* progressive, or compressed according to current settings
* which are defined by set methods.
*/
public static final int MODE_EXPLICIT = 2;
/**
* The Constant MODE_COPY_FROM_METADATA indicates that the stream
* will be tiled, progressive, or compressed according to
* stream or image metadata.
*/
public static final int MODE_COPY_FROM_METADATA = 3;
/** Whether the ImageWriter can write tiles. */
protected boolean canWriteTiles = false;
/** The tiling mode. */
protected int tilingMode = MODE_COPY_FROM_METADATA;
/** The preferred tile sizes. */
protected Dimension[] preferredTileSizes = null;
/** The tiling set. */
protected boolean tilingSet = false;
/** The tile width. */
protected int tileWidth = 0;
/** The tile height. */
protected int tileHeight = 0;
/** Whether the ImageWriter can offset tiles. */
protected boolean canOffsetTiles = false;
/** The tile grid x offset. */
protected int tileGridXOffset = 0;
/** The tile grid y offset. */
protected int tileGridYOffset = 0;
/** Whether the ImageWriter can write in progressive mode. */
protected boolean canWriteProgressive = false;
/** The progressive mode. */
protected int progressiveMode = MODE_COPY_FROM_METADATA;
/** Whether the ImageWriter can write in compressed mode. */
protected boolean canWriteCompressed = false;
/** The compression mode. */
protected int compressionMode = MODE_COPY_FROM_METADATA;
/** The compression types. */
protected String[] compressionTypes = null;
/** The compression type. */
protected String compressionType = null;
/** The compression quality. */
protected float compressionQuality = 1.0f;
/** The locale. */
protected Locale locale = null;
/**
* Instantiates a new ImageWriteParam.
*/
protected ImageWriteParam() {}
/**
* Instantiates a new ImageWriteParam with the specified Locale.
*
* @param locale the Locale.
*/
public ImageWriteParam(Locale locale) {
this.locale = locale;
}
/**
* Gets the mode for writing the stream in a progressive sequence.
*
* @return the current progressive mode.
*/
public int getProgressiveMode() {
if (canWriteProgressive()) {
return progressiveMode;
}
throw new UnsupportedOperationException("progressive mode is not supported");
}
/**
* Returns true if images can be written using
* increasing quality passes by progressive.
*
* @return true if images can be written using
* increasing quality passes by progressive, false otherwise.
*/
public boolean canWriteProgressive() {
return canWriteProgressive;
}
/**
* Sets the progressive mode which defines whether the stream
* contains a progressive sequence of increasing quality
* during writing. The progressive mode should be one of
* the following values: MODE_DISABLED, MODE_DEFAULT, or
* MODE_COPY_FROM_METADATA.
*
* @param mode the new progressive mode.
*/
public void setProgressiveMode(int mode) {
if (canWriteProgressive()) {
if (mode < MODE_DISABLED || mode > MODE_COPY_FROM_METADATA || mode == MODE_EXPLICIT) {
throw new IllegalArgumentException("mode is not supported");
}
this.progressiveMode = mode;
}
throw new UnsupportedOperationException("progressive mode is not supported");
}
/**
* Returns true if the writer can use tiles with non zero
* grid offsets while writing.
*
* @return true if the writer can use tiles with non zero
* grid offsets while writing, false otherwise.
*/
public boolean canOffsetTiles() {
return canOffsetTiles;
}
/**
* Returns true if this writer can write images with
* compression.
*
* @return true, true if this writer can write images with
* compression, false otherwise.
*/
public boolean canWriteCompressed() {
return canWriteCompressed;
}
/**
* Returns true if the writer can write tiles.
*
* @return true if the writer can write tiles, false otherwise.
*/
public boolean canWriteTiles() {
return canWriteTiles;
}
/**
* Check write compressed.
*/
private final void checkWriteCompressed() {
if (!canWriteCompressed()) {
throw new UnsupportedOperationException("Compression not supported.");
}
}
/**
* Check compression mode.
*/
private final void checkCompressionMode() {
if (getCompressionMode() != MODE_EXPLICIT) {
throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
}
}
/**
* Check compression type.
*/
private final void checkCompressionType() {
if (getCompressionTypes() != null && getCompressionType() == null) {
throw new IllegalStateException("No compression type set!");
}
}
/**
* Gets the compression mode.
*
* @return the compression mode if it's supported.
*/
public int getCompressionMode() {
checkWriteCompressed();
return compressionMode;
}
/**
* Gets the an array of supported compression types.
*
* @return the an array of supported compression types.
*/
public String[] getCompressionTypes() {
checkWriteCompressed();
if (compressionTypes != null) {
return compressionTypes.clone();
}
return null;
}
/**
* Gets the current compression type, or returns null.
*
* @return the current compression type, or returns null
* if it is not set.
*/
public String getCompressionType() {
checkWriteCompressed();
checkCompressionMode();
return compressionType;
}
/**
* Gets a bit rate which represents an estimate of the number of bits
* of output data for each bit of input image data with the specified
* quality.
*
* @param quality the quality.
*
* @return an estimate of the bit rate, or -1.0F if there is no
* estimate.
*/
public float getBitRate(float quality) {
checkWriteCompressed();
checkCompressionMode();
checkCompressionType();
if (quality < 0 || quality > 1) {
throw new IllegalArgumentException("Quality out-of-bounds!");
}
return -1.0f;
}
/**
* Gets the compression quality.
*
* @return the compression quality.
*/
public float getCompressionQuality() {
checkWriteCompressed();
checkCompressionMode();
checkCompressionType();
return compressionQuality;
}
/**
* Gets the array of compression quality descriptions.
*
* @return the string array of compression quality descriptions.
*/
public String[] getCompressionQualityDescriptions() {
checkWriteCompressed();
checkCompressionMode();
checkCompressionType();
return null;
}
/**
* Gets an array of floats which decribe
* compression quality levels.
*
* @return the array of compression quality values.
*/
public float[] getCompressionQualityValues() {
checkWriteCompressed();
checkCompressionMode();
checkCompressionType();
return null;
}
/**
* Gets the locale of this ImageWriteParam.
*
* @return the locale of this ImageWriteParam.
*/
public Locale getLocale() {
return locale;
}
/**
* Gets the current compression type using the current Locale.
*
* @return the current compression type using the current Locale.
*/
public String getLocalizedCompressionTypeName() {
checkWriteCompressed();
checkCompressionMode();
String compressionType = getCompressionType();
if (compressionType == null) {
throw new IllegalStateException("No compression type set!");
}
return compressionType;
}
/**
* Check tiling.
*/
private final void checkTiling() {
if (!canWriteTiles()) {
throw new UnsupportedOperationException("Tiling not supported!");
}
}
/**
* Check tiling mode.
*/
private final void checkTilingMode() {
if (getTilingMode() != MODE_EXPLICIT) {
throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
}
}
/**
* Check tiling params.
*/
private final void checkTilingParams() {
if (!tilingSet) {
throw new IllegalStateException("Tiling parameters not set!");
}
}
/**
* Gets the tiling mode if tiling is supported.
*
* @return the tiling mode if tiling is supported.
*/
public int getTilingMode() {
checkTiling();
return tilingMode;
}
/**
* Gets an array of Dimensions giving the sizes of the tiles as
* they are encoded in the output file or stream.
*
* @return the preferred tile sizes.
*/
public Dimension[] getPreferredTileSizes() {
checkTiling();
if (preferredTileSizes == null) {
return null;
}
Dimension[] retval = new Dimension[preferredTileSizes.length];
for (int i = 0; i < preferredTileSizes.length; i++) {
retval[i] = new Dimension(retval[i]);
}
return retval;
}
/**
* Gets the tile grid X offset for encoding.
*
* @return the tile grid X offset for encoding.
*/
public int getTileGridXOffset() {
checkTiling();
checkTilingMode();
checkTilingParams();
return tileGridXOffset;
}
/**
* Gets the tile grid Y offset for encoding.
*
* @return the tile grid Y offset for encoding.
*/
public int getTileGridYOffset() {
checkTiling();
checkTilingMode();
checkTilingParams();
return tileGridYOffset;
}
/**
* Gets the tile height in an image as it is written to the
* output stream.
*
* @return the tile height in an image as it is written to the
* output stream.
*/
public int getTileHeight() {
checkTiling();
checkTilingMode();
checkTilingParams();
return tileHeight;
}
/**
* Gets the tile width in an image as it is written to the
* output stream.
*
* @return the tile width in an image as it is written to the
* output stream.
*/
public int getTileWidth() {
checkTiling();
checkTilingMode();
checkTilingParams();
return tileWidth;
}
/**
* Checks if the current compression type has lossless
* compression or not.
*
* @return true, if the current compression type has lossless
* compression, false otherwise.
*/
public boolean isCompressionLossless() {
checkWriteCompressed();
checkCompressionMode();
checkCompressionType();
return true;
}
/**
* Removes current compression type.
*/
public void unsetCompression() {
checkWriteCompressed();
checkCompressionMode();
compressionType = null;
compressionQuality = 1;
}
/**
* Sets the compression mode to the specified value.
* The specified mode can be one of the predefined
* constants: MODE_DEFAULT, MODE_DISABLED, MODE_EXPLICIT,
* or MODE_COPY_FROM_METADATA.
*
* @param mode the new compression mode to be set.
*/
public void setCompressionMode(int mode) {
checkWriteCompressed();
switch (mode) {
case MODE_EXPLICIT: {
compressionMode = mode;
unsetCompression();
break;
}
case MODE_COPY_FROM_METADATA:
case MODE_DISABLED:
case MODE_DEFAULT: {
compressionMode = mode;
break;
}
default: {
throw new IllegalArgumentException("Illegal value for mode!");
}
}
}
/**
* Sets the compression quality. The value should be between 0 and 1.
*
* @param quality the new compression quality,
* float value between 0 and 1.
*/
public void setCompressionQuality(float quality) {
checkWriteCompressed();
checkCompressionMode();
checkCompressionType();
if (quality < 0 || quality > 1) {
throw new IllegalArgumentException("Quality out-of-bounds!");
}
compressionQuality = quality;
}
/**
* Sets the compression type. The specified string
* should be one of the values returned
* by getCompressionTypes method.
*
* @param compressionType the new compression type.
*/
public void setCompressionType(String compressionType) {
checkWriteCompressed();
checkCompressionMode();
if (compressionType == null) { // Don't check anything
this.compressionType = null;
} else {
String[] compressionTypes = getCompressionTypes();
if (compressionTypes == null) {
throw new UnsupportedOperationException("No settable compression types");
}
for (int i = 0; i < compressionTypes.length; i++) {
if (compressionTypes[i].equals(compressionType)) {
this.compressionType = compressionType;
return;
}
}
// Compression type is not in the list.
throw new IllegalArgumentException("Unknown compression type!");
}
}
/**
* Sets the instruction that tiling should be performed for
* the image in the output stream with the specified parameters.
*
* @param tileWidth the tile's width.
* @param tileHeight the tile's height.
* @param tileGridXOffset the tile grid's x offset.
* @param tileGridYOffset the tile grid's y offset.
*/
public void setTiling(int tileWidth, int tileHeight, int tileGridXOffset, int tileGridYOffset) {
checkTiling();
checkTilingMode();
if (!canOffsetTiles() && (tileGridXOffset != 0 || tileGridYOffset != 0)) {
throw new UnsupportedOperationException("Can't offset tiles!");
}
if (tileWidth <=0 || tileHeight <= 0) {
throw new IllegalArgumentException("tile dimensions are non-positive!");
}
Dimension preferredTileSizes[] = getPreferredTileSizes();
if (preferredTileSizes != null) {
for (int i = 0; i < preferredTileSizes.length; i+=2) {
Dimension minSize = preferredTileSizes[i];
Dimension maxSize = preferredTileSizes[i+1];
if (
tileWidth < minSize.width || tileWidth > maxSize.width ||
tileHeight < minSize.height || tileHeight > maxSize.height
) {
throw new IllegalArgumentException("Illegal tile size!");
}
}
}
tilingSet = true;
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.tileGridXOffset = tileGridXOffset;
this.tileGridYOffset = tileGridYOffset;
}
/**
* Clears all tiling settings.
*/
public void unsetTiling() {
checkTiling();
checkTilingMode();
tilingSet = false;
tileWidth = 0;
tileHeight = 0;
tileGridXOffset = 0;
tileGridYOffset = 0;
}
/**
* Sets the tiling mode. The specified mode should be one of the
* following values: MODE_DISABLED, MODE_DEFAULT, MODE_EXPLICIT,
* or MODE_COPY_FROM_METADATA.
*
* @param mode the new tiling mode.
*/
public void setTilingMode(int mode) {
checkTiling();
switch (mode) {
case MODE_EXPLICIT: {
tilingMode = mode;
unsetTiling();
break;
}
case MODE_COPY_FROM_METADATA:
case MODE_DISABLED:
case MODE_DEFAULT: {
tilingMode = mode;
break;
}
default: {
throw new IllegalArgumentException("Illegal value for mode!");
}
}
}
}