/* * 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. * * @since Android 1.0 */ 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, 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 describes 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!"); } } } }