Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/imageio/ImageWriteParam.java
38829 views
/*1* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.imageio;2627import java.awt.Dimension;28import java.util.Locale;2930/**31* A class describing how a stream is to be encoded. Instances of32* this class or its subclasses are used to supply prescriptive33* "how-to" information to instances of <code>ImageWriter</code>.34*35* <p> A plug-in for a specific image format may define a subclass of36* this class, and return objects of that class from the37* <code>getDefaultWriteParam</code> method of its38* <code>ImageWriter</code> implementation. For example, the built-in39* JPEG writer plug-in will return instances of40* <code>javax.imageio.plugins.jpeg.JPEGImageWriteParam</code>.41*42* <p> The region of the image to be written is determined by first43* intersecting the actual bounds of the image with the rectangle44* specified by <code>IIOParam.setSourceRegion</code>, if any. If the45* resulting rectangle has a width or height of zero, the writer will46* throw an <code>IIOException</code>. If the intersection is47* non-empty, writing will commence with the first subsampled pixel48* and include additional pixels within the intersected bounds49* according to the horizontal and vertical subsampling factors50* specified by {@link IIOParam#setSourceSubsampling51* IIOParam.setSourceSubsampling}.52*53* <p> Individual features such as tiling, progressive encoding, and54* compression may be set in one of four modes.55* <code>MODE_DISABLED</code> disables the features;56* <code>MODE_DEFAULT</code> enables the feature with57* writer-controlled parameter values; <code>MODE_EXPLICIT</code>58* enables the feature and allows the use of a <code>set</code> method59* to provide additional parameters; and60* <code>MODE_COPY_FROM_METADATA</code> copies relevant parameter61* values from the stream and image metadata objects passed to the62* writer. The default for all features is63* <code>MODE_COPY_FROM_METADATA</code>. Non-standard features64* supplied in subclasses are encouraged, but not required to use a65* similar scheme.66*67* <p> Plug-in writers may extend the functionality of68* <code>ImageWriteParam</code> by providing a subclass that implements69* additional, plug-in specific interfaces. It is up to the plug-in70* to document what interfaces are available and how they are to be71* used. Writers will silently ignore any extended features of an72* <code>ImageWriteParam</code> subclass of which they are not aware.73* Also, they may ignore any optional features that they normally74* disable when creating their own <code>ImageWriteParam</code>75* instances via <code>getDefaultWriteParam</code>.76*77* <p> Note that unless a query method exists for a capability, it must78* be supported by all <code>ImageWriter</code> implementations79* (<i>e.g.</i> progressive encoding is optional, but subsampling must be80* supported).81*82*83* @see ImageReadParam84*/85public class ImageWriteParam extends IIOParam {8687/**88* A constant value that may be passed into methods such as89* <code>setTilingMode</code>, <code>setProgressiveMode</code>,90* and <code>setCompressionMode</code> to disable a feature for91* future writes. That is, when this mode is set the stream will92* <b>not</b> be tiled, progressive, or compressed, and the93* relevant accessor methods will throw an94* <code>IllegalStateException</code>.95*96* @see #MODE_EXPLICIT97* @see #MODE_COPY_FROM_METADATA98* @see #MODE_DEFAULT99* @see #setProgressiveMode100* @see #getProgressiveMode101* @see #setTilingMode102* @see #getTilingMode103* @see #setCompressionMode104* @see #getCompressionMode105*/106public static final int MODE_DISABLED = 0;107108/**109* A constant value that may be passed into methods such as110* <code>setTilingMode</code>,111* <code>setProgressiveMode</code>, and112* <code>setCompressionMode</code> to enable that feature for113* future writes. That is, when this mode is enabled the stream114* will be tiled, progressive, or compressed according to a115* sensible default chosen internally by the writer in a plug-in116* dependent way, and the relevant accessor methods will117* throw an <code>IllegalStateException</code>.118*119* @see #MODE_DISABLED120* @see #MODE_EXPLICIT121* @see #MODE_COPY_FROM_METADATA122* @see #setProgressiveMode123* @see #getProgressiveMode124* @see #setTilingMode125* @see #getTilingMode126* @see #setCompressionMode127* @see #getCompressionMode128*/129public static final int MODE_DEFAULT = 1;130131/**132* A constant value that may be passed into methods such as133* <code>setTilingMode</code> or <code>setCompressionMode</code>134* to enable a feature for future writes. That is, when this mode135* is set the stream will be tiled or compressed according to136* additional information supplied to the corresponding137* <code>set</code> methods in this class and retrievable from the138* corresponding <code>get</code> methods. Note that this mode is139* not supported for progressive output.140*141* @see #MODE_DISABLED142* @see #MODE_COPY_FROM_METADATA143* @see #MODE_DEFAULT144* @see #setProgressiveMode145* @see #getProgressiveMode146* @see #setTilingMode147* @see #getTilingMode148* @see #setCompressionMode149* @see #getCompressionMode150*/151public static final int MODE_EXPLICIT = 2;152153/**154* A constant value that may be passed into methods such as155* <code>setTilingMode</code>, <code>setProgressiveMode</code>, or156* <code>setCompressionMode</code> to enable that feature for157* future writes. That is, when this mode is enabled the stream158* will be tiled, progressive, or compressed based on the contents159* of stream and/or image metadata passed into the write160* operation, and any relevant accessor methods will throw an161* <code>IllegalStateException</code>.162*163* <p> This is the default mode for all features, so that a read164* including metadata followed by a write including metadata will165* preserve as much information as possible.166*167* @see #MODE_DISABLED168* @see #MODE_EXPLICIT169* @see #MODE_DEFAULT170* @see #setProgressiveMode171* @see #getProgressiveMode172* @see #setTilingMode173* @see #getTilingMode174* @see #setCompressionMode175* @see #getCompressionMode176*/177public static final int MODE_COPY_FROM_METADATA = 3;178179// If more modes are added, this should be updated.180private static final int MAX_MODE = MODE_COPY_FROM_METADATA;181182/**183* A <code>boolean</code> that is <code>true</code> if this184* <code>ImageWriteParam</code> allows tile width and tile height185* parameters to be set. By default, the value is186* <code>false</code>. Subclasses must set the value manually.187*188* <p> Subclasses that do not support writing tiles should ensure189* that this value is set to <code>false</code>.190*/191protected boolean canWriteTiles = false;192193/**194* The mode controlling tiling settings, which Must be195* set to one of the four <code>MODE_*</code> values. The default196* is <code>MODE_COPY_FROM_METADATA</code>.197*198* <p> Subclasses that do not writing tiles may ignore this value.199*200* @see #MODE_DISABLED201* @see #MODE_EXPLICIT202* @see #MODE_COPY_FROM_METADATA203* @see #MODE_DEFAULT204* @see #setTilingMode205* @see #getTilingMode206*/207protected int tilingMode = MODE_COPY_FROM_METADATA;208209/**210* An array of preferred tile size range pairs. The default value211* is <code>null</code>, which indicates that there are no212* preferred sizes. If the value is non-<code>null</code>, it213* must have an even length of at least two.214*215* <p> Subclasses that do not support writing tiles may ignore216* this value.217*218* @see #getPreferredTileSizes219*/220protected Dimension[] preferredTileSizes = null;221222/**223* A <code>boolean</code> that is <code>true</code> if tiling224* parameters have been specified.225*226* <p> Subclasses that do not support writing tiles may ignore227* this value.228*/229protected boolean tilingSet = false;230231/**232* The width of each tile if tiling has been set, or 0 otherwise.233*234* <p> Subclasses that do not support tiling may ignore this235* value.236*/237protected int tileWidth = 0;238239/**240* The height of each tile if tiling has been set, or 0 otherwise.241* The initial value is <code>0</code>.242*243* <p> Subclasses that do not support tiling may ignore this244* value.245*/246protected int tileHeight = 0;247248/**249* A <code>boolean</code> that is <code>true</code> if this250* <code>ImageWriteParam</code> allows tiling grid offset251* parameters to be set. By default, the value is252* <code>false</code>. Subclasses must set the value manually.253*254* <p> Subclasses that do not support writing tiles, or that255* support writing but not offsetting tiles must ensure that this256* value is set to <code>false</code>.257*/258protected boolean canOffsetTiles = false;259260/**261* The amount by which the tile grid origin should be offset262* horizontally from the image origin if tiling has been set,263* or 0 otherwise. The initial value is <code>0</code>.264*265* <p> Subclasses that do not support offsetting tiles may ignore266* this value.267*/268protected int tileGridXOffset = 0;269270/**271* The amount by which the tile grid origin should be offset272* vertically from the image origin if tiling has been set,273* or 0 otherwise. The initial value is <code>0</code>.274*275* <p> Subclasses that do not support offsetting tiles may ignore276* this value.277*/278protected int tileGridYOffset = 0;279280/**281* A <code>boolean</code> that is <code>true</code> if this282* <code>ImageWriteParam</code> allows images to be written as a283* progressive sequence of increasing quality passes. By default,284* the value is <code>false</code>. Subclasses must set the value285* manually.286*287* <p> Subclasses that do not support progressive encoding must288* ensure that this value is set to <code>false</code>.289*/290protected boolean canWriteProgressive = false;291292/**293* The mode controlling progressive encoding, which must be set to294* one of the four <code>MODE_*</code> values, except295* <code>MODE_EXPLICIT</code>. The default is296* <code>MODE_COPY_FROM_METADATA</code>.297*298* <p> Subclasses that do not support progressive encoding may299* ignore this value.300*301* @see #MODE_DISABLED302* @see #MODE_EXPLICIT303* @see #MODE_COPY_FROM_METADATA304* @see #MODE_DEFAULT305* @see #setProgressiveMode306* @see #getProgressiveMode307*/308protected int progressiveMode = MODE_COPY_FROM_METADATA;309310/**311* A <code>boolean</code> that is <code>true</code> if this writer312* can write images using compression. By default, the value is313* <code>false</code>. Subclasses must set the value manually.314*315* <p> Subclasses that do not support compression must ensure that316* this value is set to <code>false</code>.317*/318protected boolean canWriteCompressed = false;319320/**321* The mode controlling compression settings, which must be set to322* one of the four <code>MODE_*</code> values. The default is323* <code>MODE_COPY_FROM_METADATA</code>.324*325* <p> Subclasses that do not support compression may ignore this326* value.327*328* @see #MODE_DISABLED329* @see #MODE_EXPLICIT330* @see #MODE_COPY_FROM_METADATA331* @see #MODE_DEFAULT332* @see #setCompressionMode333* @see #getCompressionMode334*/335protected int compressionMode = MODE_COPY_FROM_METADATA;336337/**338* An array of <code>String</code>s containing the names of the339* available compression types. Subclasses must set the value340* manually.341*342* <p> Subclasses that do not support compression may ignore this343* value.344*/345protected String[] compressionTypes = null;346347/**348* A <code>String</code> containing the name of the current349* compression type, or <code>null</code> if none is set.350*351* <p> Subclasses that do not support compression may ignore this352* value.353*/354protected String compressionType = null;355356/**357* A <code>float</code> containing the current compression quality358* setting. The initial value is <code>1.0F</code>.359*360* <p> Subclasses that do not support compression may ignore this361* value.362*/363protected float compressionQuality = 1.0F;364365/**366* A <code>Locale</code> to be used to localize compression type367* names and quality descriptions, or <code>null</code> to use a368* default <code>Locale</code>. Subclasses must set the value369* manually.370*/371protected Locale locale = null;372373/**374* Constructs an empty <code>ImageWriteParam</code>. It is up to375* the subclass to set up the instance variables properly.376*/377protected ImageWriteParam() {}378379/**380* Constructs an <code>ImageWriteParam</code> set to use a381* given <code>Locale</code>.382*383* @param locale a <code>Locale</code> to be used to localize384* compression type names and quality descriptions, or385* <code>null</code>.386*/387public ImageWriteParam(Locale locale) {388this.locale = locale;389}390391// Return a deep copy of the array392private static Dimension[] clonePreferredTileSizes(Dimension[] sizes) {393if (sizes == null) {394return null;395}396Dimension[] temp = new Dimension[sizes.length];397for (int i = 0; i < sizes.length; i++) {398temp[i] = new Dimension(sizes[i]);399}400return temp;401}402403/**404* Returns the currently set <code>Locale</code>, or405* <code>null</code> if only a default <code>Locale</code> is406* supported.407*408* @return the current <code>Locale</code>, or <code>null</code>.409*/410public Locale getLocale() {411return locale;412}413414/**415* Returns <code>true</code> if the writer can perform tiling416* while writing. If this method returns <code>false</code>, then417* <code>setTiling</code> will throw an418* <code>UnsupportedOperationException</code>.419*420* @return <code>true</code> if the writer supports tiling.421*422* @see #canOffsetTiles()423* @see #setTiling(int, int, int, int)424*/425public boolean canWriteTiles() {426return canWriteTiles;427}428429/**430* Returns <code>true</code> if the writer can perform tiling with431* non-zero grid offsets while writing. If this method returns432* <code>false</code>, then <code>setTiling</code> will throw an433* <code>UnsupportedOperationException</code> if the grid offset434* arguments are not both zero. If <code>canWriteTiles</code>435* returns <code>false</code>, this method will return436* <code>false</code> as well.437*438* @return <code>true</code> if the writer supports non-zero tile439* offsets.440*441* @see #canWriteTiles()442* @see #setTiling(int, int, int, int)443*/444public boolean canOffsetTiles() {445return canOffsetTiles;446}447448/**449* Determines whether the image will be tiled in the output450* stream and, if it will, how the tiling parameters will be451* determined. The modes are interpreted as follows:452*453* <ul>454*455* <li><code>MODE_DISABLED</code> - The image will not be tiled.456* <code>setTiling</code> will throw an457* <code>IllegalStateException</code>.458*459* <li><code>MODE_DEFAULT</code> - The image will be tiled using460* default parameters. <code>setTiling</code> will throw an461* <code>IllegalStateException</code>.462*463* <li><code>MODE_EXPLICIT</code> - The image will be tiled464* according to parameters given in the {@link #setTiling setTiling}465* method. Any previously set tiling parameters are discarded.466*467* <li><code>MODE_COPY_FROM_METADATA</code> - The image will468* conform to the metadata object passed in to a write.469* <code>setTiling</code> will throw an470* <code>IllegalStateException</code>.471*472* </ul>473*474* @param mode The mode to use for tiling.475*476* @exception UnsupportedOperationException if477* <code>canWriteTiles</code> returns <code>false</code>.478* @exception IllegalArgumentException if <code>mode</code> is not479* one of the modes listed above.480*481* @see #setTiling482* @see #getTilingMode483*/484public void setTilingMode(int mode) {485if (canWriteTiles() == false) {486throw new UnsupportedOperationException("Tiling not supported!");487}488if (mode < MODE_DISABLED || mode > MAX_MODE) {489throw new IllegalArgumentException("Illegal value for mode!");490}491this.tilingMode = mode;492if (mode == MODE_EXPLICIT) {493unsetTiling();494}495}496497/**498* Returns the current tiling mode, if tiling is supported.499* Otherwise throws an <code>UnsupportedOperationException</code>.500*501* @return the current tiling mode.502*503* @exception UnsupportedOperationException if504* <code>canWriteTiles</code> returns <code>false</code>.505*506* @see #setTilingMode507*/508public int getTilingMode() {509if (!canWriteTiles()) {510throw new UnsupportedOperationException("Tiling not supported");511}512return tilingMode;513}514515/**516* Returns an array of <code>Dimension</code>s indicating the517* legal size ranges for tiles as they will be encoded in the518* output file or stream. The returned array is a copy.519*520* <p> The information is returned as a set of pairs; the first521* element of a pair contains an (inclusive) minimum width and522* height, and the second element contains an (inclusive) maximum523* width and height. Together, each pair defines a valid range of524* sizes. To specify a fixed size, use the same width and height525* for both elements. To specify an arbitrary range, a value of526* <code>null</code> is used in place of an actual array of527* <code>Dimension</code>s.528*529* <p> If no array is specified on the constructor, but tiling is530* allowed, then this method returns <code>null</code>.531*532* @exception UnsupportedOperationException if the plug-in does533* not support tiling.534*535* @return an array of <code>Dimension</code>s with an even length536* of at least two, or <code>null</code>.537*/538public Dimension[] getPreferredTileSizes() {539if (!canWriteTiles()) {540throw new UnsupportedOperationException("Tiling not supported");541}542return clonePreferredTileSizes(preferredTileSizes);543}544545/**546* Specifies that the image should be tiled in the output stream.547* The <code>tileWidth</code> and <code>tileHeight</code>548* parameters specify the width and height of the tiles in the549* file. If the tile width or height is greater than the width or550* height of the image, the image is not tiled in that dimension.551*552* <p> If <code>canOffsetTiles</code> returns <code>false</code>,553* then the <code>tileGridXOffset</code> and554* <code>tileGridYOffset</code> parameters must be zero.555*556* @param tileWidth the width of each tile.557* @param tileHeight the height of each tile.558* @param tileGridXOffset the horizontal offset of the tile grid.559* @param tileGridYOffset the vertical offset of the tile grid.560*561* @exception UnsupportedOperationException if the plug-in does not562* support tiling.563* @exception IllegalStateException if the tiling mode is not564* <code>MODE_EXPLICIT</code>.565* @exception UnsupportedOperationException if the plug-in does not566* support grid offsets, and the grid offsets are not both zero.567* @exception IllegalArgumentException if the tile size is not568* within one of the allowable ranges returned by569* <code>getPreferredTileSizes</code>.570* @exception IllegalArgumentException if <code>tileWidth</code>571* or <code>tileHeight</code> is less than or equal to 0.572*573* @see #canWriteTiles574* @see #canOffsetTiles575* @see #getTileWidth()576* @see #getTileHeight()577* @see #getTileGridXOffset()578* @see #getTileGridYOffset()579*/580public void setTiling(int tileWidth,581int tileHeight,582int tileGridXOffset,583int tileGridYOffset) {584if (!canWriteTiles()) {585throw new UnsupportedOperationException("Tiling not supported!");586}587if (getTilingMode() != MODE_EXPLICIT) {588throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");589}590if (tileWidth <= 0 || tileHeight <= 0) {591throw new IllegalArgumentException592("tile dimensions are non-positive!");593}594boolean tilesOffset = (tileGridXOffset != 0) || (tileGridYOffset != 0);595if (!canOffsetTiles() && tilesOffset) {596throw new UnsupportedOperationException("Can't offset tiles!");597}598if (preferredTileSizes != null) {599boolean ok = true;600for (int i = 0; i < preferredTileSizes.length; i += 2) {601Dimension min = preferredTileSizes[i];602Dimension max = preferredTileSizes[i+1];603if ((tileWidth < min.width) ||604(tileWidth > max.width) ||605(tileHeight < min.height) ||606(tileHeight > max.height)) {607ok = false;608break;609}610}611if (!ok) {612throw new IllegalArgumentException("Illegal tile size!");613}614}615616this.tilingSet = true;617this.tileWidth = tileWidth;618this.tileHeight = tileHeight;619this.tileGridXOffset = tileGridXOffset;620this.tileGridYOffset = tileGridYOffset;621}622623/**624* Removes any previous tile grid parameters specified by calls to625* <code>setTiling</code>.626*627* <p> The default implementation sets the instance variables628* <code>tileWidth</code>, <code>tileHeight</code>,629* <code>tileGridXOffset</code>, and630* <code>tileGridYOffset</code> to <code>0</code>.631*632* @exception UnsupportedOperationException if the plug-in does not633* support tiling.634* @exception IllegalStateException if the tiling mode is not635* <code>MODE_EXPLICIT</code>.636*637* @see #setTiling(int, int, int, int)638*/639public void unsetTiling() {640if (!canWriteTiles()) {641throw new UnsupportedOperationException("Tiling not supported!");642}643if (getTilingMode() != MODE_EXPLICIT) {644throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");645}646this.tilingSet = false;647this.tileWidth = 0;648this.tileHeight = 0;649this.tileGridXOffset = 0;650this.tileGridYOffset = 0;651}652653/**654* Returns the width of each tile in an image as it will be655* written to the output stream. If tiling parameters have not656* been set, an <code>IllegalStateException</code> is thrown.657*658* @return the tile width to be used for encoding.659*660* @exception UnsupportedOperationException if the plug-in does not661* support tiling.662* @exception IllegalStateException if the tiling mode is not663* <code>MODE_EXPLICIT</code>.664* @exception IllegalStateException if the tiling parameters have665* not been set.666*667* @see #setTiling(int, int, int, int)668* @see #getTileHeight()669*/670public int getTileWidth() {671if (!canWriteTiles()) {672throw new UnsupportedOperationException("Tiling not supported!");673}674if (getTilingMode() != MODE_EXPLICIT) {675throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");676}677if (!tilingSet) {678throw new IllegalStateException("Tiling parameters not set!");679}680return tileWidth;681}682683/**684* Returns the height of each tile in an image as it will be written to685* the output stream. If tiling parameters have not686* been set, an <code>IllegalStateException</code> is thrown.687*688* @return the tile height to be used for encoding.689*690* @exception UnsupportedOperationException if the plug-in does not691* support tiling.692* @exception IllegalStateException if the tiling mode is not693* <code>MODE_EXPLICIT</code>.694* @exception IllegalStateException if the tiling parameters have695* not been set.696*697* @see #setTiling(int, int, int, int)698* @see #getTileWidth()699*/700public int getTileHeight() {701if (!canWriteTiles()) {702throw new UnsupportedOperationException("Tiling not supported!");703}704if (getTilingMode() != MODE_EXPLICIT) {705throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");706}707if (!tilingSet) {708throw new IllegalStateException("Tiling parameters not set!");709}710return tileHeight;711}712713/**714* Returns the horizontal tile grid offset of an image as it will715* be written to the output stream. If tiling parameters have not716* been set, an <code>IllegalStateException</code> is thrown.717*718* @return the tile grid X offset to be used for encoding.719*720* @exception UnsupportedOperationException if the plug-in does not721* support tiling.722* @exception IllegalStateException if the tiling mode is not723* <code>MODE_EXPLICIT</code>.724* @exception IllegalStateException if the tiling parameters have725* not been set.726*727* @see #setTiling(int, int, int, int)728* @see #getTileGridYOffset()729*/730public int getTileGridXOffset() {731if (!canWriteTiles()) {732throw new UnsupportedOperationException("Tiling not supported!");733}734if (getTilingMode() != MODE_EXPLICIT) {735throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");736}737if (!tilingSet) {738throw new IllegalStateException("Tiling parameters not set!");739}740return tileGridXOffset;741}742743/**744* Returns the vertical tile grid offset of an image as it will745* be written to the output stream. If tiling parameters have not746* been set, an <code>IllegalStateException</code> is thrown.747*748* @return the tile grid Y offset to be used for encoding.749*750* @exception UnsupportedOperationException if the plug-in does not751* support tiling.752* @exception IllegalStateException if the tiling mode is not753* <code>MODE_EXPLICIT</code>.754* @exception IllegalStateException if the tiling parameters have755* not been set.756*757* @see #setTiling(int, int, int, int)758* @see #getTileGridXOffset()759*/760public int getTileGridYOffset() {761if (!canWriteTiles()) {762throw new UnsupportedOperationException("Tiling not supported!");763}764if (getTilingMode() != MODE_EXPLICIT) {765throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");766}767if (!tilingSet) {768throw new IllegalStateException("Tiling parameters not set!");769}770return tileGridYOffset;771}772773/**774* Returns <code>true</code> if the writer can write out images775* as a series of passes of progressively increasing quality.776*777* @return <code>true</code> if the writer supports progressive778* encoding.779*780* @see #setProgressiveMode781* @see #getProgressiveMode782*/783public boolean canWriteProgressive() {784return canWriteProgressive;785}786787/**788* Specifies that the writer is to write the image out in a789* progressive mode such that the stream will contain a series of790* scans of increasing quality. If progressive encoding is not791* supported, an <code>UnsupportedOperationException</code> will792* be thrown.793*794* <p> The mode argument determines how795* the progression parameters are chosen, and must be either796* <code>MODE_DISABLED</code>,797* <code>MODE_COPY_FROM_METADATA</code>, or798* <code>MODE_DEFAULT</code>. Otherwise an799* <code>IllegalArgumentException</code> is thrown.800*801* <p> The modes are interpreted as follows:802*803* <ul>804* <li><code>MODE_DISABLED</code> - No progression. Use this to805* turn off progression.806*807* <li><code>MODE_COPY_FROM_METADATA</code> - The output image808* will use whatever progression parameters are found in the809* metadata objects passed into the writer.810*811* <li><code>MODE_DEFAULT</code> - The image will be written812* progressively, with parameters chosen by the writer.813* </ul>814*815* <p> The default is <code>MODE_COPY_FROM_METADATA</code>.816*817* @param mode The mode for setting progression in the output818* stream.819*820* @exception UnsupportedOperationException if the writer does not821* support progressive encoding.822* @exception IllegalArgumentException if <code>mode</code> is not823* one of the modes listed above.824*825* @see #getProgressiveMode826*/827public void setProgressiveMode(int mode) {828if (!canWriteProgressive()) {829throw new UnsupportedOperationException(830"Progressive output not supported");831}832if (mode < MODE_DISABLED || mode > MAX_MODE) {833throw new IllegalArgumentException("Illegal value for mode!");834}835if (mode == MODE_EXPLICIT) {836throw new IllegalArgumentException(837"MODE_EXPLICIT not supported for progressive output");838}839this.progressiveMode = mode;840}841842/**843* Returns the current mode for writing the stream in a844* progressive manner.845*846* @return the current mode for progressive encoding.847*848* @exception UnsupportedOperationException if the writer does not849* support progressive encoding.850*851* @see #setProgressiveMode852*/853public int getProgressiveMode() {854if (!canWriteProgressive()) {855throw new UnsupportedOperationException856("Progressive output not supported");857}858return progressiveMode;859}860861/**862* Returns <code>true</code> if this writer supports compression.863*864* @return <code>true</code> if the writer supports compression.865*/866public boolean canWriteCompressed() {867return canWriteCompressed;868}869870/**871* Specifies whether compression is to be performed, and if so how872* compression parameters are to be determined. The <code>mode</code>873* argument must be one of the four modes, interpreted as follows:874*875* <ul>876* <li><code>MODE_DISABLED</code> - If the mode is set to877* <code>MODE_DISABLED</code>, methods that query or modify the878* compression type or parameters will throw an879* <code>IllegalStateException</code> (if compression is880* normally supported by the plug-in). Some writers, such as JPEG,881* do not normally offer uncompressed output. In this case, attempting882* to set the mode to <code>MODE_DISABLED</code> will throw an883* <code>UnsupportedOperationException</code> and the mode will not be884* changed.885*886* <li><code>MODE_EXPLICIT</code> - Compress using the887* compression type and quality settings specified in this888* <code>ImageWriteParam</code>. Any previously set compression889* parameters are discarded.890*891* <li><code>MODE_COPY_FROM_METADATA</code> - Use whatever892* compression parameters are specified in metadata objects893* passed in to the writer.894*895* <li><code>MODE_DEFAULT</code> - Use default compression896* parameters.897* </ul>898*899* <p> The default is <code>MODE_COPY_FROM_METADATA</code>.900*901* @param mode The mode for setting compression in the output902* stream.903*904* @exception UnsupportedOperationException if the writer does not905* support compression, or does not support the requested mode.906* @exception IllegalArgumentException if <code>mode</code> is not907* one of the modes listed above.908*909* @see #getCompressionMode910*/911public void setCompressionMode(int mode) {912if (!canWriteCompressed()) {913throw new UnsupportedOperationException(914"Compression not supported.");915}916if (mode < MODE_DISABLED || mode > MAX_MODE) {917throw new IllegalArgumentException("Illegal value for mode!");918}919this.compressionMode = mode;920if (mode == MODE_EXPLICIT) {921unsetCompression();922}923}924925/**926* Returns the current compression mode, if compression is927* supported.928*929* @return the current compression mode.930*931* @exception UnsupportedOperationException if the writer does not932* support compression.933*934* @see #setCompressionMode935*/936public int getCompressionMode() {937if (!canWriteCompressed()) {938throw new UnsupportedOperationException(939"Compression not supported.");940}941return compressionMode;942}943944/**945* Returns a list of available compression types, as an array or946* <code>String</code>s, or <code>null</code> if a compression947* type may not be chosen using these interfaces. The array948* returned is a copy.949*950* <p> If the writer only offers a single, mandatory form of951* compression, it is not necessary to provide any named952* compression types. Named compression types should only be953* used where the user is able to make a meaningful choice954* between different schemes.955*956* <p> The default implementation checks if compression is957* supported and throws an958* <code>UnsupportedOperationException</code> if not. Otherwise,959* it returns a clone of the <code>compressionTypes</code>960* instance variable if it is non-<code>null</code>, or else961* returns <code>null</code>.962*963* @return an array of <code>String</code>s containing the964* (non-localized) names of available compression types, or965* <code>null</code>.966*967* @exception UnsupportedOperationException if the writer does not968* support compression.969*/970public String[] getCompressionTypes() {971if (!canWriteCompressed()) {972throw new UnsupportedOperationException(973"Compression not supported");974}975if (compressionTypes == null) {976return null;977}978return (String[])compressionTypes.clone();979}980981/**982* Sets the compression type to one of the values indicated by983* <code>getCompressionTypes</code>. If a value of984* <code>null</code> is passed in, any previous setting is985* removed.986*987* <p> The default implementation checks whether compression is988* supported and the compression mode is989* <code>MODE_EXPLICIT</code>. If so, it calls990* <code>getCompressionTypes</code> and checks if991* <code>compressionType</code> is one of the legal values. If it992* is, the <code>compressionType</code> instance variable is set.993* If <code>compressionType</code> is <code>null</code>, the994* instance variable is set without performing any checking.995*996* @param compressionType one of the <code>String</code>s returned997* by <code>getCompressionTypes</code>, or <code>null</code> to998* remove any previous setting.999*1000* @exception UnsupportedOperationException if the writer does not1001* support compression.1002* @exception IllegalStateException if the compression mode is not1003* <code>MODE_EXPLICIT</code>.1004* @exception UnsupportedOperationException if there are no1005* settable compression types.1006* @exception IllegalArgumentException if1007* <code>compressionType</code> is non-<code>null</code> but is not1008* one of the values returned by <code>getCompressionTypes</code>.1009*1010* @see #getCompressionTypes1011* @see #getCompressionType1012* @see #unsetCompression1013*/1014public void setCompressionType(String compressionType) {1015if (!canWriteCompressed()) {1016throw new UnsupportedOperationException(1017"Compression not supported");1018}1019if (getCompressionMode() != MODE_EXPLICIT) {1020throw new IllegalStateException1021("Compression mode not MODE_EXPLICIT!");1022}1023String[] legalTypes = getCompressionTypes();1024if (legalTypes == null) {1025throw new UnsupportedOperationException(1026"No settable compression types");1027}1028if (compressionType != null) {1029boolean found = false;1030if (legalTypes != null) {1031for (int i = 0; i < legalTypes.length; i++) {1032if (compressionType.equals(legalTypes[i])) {1033found = true;1034break;1035}1036}1037}1038if (!found) {1039throw new IllegalArgumentException("Unknown compression type!");1040}1041}1042this.compressionType = compressionType;1043}10441045/**1046* Returns the currently set compression type, or1047* <code>null</code> if none has been set. The type is returned1048* as a <code>String</code> from among those returned by1049* <code>getCompressionTypes</code>.1050* If no compression type has been set, <code>null</code> is1051* returned.1052*1053* <p> The default implementation checks whether compression is1054* supported and the compression mode is1055* <code>MODE_EXPLICIT</code>. If so, it returns the value of the1056* <code>compressionType</code> instance variable.1057*1058* @return the current compression type as a <code>String</code>,1059* or <code>null</code> if no type is set.1060*1061* @exception UnsupportedOperationException if the writer does not1062* support compression.1063* @exception IllegalStateException if the compression mode is not1064* <code>MODE_EXPLICIT</code>.1065*1066* @see #setCompressionType1067*/1068public String getCompressionType() {1069if (!canWriteCompressed()) {1070throw new UnsupportedOperationException(1071"Compression not supported.");1072}1073if (getCompressionMode() != MODE_EXPLICIT) {1074throw new IllegalStateException1075("Compression mode not MODE_EXPLICIT!");1076}1077return compressionType;1078}10791080/**1081* Removes any previous compression type and quality settings.1082*1083* <p> The default implementation sets the instance variable1084* <code>compressionType</code> to <code>null</code>, and the1085* instance variable <code>compressionQuality</code> to1086* <code>1.0F</code>.1087*1088* @exception UnsupportedOperationException if the plug-in does not1089* support compression.1090* @exception IllegalStateException if the compression mode is not1091* <code>MODE_EXPLICIT</code>.1092*1093* @see #setCompressionType1094* @see #setCompressionQuality1095*/1096public void unsetCompression() {1097if (!canWriteCompressed()) {1098throw new UnsupportedOperationException(1099"Compression not supported");1100}1101if (getCompressionMode() != MODE_EXPLICIT) {1102throw new IllegalStateException1103("Compression mode not MODE_EXPLICIT!");1104}1105this.compressionType = null;1106this.compressionQuality = 1.0F;1107}11081109/**1110* Returns a localized version of the name of the current1111* compression type, using the <code>Locale</code> returned by1112* <code>getLocale</code>.1113*1114* <p> The default implementation checks whether compression is1115* supported and the compression mode is1116* <code>MODE_EXPLICIT</code>. If so, if1117* <code>compressionType</code> is <code>non-null</code> the value1118* of <code>getCompressionType</code> is returned as a1119* convenience.1120*1121* @return a <code>String</code> containing a localized version of1122* the name of the current compression type.1123*1124* @exception UnsupportedOperationException if the writer does not1125* support compression.1126* @exception IllegalStateException if the compression mode is not1127* <code>MODE_EXPLICIT</code>.1128* @exception IllegalStateException if no compression type is set.1129*/1130public String getLocalizedCompressionTypeName() {1131if (!canWriteCompressed()) {1132throw new UnsupportedOperationException(1133"Compression not supported.");1134}1135if (getCompressionMode() != MODE_EXPLICIT) {1136throw new IllegalStateException1137("Compression mode not MODE_EXPLICIT!");1138}1139if (getCompressionType() == null) {1140throw new IllegalStateException("No compression type set!");1141}1142return getCompressionType();1143}11441145/**1146* Returns <code>true</code> if the current compression type1147* provides lossless compression. If a plug-in provides only1148* one mandatory compression type, then this method may be1149* called without calling <code>setCompressionType</code> first.1150*1151* <p> If there are multiple compression types but none has1152* been set, an <code>IllegalStateException</code> is thrown.1153*1154* <p> The default implementation checks whether compression is1155* supported and the compression mode is1156* <code>MODE_EXPLICIT</code>. If so, if1157* <code>getCompressionTypes()</code> is <code>null</code> or1158* <code>getCompressionType()</code> is non-<code>null</code>1159* <code>true</code> is returned as a convenience.1160*1161* @return <code>true</code> if the current compression type is1162* lossless.1163*1164* @exception UnsupportedOperationException if the writer does not1165* support compression.1166* @exception IllegalStateException if the compression mode is not1167* <code>MODE_EXPLICIT</code>.1168* @exception IllegalStateException if the set of legal1169* compression types is non-<code>null</code> and the current1170* compression type is <code>null</code>.1171*/1172public boolean isCompressionLossless() {1173if (!canWriteCompressed()) {1174throw new UnsupportedOperationException(1175"Compression not supported");1176}1177if (getCompressionMode() != MODE_EXPLICIT) {1178throw new IllegalStateException1179("Compression mode not MODE_EXPLICIT!");1180}1181if ((getCompressionTypes() != null) &&1182(getCompressionType() == null)) {1183throw new IllegalStateException("No compression type set!");1184}1185return true;1186}11871188/**1189* Sets the compression quality to a value between <code>0</code>1190* and <code>1</code>. Only a single compression quality setting1191* is supported by default; writers can provide extended versions1192* of <code>ImageWriteParam</code> that offer more control. For1193* lossy compression schemes, the compression quality should1194* control the tradeoff between file size and image quality (for1195* example, by choosing quantization tables when writing JPEG1196* images). For lossless schemes, the compression quality may be1197* used to control the tradeoff between file size and time taken1198* to perform the compression (for example, by optimizing row1199* filters and setting the ZLIB compression level when writing1200* PNG images).1201*1202* <p> A compression quality setting of 0.0 is most generically1203* interpreted as "high compression is important," while a setting of1204* 1.0 is most generically interpreted as "high image quality is1205* important."1206*1207* <p> If there are multiple compression types but none has been1208* set, an <code>IllegalStateException</code> is thrown.1209*1210* <p> The default implementation checks that compression is1211* supported, and that the compression mode is1212* <code>MODE_EXPLICIT</code>. If so, if1213* <code>getCompressionTypes()</code> returns <code>null</code> or1214* <code>compressionType</code> is non-<code>null</code> it sets1215* the <code>compressionQuality</code> instance variable.1216*1217* @param quality a <code>float</code> between <code>0</code>and1218* <code>1</code> indicating the desired quality level.1219*1220* @exception UnsupportedOperationException if the writer does not1221* support compression.1222* @exception IllegalStateException if the compression mode is not1223* <code>MODE_EXPLICIT</code>.1224* @exception IllegalStateException if the set of legal1225* compression types is non-<code>null</code> and the current1226* compression type is <code>null</code>.1227* @exception IllegalArgumentException if <code>quality</code> is1228* not between <code>0</code>and <code>1</code>, inclusive.1229*1230* @see #getCompressionQuality1231*/1232public void setCompressionQuality(float quality) {1233if (!canWriteCompressed()) {1234throw new UnsupportedOperationException(1235"Compression not supported");1236}1237if (getCompressionMode() != MODE_EXPLICIT) {1238throw new IllegalStateException1239("Compression mode not MODE_EXPLICIT!");1240}1241if (getCompressionTypes() != null && getCompressionType() == null) {1242throw new IllegalStateException("No compression type set!");1243}1244if (quality < 0.0F || quality > 1.0F) {1245throw new IllegalArgumentException("Quality out-of-bounds!");1246}1247this.compressionQuality = quality;1248}12491250/**1251* Returns the current compression quality setting.1252*1253* <p> If there are multiple compression types but none has been1254* set, an <code>IllegalStateException</code> is thrown.1255*1256* <p> The default implementation checks that compression is1257* supported and that the compression mode is1258* <code>MODE_EXPLICIT</code>. If so, if1259* <code>getCompressionTypes()</code> is <code>null</code> or1260* <code>getCompressionType()</code> is non-<code>null</code>, it1261* returns the value of the <code>compressionQuality</code>1262* instance variable.1263*1264* @return the current compression quality setting.1265*1266* @exception UnsupportedOperationException if the writer does not1267* support compression.1268* @exception IllegalStateException if the compression mode is not1269* <code>MODE_EXPLICIT</code>.1270* @exception IllegalStateException if the set of legal1271* compression types is non-<code>null</code> and the current1272* compression type is <code>null</code>.1273*1274* @see #setCompressionQuality1275*/1276public float getCompressionQuality() {1277if (!canWriteCompressed()) {1278throw new UnsupportedOperationException(1279"Compression not supported.");1280}1281if (getCompressionMode() != MODE_EXPLICIT) {1282throw new IllegalStateException1283("Compression mode not MODE_EXPLICIT!");1284}1285if ((getCompressionTypes() != null) &&1286(getCompressionType() == null)) {1287throw new IllegalStateException("No compression type set!");1288}1289return compressionQuality;1290}129112921293/**1294* Returns a <code>float</code> indicating an estimate of the1295* number of bits of output data for each bit of input image data1296* at the given quality level. The value will typically lie1297* between <code>0</code> and <code>1</code>, with smaller values1298* indicating more compression. A special value of1299* <code>-1.0F</code> is used to indicate that no estimate is1300* available.1301*1302* <p> If there are multiple compression types but none has been set,1303* an <code>IllegalStateException</code> is thrown.1304*1305* <p> The default implementation checks that compression is1306* supported and the compression mode is1307* <code>MODE_EXPLICIT</code>. If so, if1308* <code>getCompressionTypes()</code> is <code>null</code> or1309* <code>getCompressionType()</code> is non-<code>null</code>, and1310* <code>quality</code> is within bounds, it returns1311* <code>-1.0</code>.1312*1313* @param quality the quality setting whose bit rate is to be1314* queried.1315*1316* @return an estimate of the compressed bit rate, or1317* <code>-1.0F</code> if no estimate is available.1318*1319* @exception UnsupportedOperationException if the writer does not1320* support compression.1321* @exception IllegalStateException if the compression mode is not1322* <code>MODE_EXPLICIT</code>.1323* @exception IllegalStateException if the set of legal1324* compression types is non-<code>null</code> and the current1325* compression type is <code>null</code>.1326* @exception IllegalArgumentException if <code>quality</code> is1327* not between <code>0</code>and <code>1</code>, inclusive.1328*/1329public float getBitRate(float quality) {1330if (!canWriteCompressed()) {1331throw new UnsupportedOperationException(1332"Compression not supported.");1333}1334if (getCompressionMode() != MODE_EXPLICIT) {1335throw new IllegalStateException1336("Compression mode not MODE_EXPLICIT!");1337}1338if ((getCompressionTypes() != null) &&1339(getCompressionType() == null)) {1340throw new IllegalStateException("No compression type set!");1341}1342if (quality < 0.0F || quality > 1.0F) {1343throw new IllegalArgumentException("Quality out-of-bounds!");1344}1345return -1.0F;1346}13471348/**1349* Returns an array of <code>String</code>s that may be used along1350* with <code>getCompressionQualityValues</code> as part of a user1351* interface for setting or displaying the compression quality1352* level. The <code>String</code> with index <code>i</code>1353* provides a description of the range of quality levels between1354* <code>getCompressionQualityValues[i]</code> and1355* <code>getCompressionQualityValues[i + 1]</code>. Note that the1356* length of the array returned from1357* <code>getCompressionQualityValues</code> will always be one1358* greater than that returned from1359* <code>getCompressionQualityDescriptions</code>.1360*1361* <p> As an example, the strings "Good", "Better", and "Best"1362* could be associated with the ranges <code>[0, .33)</code>,1363* <code>[.33, .66)</code>, and <code>[.66, 1.0]</code>. In this1364* case, <code>getCompressionQualityDescriptions</code> would1365* return <code>{ "Good", "Better", "Best" }</code> and1366* <code>getCompressionQualityValues</code> would return1367* <code>{ 0.0F, .33F, .66F, 1.0F }</code>.1368*1369* <p> If no descriptions are available, <code>null</code> is1370* returned. If <code>null</code> is returned from1371* <code>getCompressionQualityValues</code>, this method must also1372* return <code>null</code>.1373*1374* <p> The descriptions should be localized for the1375* <code>Locale</code> returned by <code>getLocale</code>, if it1376* is non-<code>null</code>.1377*1378* <p> If there are multiple compression types but none has been set,1379* an <code>IllegalStateException</code> is thrown.1380*1381* <p> The default implementation checks that compression is1382* supported and that the compression mode is1383* <code>MODE_EXPLICIT</code>. If so, if1384* <code>getCompressionTypes()</code> is <code>null</code> or1385* <code>getCompressionType()</code> is non-<code>null</code>, it1386* returns <code>null</code>.1387*1388* @return an array of <code>String</code>s containing localized1389* descriptions of the compression quality levels.1390*1391* @exception UnsupportedOperationException if the writer does not1392* support compression.1393* @exception IllegalStateException if the compression mode is not1394* <code>MODE_EXPLICIT</code>.1395* @exception IllegalStateException if the set of legal1396* compression types is non-<code>null</code> and the current1397* compression type is <code>null</code>.1398*1399* @see #getCompressionQualityValues1400*/1401public String[] getCompressionQualityDescriptions() {1402if (!canWriteCompressed()) {1403throw new UnsupportedOperationException(1404"Compression not supported.");1405}1406if (getCompressionMode() != MODE_EXPLICIT) {1407throw new IllegalStateException1408("Compression mode not MODE_EXPLICIT!");1409}1410if ((getCompressionTypes() != null) &&1411(getCompressionType() == null)) {1412throw new IllegalStateException("No compression type set!");1413}1414return null;1415}14161417/**1418* Returns an array of <code>float</code>s that may be used along1419* with <code>getCompressionQualityDescriptions</code> as part of a user1420* interface for setting or displaying the compression quality1421* level. See {@link #getCompressionQualityDescriptions1422* getCompressionQualityDescriptions} for more information.1423*1424* <p> If no descriptions are available, <code>null</code> is1425* returned. If <code>null</code> is returned from1426* <code>getCompressionQualityDescriptions</code>, this method1427* must also return <code>null</code>.1428*1429* <p> If there are multiple compression types but none has been set,1430* an <code>IllegalStateException</code> is thrown.1431*1432* <p> The default implementation checks that compression is1433* supported and that the compression mode is1434* <code>MODE_EXPLICIT</code>. If so, if1435* <code>getCompressionTypes()</code> is <code>null</code> or1436* <code>getCompressionType()</code> is non-<code>null</code>, it1437* returns <code>null</code>.1438*1439* @return an array of <code>float</code>s indicating the1440* boundaries between the compression quality levels as described1441* by the <code>String</code>s from1442* <code>getCompressionQualityDescriptions</code>.1443*1444* @exception UnsupportedOperationException if the writer does not1445* support compression.1446* @exception IllegalStateException if the compression mode is not1447* <code>MODE_EXPLICIT</code>.1448* @exception IllegalStateException if the set of legal1449* compression types is non-<code>null</code> and the current1450* compression type is <code>null</code>.1451*1452* @see #getCompressionQualityDescriptions1453*/1454public float[] getCompressionQualityValues() {1455if (!canWriteCompressed()) {1456throw new UnsupportedOperationException(1457"Compression not supported.");1458}1459if (getCompressionMode() != MODE_EXPLICIT) {1460throw new IllegalStateException1461("Compression mode not MODE_EXPLICIT!");1462}1463if ((getCompressionTypes() != null) &&1464(getCompressionType() == null)) {1465throw new IllegalStateException("No compression type set!");1466}1467return null;1468}1469}147014711472