Save This Page
Home » openjdk-7 » javax » imageio » [javadoc | source]
    1   /*
    2    * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.imageio;
   27   
   28   import java.awt.Dimension;
   29   import java.util.Locale;
   30   
   31   /**
   32    * A class describing how a stream is to be encoded.  Instances of
   33    * this class or its subclasses are used to supply prescriptive
   34    * "how-to" information to instances of <code>ImageWriter</code>.
   35    *
   36    * <p> A plug-in for a specific image format may define a subclass of
   37    * this class, and return objects of that class from the
   38    * <code>getDefaultWriteParam</code> method of its
   39    * <code>ImageWriter</code> implementation.  For example, the built-in
   40    * JPEG writer plug-in will return instances of
   41    * <code>javax.imageio.plugins.jpeg.JPEGImageWriteParam</code>.
   42    *
   43    * <p> The region of the image to be written is determined by first
   44    * intersecting the actual bounds of the image with the rectangle
   45    * specified by <code>IIOParam.setSourceRegion</code>, if any.  If the
   46    * resulting rectangle has a width or height of zero, the writer will
   47    * throw an <code>IIOException</code>. If the intersection is
   48    * non-empty, writing will commence with the first subsampled pixel
   49    * and include additional pixels within the intersected bounds
   50    * according to the horizontal and vertical subsampling factors
   51    * specified by {@link IIOParam#setSourceSubsampling
   52    * <code>IIOParam.setSourceSubsampling</code>}.
   53    *
   54    * <p> Individual features such as tiling, progressive encoding, and
   55    * compression may be set in one of four modes.
   56    * <code>MODE_DISABLED</code> disables the features;
   57    * <code>MODE_DEFAULT</code> enables the feature with
   58    * writer-controlled parameter values; <code>MODE_EXPLICIT</code>
   59    * enables the feature and allows the use of a <code>set</code> method
   60    * to provide additional parameters; and
   61    * <code>MODE_COPY_FROM_METADATA</code> copies relevant parameter
   62    * values from the stream and image metadata objects passed to the
   63    * writer.  The default for all features is
   64    * <code>MODE_COPY_FROM_METADATA</code>.  Non-standard features
   65    * supplied in subclasses are encouraged, but not required to use a
   66    * similar scheme.
   67    *
   68    * <p> Plug-in writers may extend the functionality of
   69    * <code>ImageWriteParam</code> by providing a subclass that implements
   70    * additional, plug-in specific interfaces.  It is up to the plug-in
   71    * to document what interfaces are available and how they are to be
   72    * used.  Writers will silently ignore any extended features of an
   73    * <code>ImageWriteParam</code> subclass of which they are not aware.
   74    * Also, they may ignore any optional features that they normally
   75    * disable when creating their own <code>ImageWriteParam</code>
   76    * instances via <code>getDefaultWriteParam</code>.
   77    *
   78    * <p> Note that unless a query method exists for a capability, it must
   79    * be supported by all <code>ImageWriter</code> implementations
   80    * (<i>e.g.</i> progressive encoding is optional, but subsampling must be
   81    * supported).
   82    *
   83    *
   84    * @see ImageReadParam
   85    */
   86   public class ImageWriteParam extends IIOParam {
   87   
   88       /**
   89        * A constant value that may be passed into methods such as
   90        * <code>setTilingMode</code>, <code>setProgressiveMode</code>,
   91        * and <code>setCompressionMode</code> to disable a feature for
   92        * future writes.  That is, when this mode is set the stream will
   93        * <b>not</b> be tiled, progressive, or compressed, and the
   94        * relevant accessor methods will throw an
   95        * <code>IllegalStateException</code>.
   96        *
   97        * @see #MODE_EXPLICIT
   98        * @see #MODE_COPY_FROM_METADATA
   99        * @see #MODE_DEFAULT
  100        * @see #setProgressiveMode
  101        * @see #getProgressiveMode
  102        * @see #setTilingMode
  103        * @see #getTilingMode
  104        * @see #setCompressionMode
  105        * @see #getCompressionMode
  106        */
  107       public static final int MODE_DISABLED = 0;
  108   
  109       /**
  110        * A constant value that may be passed into methods such as
  111        * <code>setTilingMode</code>,
  112        * <code>setProgressiveMode</code>, and
  113        * <code>setCompressionMode</code> to enable that feature for
  114        * future writes.  That is, when this mode is enabled the stream
  115        * will be tiled, progressive, or compressed according to a
  116        * sensible default chosen internally by the writer in a plug-in
  117        * dependent way, and the relevant accessor methods will
  118        * throw an <code>IllegalStateException</code>.
  119        *
  120        * @see #MODE_DISABLED
  121        * @see #MODE_EXPLICIT
  122        * @see #MODE_COPY_FROM_METADATA
  123        * @see #setProgressiveMode
  124        * @see #getProgressiveMode
  125        * @see #setTilingMode
  126        * @see #getTilingMode
  127        * @see #setCompressionMode
  128        * @see #getCompressionMode
  129        */
  130       public static final int MODE_DEFAULT = 1;
  131   
  132       /**
  133        * A constant value that may be passed into methods such as
  134        * <code>setTilingMode</code> or <code>setCompressionMode</code>
  135        * to enable a feature for future writes. That is, when this mode
  136        * is set the stream will be tiled or compressed according to
  137        * additional information supplied to the corresponding
  138        * <code>set</code> methods in this class and retrievable from the
  139        * corresponding <code>get</code> methods.  Note that this mode is
  140        * not supported for progressive output.
  141        *
  142        * @see #MODE_DISABLED
  143        * @see #MODE_COPY_FROM_METADATA
  144        * @see #MODE_DEFAULT
  145        * @see #setProgressiveMode
  146        * @see #getProgressiveMode
  147        * @see #setTilingMode
  148        * @see #getTilingMode
  149        * @see #setCompressionMode
  150        * @see #getCompressionMode
  151        */
  152       public static final int MODE_EXPLICIT = 2;
  153   
  154       /**
  155        * A constant value that may be passed into methods such as
  156        * <code>setTilingMode</code>, <code>setProgressiveMode</code>, or
  157        * <code>setCompressionMode</code> to enable that feature for
  158        * future writes.  That is, when this mode is enabled the stream
  159        * will be tiled, progressive, or compressed based on the contents
  160        * of stream and/or image metadata passed into the write
  161        * operation, and any relevant accessor methods will throw an
  162        * <code>IllegalStateException</code>.
  163        *
  164        * <p> This is the default mode for all features, so that a read
  165        * including metadata followed by a write including metadata will
  166        * preserve as much information as possible.
  167        *
  168        * @see #MODE_DISABLED
  169        * @see #MODE_EXPLICIT
  170        * @see #MODE_DEFAULT
  171        * @see #setProgressiveMode
  172        * @see #getProgressiveMode
  173        * @see #setTilingMode
  174        * @see #getTilingMode
  175        * @see #setCompressionMode
  176        * @see #getCompressionMode
  177        */
  178       public static final int MODE_COPY_FROM_METADATA = 3;
  179   
  180       // If more modes are added, this should be updated.
  181       private static final int MAX_MODE = MODE_COPY_FROM_METADATA;
  182   
  183       /**
  184        * A <code>boolean</code> that is <code>true</code> if this
  185        * <code>ImageWriteParam</code> allows tile width and tile height
  186        * parameters to be set.  By default, the value is
  187        * <code>false</code>.  Subclasses must set the value manually.
  188        *
  189        * <p> Subclasses that do not support writing tiles should ensure
  190        * that this value is set to <code>false</code>.
  191        */
  192       protected boolean canWriteTiles = false;
  193   
  194       /**
  195        * The mode controlling tiling settings, which Must be
  196        * set to one of the four <code>MODE_*</code> values.  The default
  197        * is <code>MODE_COPY_FROM_METADATA</code>.
  198        *
  199        * <p> Subclasses that do not writing tiles may ignore this value.
  200        *
  201        * @see #MODE_DISABLED
  202        * @see #MODE_EXPLICIT
  203        * @see #MODE_COPY_FROM_METADATA
  204        * @see #MODE_DEFAULT
  205        * @see #setTilingMode
  206        * @see #getTilingMode
  207        */
  208       protected int tilingMode = MODE_COPY_FROM_METADATA;
  209   
  210       /**
  211        * An array of preferred tile size range pairs.  The default value
  212        * is <code>null</code>, which indicates that there are no
  213        * preferred sizes.  If the value is non-<code>null</code>, it
  214        * must have an even length of at least two.
  215        *
  216        * <p> Subclasses that do not support writing tiles may ignore
  217        * this value.
  218        *
  219        * @see #getPreferredTileSizes
  220        */
  221       protected Dimension[] preferredTileSizes = null;
  222   
  223       /**
  224        * A <code>boolean</code> that is <code>true</code> if tiling
  225        * parameters have been specified.
  226        *
  227        * <p> Subclasses that do not support writing tiles may ignore
  228        * this value.
  229        */
  230       protected boolean tilingSet = false;
  231   
  232       /**
  233        * The width of each tile if tiling has been set, or 0 otherwise.
  234        *
  235        * <p> Subclasses that do not support tiling may ignore this
  236        * value.
  237        */
  238       protected int tileWidth = 0;
  239   
  240       /**
  241        * The height of each tile if tiling has been set, or 0 otherwise.
  242        * The initial value is <code>0</code>.
  243        *
  244        * <p> Subclasses that do not support tiling may ignore this
  245        * value.
  246        */
  247       protected int tileHeight = 0;
  248   
  249       /**
  250        * A <code>boolean</code> that is <code>true</code> if this
  251        * <code>ImageWriteParam</code> allows tiling grid offset
  252        * parameters to be set.  By default, the value is
  253        * <code>false</code>.  Subclasses must set the value manually.
  254        *
  255        * <p> Subclasses that do not support writing tiles, or that
  256        * supprt writing but not offsetting tiles must ensure that this
  257        * value is set to <code>false</code>.
  258        */
  259       protected boolean canOffsetTiles = false;
  260   
  261       /**
  262        * The amount by which the tile grid origin should be offset
  263        * horizontally from the image origin if tiling has been set,
  264        * or 0 otherwise.  The initial value is <code>0</code>.
  265        *
  266        * <p> Subclasses that do not support offsetting tiles may ignore
  267        * this value.
  268        */
  269       protected int tileGridXOffset = 0;
  270   
  271       /**
  272        * The amount by which the tile grid origin should be offset
  273        * vertically from the image origin if tiling has been set,
  274        * or 0 otherwise.  The initial value is <code>0</code>.
  275        *
  276        * <p> Subclasses that do not support offsetting tiles may ignore
  277        * this value.
  278        */
  279       protected int tileGridYOffset = 0;
  280   
  281       /**
  282        * A <code>boolean</code> that is <code>true</code> if this
  283        * <code>ImageWriteParam</code> allows images to be written as a
  284        * progressive sequence of increasing quality passes.  By default,
  285        * the value is <code>false</code>.  Subclasses must set the value
  286        * manually.
  287        *
  288        * <p> Subclasses that do not support progressive encoding must
  289        * ensure that this value is set to <code>false</code>.
  290        */
  291       protected boolean canWriteProgressive = false;
  292   
  293       /**
  294        * The mode controlling progressive encoding, which must be set to
  295        * one of the four <code>MODE_*</code> values, except
  296        * <code>MODE_EXPLICIT</code>.  The default is
  297        * <code>MODE_COPY_FROM_METADATA</code>.
  298        *
  299        * <p> Subclasses that do not support progressive encoding may
  300        * ignore this value.
  301        *
  302        * @see #MODE_DISABLED
  303        * @see #MODE_EXPLICIT
  304        * @see #MODE_COPY_FROM_METADATA
  305        * @see #MODE_DEFAULT
  306        * @see #setProgressiveMode
  307        * @see #getProgressiveMode
  308        */
  309       protected int progressiveMode = MODE_COPY_FROM_METADATA;
  310   
  311       /**
  312        * A <code>boolean</code> that is <code>true</code> if this writer
  313        * can write images using compression. By default, the value is
  314        * <code>false</code>.  Subclasses must set the value manually.
  315        *
  316        * <p> Subclasses that do not support compression must ensure that
  317        * this value is set to <code>false</code>.
  318        */
  319       protected boolean canWriteCompressed = false;
  320   
  321       /**
  322        * The mode controlling compression settings, which must be set to
  323        * one of the four <code>MODE_*</code> values.  The default is
  324        * <code>MODE_COPY_FROM_METADATA</code>.
  325        *
  326        * <p> Subclasses that do not support compression may ignore this
  327        * value.
  328        *
  329        * @see #MODE_DISABLED
  330        * @see #MODE_EXPLICIT
  331        * @see #MODE_COPY_FROM_METADATA
  332        * @see #MODE_DEFAULT
  333        * @see #setCompressionMode
  334        * @see #getCompressionMode
  335        */
  336       protected int compressionMode = MODE_COPY_FROM_METADATA;
  337   
  338       /**
  339        * An array of <code>String</code>s containing the names of the
  340        * available compression types.  Subclasses must set the value
  341        * manually.
  342        *
  343        * <p> Subclasses that do not support compression may ignore this
  344        * value.
  345        */
  346       protected String[] compressionTypes = null;
  347   
  348       /**
  349        * A <code>String</code> containing the name of the current
  350        * compression type, or <code>null</code> if none is set.
  351        *
  352        * <p> Subclasses that do not support compression may ignore this
  353        * value.
  354        */
  355       protected String compressionType = null;
  356   
  357       /**
  358        * A <code>float</code> containing the current compression quality
  359        * setting.  The initial value is <code>1.0F</code>.
  360        *
  361        * <p> Subclasses that do not support compression may ignore this
  362        * value.
  363        */
  364       protected float compressionQuality = 1.0F;
  365   
  366       /**
  367        * A <code>Locale</code> to be used to localize compression type
  368        * names and quality descriptions, or <code>null</code> to use a
  369        * default <code>Locale</code>.  Subclasses must set the value
  370        * manually.
  371        */
  372       protected Locale locale = null;
  373   
  374       /**
  375        * Constructs an empty <code>ImageWriteParam</code>.  It is up to
  376        * the subclass to set up the instance variables properly.
  377        */
  378       protected ImageWriteParam() {}
  379   
  380       /**
  381        * Constructs an <code>ImageWriteParam</code> set to use a
  382        * given <code>Locale</code>.
  383        *
  384        * @param locale a <code>Locale</code> to be used to localize
  385        * compression type names and quality descriptions, or
  386        * <code>null</code>.
  387        */
  388       public ImageWriteParam(Locale locale) {
  389           this.locale = locale;
  390       }
  391   
  392       // Return a deep copy of the array
  393       private static Dimension[] clonePreferredTileSizes(Dimension[] sizes) {
  394           if (sizes == null) {
  395               return null;
  396           }
  397           Dimension[] temp = new Dimension[sizes.length];
  398           for (int i = 0; i < sizes.length; i++) {
  399               temp[i] = new Dimension(sizes[i]);
  400           }
  401           return temp;
  402       }
  403   
  404       /**
  405        * Returns the currently set <code>Locale</code>, or
  406        * <code>null</code> if only a default <code>Locale</code> is
  407        * supported.
  408        *
  409        * @return the current <code>Locale</code>, or <code>null</code>.
  410        */
  411       public Locale getLocale() {
  412           return locale;
  413       }
  414   
  415       /**
  416        * Returns <code>true</code> if the writer can perform tiling
  417        * while writing.  If this method returns <code>false</code>, then
  418        * <code>setTiling</code> will throw an
  419        * <code>UnsupportedOperationException</code>.
  420        *
  421        * @return <code>true</code> if the writer supports tiling.
  422        *
  423        * @see #canOffsetTiles()
  424        * @see #setTiling(int, int, int, int)
  425        */
  426       public boolean canWriteTiles() {
  427           return canWriteTiles;
  428       }
  429   
  430       /**
  431        * Returns <code>true</code> if the writer can perform tiling with
  432        * non-zero grid offsets while writing.  If this method returns
  433        * <code>false</code>, then <code>setTiling</code> will throw an
  434        * <code>UnsupportedOperationException</code> if the grid offset
  435        * arguments are not both zero.  If <code>canWriteTiles</code>
  436        * returns <code>false</code>, this method will return
  437        * <code>false</code> as well.
  438        *
  439        * @return <code>true</code> if the writer supports non-zero tile
  440        * offsets.
  441        *
  442        * @see #canWriteTiles()
  443        * @see #setTiling(int, int, int, int)
  444        */
  445       public boolean canOffsetTiles() {
  446           return canOffsetTiles;
  447       }
  448   
  449       /**
  450        * Determines whether the image will be tiled in the output
  451        * stream and, if it will, how the tiling parameters will be
  452        * determined.  The modes are interpreted as follows:
  453        *
  454        * <ul>
  455        *
  456        * <li><code>MODE_DISABLED</code> - The image will not be tiled.
  457        * <code>setTiling</code> will throw an
  458        * <code>IllegalStateException</code>.
  459        *
  460        * <li><code>MODE_DEFAULT</code> - The image will be tiled using
  461        * default parameters.  <code>setTiling</code> will throw an
  462        * <code>IllegalStateException</code>.
  463        *
  464        * <li><code>MODE_EXPLICIT</code> - The image will be tiled
  465        * according to parameters given in the {@link #setTiling
  466        * <code>setTiling</code>} method.  Any previously set tiling
  467        * parameters are discarded.
  468        *
  469        * <li><code>MODE_COPY_FROM_METADATA</code> - The image will
  470        * conform to the metadata object passed in to a write.
  471        * <code>setTiling</code> will throw an
  472        * <code>IllegalStateException</code>.
  473        *
  474        * </ul>
  475        *
  476        * @param mode The mode to use for tiling.
  477        *
  478        * @exception UnsupportedOperationException if
  479        * <code>canWriteTiles</code> returns <code>false</code>.
  480        * @exception IllegalArgumentException if <code>mode</code> is not
  481        * one of the modes listed above.
  482        *
  483        * @see #setTiling
  484        * @see #getTilingMode
  485        */
  486       public void setTilingMode(int mode) {
  487           if (canWriteTiles() == false) {
  488               throw new UnsupportedOperationException("Tiling not supported!");
  489           }
  490           if (mode < MODE_DISABLED || mode > MAX_MODE) {
  491               throw new IllegalArgumentException("Illegal value for mode!");
  492           }
  493           this.tilingMode = mode;
  494           if (mode == MODE_EXPLICIT) {
  495               unsetTiling();
  496           }
  497       }
  498   
  499       /**
  500        * Returns the current tiling mode, if tiling is supported.
  501        * Otherwise throws an <code>UnsupportedOperationException</code>.
  502        *
  503        * @return the current tiling mode.
  504        *
  505        * @exception UnsupportedOperationException if
  506        * <code>canWriteTiles</code> returns <code>false</code>.
  507        *
  508        * @see #setTilingMode
  509        */
  510       public int getTilingMode() {
  511           if (!canWriteTiles()) {
  512               throw new UnsupportedOperationException("Tiling not supported");
  513           }
  514           return tilingMode;
  515       }
  516   
  517       /**
  518        * Returns an array of <code>Dimension</code>s indicating the
  519        * legal size ranges for tiles as they will be encoded in the
  520        * output file or stream.  The returned array is a copy.
  521        *
  522        * <p> The information is returned as a set of pairs; the first
  523        * element of a pair contains an (inclusive) minimum width and
  524        * height, and the second element contains an (inclusive) maximum
  525        * width and height.  Together, each pair defines a valid range of
  526        * sizes.  To specify a fixed size, use the same width and height
  527        * for both elements.  To specify an arbitrary range, a value of
  528        * <code>null</code> is used in place of an actual array of
  529        * <code>Dimension</code>s.
  530        *
  531        * <p> If no array is specified on the constructor, but tiling is
  532        * allowed, then this method returns <code>null</code>.
  533        *
  534        * @exception UnsupportedOperationException if the plug-in does
  535        * not support tiling.
  536        *
  537        * @return an array of <code>Dimension</code>s with an even length
  538        * of at least two, or <code>null</code>.
  539        */
  540       public Dimension[] getPreferredTileSizes() {
  541           if (!canWriteTiles()) {
  542               throw new UnsupportedOperationException("Tiling not supported");
  543           }
  544           return clonePreferredTileSizes(preferredTileSizes);
  545       }
  546   
  547       /**
  548        * Specifies that the image should be tiled in the output stream.
  549        * The <code>tileWidth</code> and <code>tileHeight</code>
  550        * parameters specify the width and height of the tiles in the
  551        * file.  If the tile width or height is greater than the width or
  552        * height of the image, the image is not tiled in that dimension.
  553        *
  554        * <p> If <code>canOffsetTiles</code> returns <code>false</code>,
  555        * then the <code>tileGridXOffset</code> and
  556        * <code>tileGridYOffset</code> parameters must be zero.
  557        *
  558        * @param tileWidth the width of each tile.
  559        * @param tileHeight the height of each tile.
  560        * @param tileGridXOffset the horizontal offset of the tile grid.
  561        * @param tileGridYOffset the vertical offset of the tile grid.
  562        *
  563        * @exception UnsupportedOperationException if the plug-in does not
  564        * support tiling.
  565        * @exception IllegalStateException if the tiling mode is not
  566        * <code>MODE_EXPLICIT</code>.
  567        * @exception UnsupportedOperationException if the plug-in does not
  568        * support grid offsets, and the grid offsets are not both zero.
  569        * @exception IllegalArgumentException if the tile size is not
  570        * within one of the allowable ranges returned by
  571        * <code>getPreferredTileSizes</code>.
  572        * @exception IllegalArgumentException if <code>tileWidth</code>
  573        * or <code>tileHeight</code> is less than or equal to 0.
  574        *
  575        * @see #canWriteTiles
  576        * @see #canOffsetTiles
  577        * @see #getTileWidth()
  578        * @see #getTileHeight()
  579        * @see #getTileGridXOffset()
  580        * @see #getTileGridYOffset()
  581        */
  582       public void setTiling(int tileWidth,
  583                             int tileHeight,
  584                             int tileGridXOffset,
  585                             int tileGridYOffset) {
  586           if (!canWriteTiles()) {
  587               throw new UnsupportedOperationException("Tiling not supported!");
  588           }
  589           if (getTilingMode() != MODE_EXPLICIT) {
  590               throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
  591           }
  592           if (tileWidth <= 0 || tileHeight <= 0) {
  593               throw new IllegalArgumentException
  594                   ("tile dimensions are non-positive!");
  595           }
  596           boolean tilesOffset = (tileGridXOffset != 0) || (tileGridYOffset != 0);
  597           if (!canOffsetTiles() && tilesOffset) {
  598               throw new UnsupportedOperationException("Can't offset tiles!");
  599           }
  600           if (preferredTileSizes != null) {
  601               boolean ok = true;
  602               for (int i = 0; i < preferredTileSizes.length; i += 2) {
  603                   Dimension min = preferredTileSizes[i];
  604                   Dimension max = preferredTileSizes[i+1];
  605                   if ((tileWidth < min.width) ||
  606                       (tileWidth > max.width) ||
  607                       (tileHeight < min.height) ||
  608                       (tileHeight > max.height)) {
  609                       ok = false;
  610                       break;
  611                   }
  612               }
  613               if (!ok) {
  614                   throw new IllegalArgumentException("Illegal tile size!");
  615               }
  616           }
  617   
  618           this.tilingSet = true;
  619           this.tileWidth = tileWidth;
  620           this.tileHeight = tileHeight;
  621           this.tileGridXOffset = tileGridXOffset;
  622           this.tileGridYOffset = tileGridYOffset;
  623       }
  624   
  625       /**
  626        * Removes any previous tile grid parameters specified by calls to
  627        * <code>setTiling</code>.
  628        *
  629        * <p> The default implementation sets the instance variables
  630        * <code>tileWidth</code>, <code>tileHeight</code>,
  631        * <code>tileGridXOffset</code>, and
  632        * <code>tileGridYOffset</code> to <code>0</code>.
  633        *
  634        * @exception UnsupportedOperationException if the plug-in does not
  635        * support tiling.
  636        * @exception IllegalStateException if the tiling mode is not
  637        * <code>MODE_EXPLICIT</code>.
  638        *
  639        * @see #setTiling(int, int, int, int)
  640        */
  641       public void unsetTiling() {
  642           if (!canWriteTiles()) {
  643               throw new UnsupportedOperationException("Tiling not supported!");
  644           }
  645           if (getTilingMode() != MODE_EXPLICIT) {
  646               throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
  647           }
  648           this.tilingSet = false;
  649           this.tileWidth = 0;
  650           this.tileHeight = 0;
  651           this.tileGridXOffset = 0;
  652           this.tileGridYOffset = 0;
  653       }
  654   
  655       /**
  656        * Returns the width of each tile in an image as it will be
  657        * written to the output stream.  If tiling parameters have not
  658        * been set, an <code>IllegalStateException</code> is thrown.
  659        *
  660        * @return the tile width to be used for encoding.
  661        *
  662        * @exception UnsupportedOperationException if the plug-in does not
  663        * support tiling.
  664        * @exception IllegalStateException if the tiling mode is not
  665        * <code>MODE_EXPLICIT</code>.
  666        * @exception IllegalStateException if the tiling parameters have
  667        * not been set.
  668        *
  669        * @see #setTiling(int, int, int, int)
  670        * @see #getTileHeight()
  671        */
  672       public int getTileWidth() {
  673           if (!canWriteTiles()) {
  674               throw new UnsupportedOperationException("Tiling not supported!");
  675           }
  676           if (getTilingMode() != MODE_EXPLICIT) {
  677               throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
  678           }
  679           if (!tilingSet) {
  680               throw new IllegalStateException("Tiling parameters not set!");
  681           }
  682           return tileWidth;
  683       }
  684   
  685       /**
  686        * Returns the height of each tile in an image as it will be written to
  687        * the output stream.  If tiling parameters have not
  688        * been set, an <code>IllegalStateException</code> is thrown.
  689        *
  690        * @return the tile height to be used for encoding.
  691        *
  692        * @exception UnsupportedOperationException if the plug-in does not
  693        * support tiling.
  694        * @exception IllegalStateException if the tiling mode is not
  695        * <code>MODE_EXPLICIT</code>.
  696        * @exception IllegalStateException if the tiling parameters have
  697        * not been set.
  698        *
  699        * @see #setTiling(int, int, int, int)
  700        * @see #getTileWidth()
  701        */
  702       public int getTileHeight() {
  703           if (!canWriteTiles()) {
  704               throw new UnsupportedOperationException("Tiling not supported!");
  705           }
  706           if (getTilingMode() != MODE_EXPLICIT) {
  707               throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
  708           }
  709           if (!tilingSet) {
  710               throw new IllegalStateException("Tiling parameters not set!");
  711           }
  712           return tileHeight;
  713       }
  714   
  715       /**
  716        * Returns the horizontal tile grid offset of an image as it will
  717        * be written to the output stream.  If tiling parameters have not
  718        * been set, an <code>IllegalStateException</code> is thrown.
  719        *
  720        * @return the tile grid X offset to be used for encoding.
  721        *
  722        * @exception UnsupportedOperationException if the plug-in does not
  723        * support tiling.
  724        * @exception IllegalStateException if the tiling mode is not
  725        * <code>MODE_EXPLICIT</code>.
  726        * @exception IllegalStateException if the tiling parameters have
  727        * not been set.
  728        *
  729        * @see #setTiling(int, int, int, int)
  730        * @see #getTileGridYOffset()
  731        */
  732       public int getTileGridXOffset() {
  733           if (!canWriteTiles()) {
  734               throw new UnsupportedOperationException("Tiling not supported!");
  735           }
  736           if (getTilingMode() != MODE_EXPLICIT) {
  737               throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
  738           }
  739           if (!tilingSet) {
  740               throw new IllegalStateException("Tiling parameters not set!");
  741           }
  742           return tileGridXOffset;
  743       }
  744   
  745       /**
  746        * Returns the vertical tile grid offset of an image as it will
  747        * be written to the output stream.  If tiling parameters have not
  748        * been set, an <code>IllegalStateException</code> is thrown.
  749        *
  750        * @return the tile grid Y offset to be used for encoding.
  751        *
  752        * @exception UnsupportedOperationException if the plug-in does not
  753        * support tiling.
  754        * @exception IllegalStateException if the tiling mode is not
  755        * <code>MODE_EXPLICIT</code>.
  756        * @exception IllegalStateException if the tiling parameters have
  757        * not been set.
  758        *
  759        * @see #setTiling(int, int, int, int)
  760        * @see #getTileGridXOffset()
  761        */
  762       public int getTileGridYOffset() {
  763           if (!canWriteTiles()) {
  764               throw new UnsupportedOperationException("Tiling not supported!");
  765           }
  766           if (getTilingMode() != MODE_EXPLICIT) {
  767               throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
  768           }
  769           if (!tilingSet) {
  770               throw new IllegalStateException("Tiling parameters not set!");
  771           }
  772           return tileGridYOffset;
  773       }
  774   
  775       /**
  776        * Returns <code>true</code> if the writer can write out images
  777        * as a series of passes of progressively increasing quality.
  778        *
  779        * @return <code>true</code> if the writer supports progressive
  780        * encoding.
  781        *
  782        * @see #setProgressiveMode
  783        * @see #getProgressiveMode
  784        */
  785       public boolean canWriteProgressive() {
  786           return canWriteProgressive;
  787       }
  788   
  789       /**
  790        * Specifies that the writer is to write the image out in a
  791        * progressive mode such that the stream will contain a series of
  792        * scans of increasing quality.  If progressive encoding is not
  793        * supported, an <code>UnsupportedOperationException</code> will
  794        * be thrown.
  795        *
  796        * <p>  The mode argument determines how
  797        * the progression parameters are chosen, and must be either
  798        * <code>MODE_DISABLED</code>,
  799        * <code>MODE_COPY_FROM_METADATA</code>, or
  800        * <code>MODE_DEFAULT</code>.  Otherwise an
  801        * <code>IllegalArgumentException</code> is thrown.
  802        *
  803        * <p> The modes are interpreted as follows:
  804        *
  805        * <ul>
  806        *   <li><code>MODE_DISABLED</code> - No progression.  Use this to
  807        *   turn off progession.
  808        *
  809        *   <li><code>MODE_COPY_FROM_METADATA</code> - The output image
  810        *   will use whatever progression parameters are found in the
  811        *   metadata objects passed into the writer.
  812        *
  813        *   <li><code>MODE_DEFAULT</code> - The image will be written
  814        *   progressively, with parameters chosen by the writer.
  815        * </ul>
  816        *
  817        * <p> The default is <code>MODE_COPY_FROM_METADATA</code>.
  818        *
  819        * @param mode The mode for setting progression in the output
  820        * stream.
  821        *
  822        * @exception UnsupportedOperationException if the writer does not
  823        * support progressive encoding.
  824        * @exception IllegalArgumentException if <code>mode</code> is not
  825        * one of the modes listed above.
  826        *
  827        * @see #getProgressiveMode
  828        */
  829       public void setProgressiveMode(int mode) {
  830           if (!canWriteProgressive()) {
  831               throw new UnsupportedOperationException(
  832                   "Progressive output not supported");
  833           }
  834           if (mode < MODE_DISABLED || mode > MAX_MODE) {
  835               throw new IllegalArgumentException("Illegal value for mode!");
  836           }
  837           if (mode == MODE_EXPLICIT) {
  838               throw new IllegalArgumentException(
  839                   "MODE_EXPLICIT not supported for progressive output");
  840           }
  841           this.progressiveMode = mode;
  842       }
  843   
  844       /**
  845        * Returns the current mode for writing the stream in a
  846        * progressive manner.
  847        *
  848        * @return the current mode for progressive encoding.
  849        *
  850        * @exception UnsupportedOperationException if the writer does not
  851        * support progressive encoding.
  852        *
  853        * @see #setProgressiveMode
  854        */
  855       public int getProgressiveMode() {
  856           if (!canWriteProgressive()) {
  857               throw new UnsupportedOperationException
  858                   ("Progressive output not supported");
  859           }
  860           return progressiveMode;
  861       }
  862   
  863       /**
  864        * Returns <code>true</code> if this writer supports compression.
  865        *
  866        * @return <code>true</code> if the writer supports compression.
  867        */
  868       public boolean canWriteCompressed() {
  869           return canWriteCompressed;
  870       }
  871   
  872       /**
  873        * Specifies whether compression is to be performed, and if so how
  874        * compression parameters are to be determined.  The <code>mode</code>
  875        * argument must be one of the four modes, interpreted as follows:
  876        *
  877        * <ul>
  878        *   <li><code>MODE_DISABLED</code> - If the mode is set to
  879        *   <code>MODE_DISABLED</code>, methods that query or modify the
  880        *   compression type or parameters will throw an
  881        *   <code>IllegalStateException</code> (if compression is
  882        *   normally supported by the plug-in). Some writers, such as JPEG,
  883        *   do not normally offer uncompressed output. In this case, attempting
  884        *   to set the mode to <code>MODE_DISABLED</code> will throw an
  885        *   <code>UnsupportedOperationException</code> and the mode will not be
  886        *   changed.
  887        *
  888        *   <li><code>MODE_EXPLICIT</code> - Compress using the
  889        *   compression type and quality settings specified in this
  890        *   <code>ImageWriteParam</code>.  Any previously set compression
  891        *   parameters are discarded.
  892        *
  893        *   <li><code>MODE_COPY_FROM_METADATA</code> - Use whatever
  894        *   compression parameters are specified in metadata objects
  895        *   passed in to the writer.
  896        *
  897        *   <li><code>MODE_DEFAULT</code> - Use default compression
  898        *   parameters.
  899        * </ul>
  900        *
  901        * <p> The default is <code>MODE_COPY_FROM_METADATA</code>.
  902        *
  903        * @param mode The mode for setting compression in the output
  904        * stream.
  905        *
  906        * @exception UnsupportedOperationException if the writer does not
  907        * support compression, or does not support the requested mode.
  908        * @exception IllegalArgumentException if <code>mode</code> is not
  909        * one of the modes listed above.
  910        *
  911        * @see #getCompressionMode
  912        */
  913       public void setCompressionMode(int mode) {
  914           if (!canWriteCompressed()) {
  915               throw new UnsupportedOperationException(
  916                   "Compression not supported.");
  917           }
  918           if (mode < MODE_DISABLED || mode > MAX_MODE) {
  919               throw new IllegalArgumentException("Illegal value for mode!");
  920           }
  921           this.compressionMode = mode;
  922           if (mode == MODE_EXPLICIT) {
  923               unsetCompression();
  924           }
  925       }
  926   
  927       /**
  928        * Returns the current compression mode, if compression is
  929        * supported.
  930        *
  931        * @return the current compression mode.
  932        *
  933        * @exception UnsupportedOperationException if the writer does not
  934        * support compression.
  935        *
  936        * @see #setCompressionMode
  937        */
  938       public int getCompressionMode() {
  939           if (!canWriteCompressed()) {
  940               throw new UnsupportedOperationException(
  941                   "Compression not supported.");
  942           }
  943           return compressionMode;
  944       }
  945   
  946       /**
  947        * Returns a list of available compression types, as an array or
  948        * <code>String</code>s, or <code>null</code> if a compression
  949        * type may not be chosen using these interfaces.  The array
  950        * returned is a copy.
  951        *
  952        * <p> If the writer only offers a single, mandatory form of
  953        * compression, it is not necessary to provide any named
  954        * compression types.  Named compression types should only be
  955        * used where the user is able to make a meaningful choice
  956        * between different schemes.
  957        *
  958        * <p> The default implementation checks if compression is
  959        * supported and throws an
  960        * <code>UnsupportedOperationException</code> if not.  Otherwise,
  961        * it returns a clone of the <code>compressionTypes</code>
  962        * instance variable if it is non-<code>null</code>, or else
  963        * returns <code>null</code>.
  964        *
  965        * @return an array of <code>String</code>s containing the
  966        * (non-localized) names of available compression types, or
  967        * <code>null</code>.
  968        *
  969        * @exception UnsupportedOperationException if the writer does not
  970        * support compression.
  971        */
  972       public String[] getCompressionTypes() {
  973           if (!canWriteCompressed()) {
  974               throw new UnsupportedOperationException(
  975                   "Compression not supported");
  976           }
  977           if (compressionTypes == null) {
  978               return null;
  979           }
  980           return (String[])compressionTypes.clone();
  981       }
  982   
  983       /**
  984        * Sets the compression type to one of the values indicated by
  985        * <code>getCompressionTypes</code>.  If a value of
  986        * <code>null</code> is passed in, any previous setting is
  987        * removed.
  988        *
  989        * <p> The default implementation checks whether compression is
  990        * supported and the compression mode is
  991        * <code>MODE_EXPLICIT</code>.  If so, it calls
  992        * <code>getCompressionTypes</code> and checks if
  993        * <code>compressionType</code> is one of the legal values.  If it
  994        * is, the <code>compressionType</code> instance variable is set.
  995        * If <code>compressionType</code> is <code>null</code>, the
  996        * instance variable is set without performing any checking.
  997        *
  998        * @param compressionType one of the <code>String</code>s returned
  999        * by <code>getCompressionTypes</code>, or <code>null</code> to
 1000        * remove any previous setting.
 1001        *
 1002        * @exception UnsupportedOperationException if the writer does not
 1003        * support compression.
 1004        * @exception IllegalStateException if the compression mode is not
 1005        * <code>MODE_EXPLICIT</code>.
 1006        * @exception UnsupportedOperationException if there are no
 1007        * settable compression types.
 1008        * @exception IllegalArgumentException if
 1009        * <code>compressionType</code> is non-<code>null</code> but is not
 1010        * one of the values returned by <code>getCompressionTypes</code>.
 1011        *
 1012        * @see #getCompressionTypes
 1013        * @see #getCompressionType
 1014        * @see #unsetCompression
 1015        */
 1016       public void setCompressionType(String compressionType) {
 1017           if (!canWriteCompressed()) {
 1018               throw new UnsupportedOperationException(
 1019                   "Compression not supported");
 1020           }
 1021           if (getCompressionMode() != MODE_EXPLICIT) {
 1022               throw new IllegalStateException
 1023                   ("Compression mode not MODE_EXPLICIT!");
 1024           }
 1025           String[] legalTypes = getCompressionTypes();
 1026           if (legalTypes == null) {
 1027               throw new UnsupportedOperationException(
 1028                   "No settable compression types");
 1029           }
 1030           if (compressionType != null) {
 1031               boolean found = false;
 1032               if (legalTypes != null) {
 1033                   for (int i = 0; i < legalTypes.length; i++) {
 1034                       if (compressionType.equals(legalTypes[i])) {
 1035                           found = true;
 1036                           break;
 1037                       }
 1038                   }
 1039               }
 1040               if (!found) {
 1041                   throw new IllegalArgumentException("Unknown compression type!");
 1042               }
 1043           }
 1044           this.compressionType = compressionType;
 1045       }
 1046   
 1047       /**
 1048        * Returns the currently set compression type, or
 1049        * <code>null</code> if none has been set.  The type is returned
 1050        * as a <code>String</code> from among those returned by
 1051        * <code>getCompressionTypes</code>.
 1052        * If no compression type has been set, <code>null</code> is
 1053        * returned.
 1054        *
 1055        * <p> The default implementation checks whether compression is
 1056        * supported and the compression mode is
 1057        * <code>MODE_EXPLICIT</code>.  If so, it returns the value of the
 1058        * <code>compressionType</code> instance variable.
 1059        *
 1060        * @return the current compression type as a <code>String</code>,
 1061        * or <code>null</code> if no type is set.
 1062        *
 1063        * @exception UnsupportedOperationException if the writer does not
 1064        * support compression.
 1065        * @exception IllegalStateException if the compression mode is not
 1066        * <code>MODE_EXPLICIT</code>.
 1067        *
 1068        * @see #setCompressionType
 1069        */
 1070       public String getCompressionType() {
 1071           if (!canWriteCompressed()) {
 1072               throw new UnsupportedOperationException(
 1073                   "Compression not supported.");
 1074           }
 1075           if (getCompressionMode() != MODE_EXPLICIT) {
 1076               throw new IllegalStateException
 1077                   ("Compression mode not MODE_EXPLICIT!");
 1078           }
 1079           return compressionType;
 1080       }
 1081   
 1082       /**
 1083        * Removes any previous compression type and quality settings.
 1084        *
 1085        * <p> The default implementation sets the instance variable
 1086        * <code>compressionType</code> to <code>null</code>, and the
 1087        * instance variable <code>compressionQuality</code> to
 1088        * <code>1.0F</code>.
 1089        *
 1090        * @exception UnsupportedOperationException if the plug-in does not
 1091        * support compression.
 1092        * @exception IllegalStateException if the compression mode is not
 1093        * <code>MODE_EXPLICIT</code>.
 1094        *
 1095        * @see #setCompressionType
 1096        * @see #setCompressionQuality
 1097        */
 1098       public void unsetCompression() {
 1099           if (!canWriteCompressed()) {
 1100               throw new UnsupportedOperationException(
 1101                   "Compression not supported");
 1102           }
 1103           if (getCompressionMode() != MODE_EXPLICIT) {
 1104               throw new IllegalStateException
 1105                   ("Compression mode not MODE_EXPLICIT!");
 1106           }
 1107           this.compressionType = null;
 1108           this.compressionQuality = 1.0F;
 1109       }
 1110   
 1111       /**
 1112        * Returns a localized version of the name of the current
 1113        * compression type, using the <code>Locale</code> returned by
 1114        * <code>getLocale</code>.
 1115        *
 1116        * <p> The default implementation checks whether compression is
 1117        * supported and the compression mode is
 1118        * <code>MODE_EXPLICIT</code>.  If so, if
 1119        * <code>compressionType</code> is <code>non-null</code> the value
 1120        * of <code>getCompressionType</code> is returned as a
 1121        * convenience.
 1122        *
 1123        * @return a <code>String</code> containing a localized version of
 1124        * the name of the current compression type.
 1125        *
 1126        * @exception UnsupportedOperationException if the writer does not
 1127        * support compression.
 1128        * @exception IllegalStateException if the compression mode is not
 1129        * <code>MODE_EXPLICIT</code>.
 1130        * @exception IllegalStateException if no compression type is set.
 1131        */
 1132       public String getLocalizedCompressionTypeName() {
 1133           if (!canWriteCompressed()) {
 1134               throw new UnsupportedOperationException(
 1135                   "Compression not supported.");
 1136           }
 1137           if (getCompressionMode() != MODE_EXPLICIT) {
 1138               throw new IllegalStateException
 1139                   ("Compression mode not MODE_EXPLICIT!");
 1140           }
 1141           if (getCompressionType() == null) {
 1142               throw new IllegalStateException("No compression type set!");
 1143           }
 1144           return getCompressionType();
 1145       }
 1146   
 1147       /**
 1148        * Returns <code>true</code> if the current compression type
 1149        * provides lossless compression.  If a plug-in provides only
 1150        * one mandatory compression type, then this method may be
 1151        * called without calling <code>setCompressionType</code> first.
 1152        *
 1153        * <p> If there are multiple compression types but none has
 1154        * been set, an <code>IllegalStateException</code> is thrown.
 1155        *
 1156        * <p> The default implementation checks whether compression is
 1157        * supported and the compression mode is
 1158        * <code>MODE_EXPLICIT</code>.  If so, if
 1159        * <code>getCompressionTypes()</code> is <code>null</code> or
 1160        * <code>getCompressionType()</code> is non-<code>null</code>
 1161        * <code>true</code> is returned as a convenience.
 1162        *
 1163        * @return <code>true</code> if the current compression type is
 1164        * lossless.
 1165        *
 1166        * @exception UnsupportedOperationException if the writer does not
 1167        * support compression.
 1168        * @exception IllegalStateException if the compression mode is not
 1169        * <code>MODE_EXPLICIT</code>.
 1170        * @exception IllegalStateException if the set of legal
 1171        * compression types is non-<code>null</code> and the current
 1172        * compression type is <code>null</code>.
 1173        */
 1174       public boolean isCompressionLossless() {
 1175           if (!canWriteCompressed()) {
 1176               throw new UnsupportedOperationException(
 1177                   "Compression not supported");
 1178           }
 1179           if (getCompressionMode() != MODE_EXPLICIT) {
 1180               throw new IllegalStateException
 1181                   ("Compression mode not MODE_EXPLICIT!");
 1182           }
 1183           if ((getCompressionTypes() != null) &&
 1184               (getCompressionType() == null)) {
 1185               throw new IllegalStateException("No compression type set!");
 1186           }
 1187           return true;
 1188       }
 1189   
 1190       /**
 1191        * Sets the compression quality to a value between <code>0</code>
 1192        * and <code>1</code>.  Only a single compression quality setting
 1193        * is supported by default; writers can provide extended versions
 1194        * of <code>ImageWriteParam</code> that offer more control.  For
 1195        * lossy compression schemes, the compression quality should
 1196        * control the tradeoff between file size and image quality (for
 1197        * example, by choosing quantization tables when writing JPEG
 1198        * images).  For lossless schemes, the compression quality may be
 1199        * used to control the tradeoff between file size and time taken
 1200        * to perform the compression (for example, by optimizing row
 1201        * filters and setting the ZLIB compression level when writing
 1202        * PNG images).
 1203        *
 1204        * <p> A compression quality setting of 0.0 is most generically
 1205        * interpreted as "high compression is important," while a setting of
 1206        * 1.0 is most generically interpreted as "high image quality is
 1207        * important."
 1208        *
 1209        * <p> If there are multiple compression types but none has been
 1210        * set, an <code>IllegalStateException</code> is thrown.
 1211        *
 1212        * <p> The default implementation checks that compression is
 1213        * supported, and that the compression mode is
 1214        * <code>MODE_EXPLICIT</code>.  If so, if
 1215        * <code>getCompressionTypes()</code> returns <code>null</code> or
 1216        * <code>compressionType</code> is non-<code>null</code> it sets
 1217        * the <code>compressionQuality</code> instance variable.
 1218        *
 1219        * @param quality a <code>float</code> between <code>0</code>and
 1220        * <code>1</code> indicating the desired quality level.
 1221        *
 1222        * @exception UnsupportedOperationException if the writer does not
 1223        * support compression.
 1224        * @exception IllegalStateException if the compression mode is not
 1225        * <code>MODE_EXPLICIT</code>.
 1226        * @exception IllegalStateException if the set of legal
 1227        * compression types is non-<code>null</code> and the current
 1228        * compression type is <code>null</code>.
 1229        * @exception IllegalArgumentException if <code>quality</code> is
 1230        * not between <code>0</code>and <code>1</code>, inclusive.
 1231        *
 1232        * @see #getCompressionQuality
 1233        */
 1234       public void setCompressionQuality(float quality) {
 1235           if (!canWriteCompressed()) {
 1236               throw new UnsupportedOperationException(
 1237                   "Compression not supported");
 1238           }
 1239           if (getCompressionMode() != MODE_EXPLICIT) {
 1240               throw new IllegalStateException
 1241                   ("Compression mode not MODE_EXPLICIT!");
 1242           }
 1243           if (getCompressionTypes() != null && getCompressionType() == null) {
 1244               throw new IllegalStateException("No compression type set!");
 1245           }
 1246           if (quality < 0.0F || quality > 1.0F) {
 1247               throw new IllegalArgumentException("Quality out-of-bounds!");
 1248           }
 1249           this.compressionQuality = quality;
 1250       }
 1251   
 1252       /**
 1253        * Returns the current compression quality setting.
 1254        *
 1255        * <p> If there are multiple compression types but none has been
 1256        * set, an <code>IllegalStateException</code> is thrown.
 1257        *
 1258        * <p> The default implementation checks that compression is
 1259        * supported and that the compression mode is
 1260        * <code>MODE_EXPLICIT</code>.  If so, if
 1261        * <code>getCompressionTypes()</code> is <code>null</code> or
 1262        * <code>getCompressionType()</code> is non-<code>null</code>, it
 1263        * returns the value of the <code>compressionQuality</code>
 1264        * instance variable.
 1265        *
 1266        * @return the current compression quality setting.
 1267        *
 1268        * @exception UnsupportedOperationException if the writer does not
 1269        * support compression.
 1270        * @exception IllegalStateException if the compression mode is not
 1271        * <code>MODE_EXPLICIT</code>.
 1272        * @exception IllegalStateException if the set of legal
 1273        * compression types is non-<code>null</code> and the current
 1274        * compression type is <code>null</code>.
 1275        *
 1276        * @see #setCompressionQuality
 1277        */
 1278       public float getCompressionQuality() {
 1279           if (!canWriteCompressed()) {
 1280               throw new UnsupportedOperationException(
 1281                   "Compression not supported.");
 1282           }
 1283           if (getCompressionMode() != MODE_EXPLICIT) {
 1284               throw new IllegalStateException
 1285                   ("Compression mode not MODE_EXPLICIT!");
 1286           }
 1287           if ((getCompressionTypes() != null) &&
 1288               (getCompressionType() == null)) {
 1289               throw new IllegalStateException("No compression type set!");
 1290           }
 1291           return compressionQuality;
 1292       }
 1293   
 1294   
 1295       /**
 1296        * Returns a <code>float</code> indicating an estimate of the
 1297        * number of bits of output data for each bit of input image data
 1298        * at the given quality level.  The value will typically lie
 1299        * between <code>0</code> and <code>1</code>, with smaller values
 1300        * indicating more compression.  A special value of
 1301        * <code>-1.0F</code> is used to indicate that no estimate is
 1302        * available.
 1303        *
 1304        * <p> If there are multiple compression types but none has been set,
 1305        * an <code>IllegalStateException</code> is thrown.
 1306        *
 1307        * <p> The default implementation checks that compression is
 1308        * supported and the compression mode is
 1309        * <code>MODE_EXPLICIT</code>.  If so, if
 1310        * <code>getCompressionTypes()</code> is <code>null</code> or
 1311        * <code>getCompressionType()</code> is non-<code>null</code>, and
 1312        * <code>quality</code> is within bounds, it returns
 1313        * <code>-1.0</code>.
 1314        *
 1315        * @param quality the quality setting whose bit rate is to be
 1316        * queried.
 1317        *
 1318        * @return an estimate of the compressed bit rate, or
 1319        * <code>-1.0F</code> if no estimate is available.
 1320        *
 1321        * @exception UnsupportedOperationException if the writer does not
 1322        * support compression.
 1323        * @exception IllegalStateException if the compression mode is not
 1324        * <code>MODE_EXPLICIT</code>.
 1325        * @exception IllegalStateException if the set of legal
 1326        * compression types is non-<code>null</code> and the current
 1327        * compression type is <code>null</code>.
 1328        * @exception IllegalArgumentException if <code>quality</code> is
 1329        * not between <code>0</code>and <code>1</code>, inclusive.
 1330        */
 1331       public float getBitRate(float quality) {
 1332           if (!canWriteCompressed()) {
 1333               throw new UnsupportedOperationException(
 1334                   "Compression not supported.");
 1335           }
 1336           if (getCompressionMode() != MODE_EXPLICIT) {
 1337               throw new IllegalStateException
 1338                   ("Compression mode not MODE_EXPLICIT!");
 1339           }
 1340           if ((getCompressionTypes() != null) &&
 1341               (getCompressionType() == null)) {
 1342               throw new IllegalStateException("No compression type set!");
 1343           }
 1344           if (quality < 0.0F || quality > 1.0F) {
 1345               throw new IllegalArgumentException("Quality out-of-bounds!");
 1346           }
 1347           return -1.0F;
 1348       }
 1349   
 1350       /**
 1351        * Returns an array of <code>String</code>s that may be used along
 1352        * with <code>getCompressionQualityValues</code> as part of a user
 1353        * interface for setting or displaying the compression quality
 1354        * level.  The <code>String</code> with index <code>i</code>
 1355        * provides a description of the range of quality levels between
 1356        * <code>getCompressionQualityValues[i]</code> and
 1357        * <code>getCompressionQualityValues[i + 1]</code>.  Note that the
 1358        * length of the array returned from
 1359        * <code>getCompressionQualityValues</code> will always be one
 1360        * greater than that returned from
 1361        * <code>getCompressionQualityDescriptions</code>.
 1362        *
 1363        * <p> As an example, the strings "Good", "Better", and "Best"
 1364        * could be associated with the ranges <code>[0, .33)</code>,
 1365        * <code>[.33, .66)</code>, and <code>[.66, 1.0]</code>.  In this
 1366        * case, <code>getCompressionQualityDescriptions</code> would
 1367        * return <code>{ "Good", "Better", "Best" }</code> and
 1368        * <code>getCompressionQualityValues</code> would return
 1369        * <code>{ 0.0F, .33F, .66F, 1.0F }</code>.
 1370        *
 1371        * <p> If no descriptions are available, <code>null</code> is
 1372        * returned.  If <code>null</code> is returned from
 1373        * <code>getCompressionQualityValues</code>, this method must also
 1374        * return <code>null</code>.
 1375        *
 1376        * <p> The descriptions should be localized for the
 1377        * <code>Locale</code> returned by <code>getLocale</code>, if it
 1378        * is non-<code>null</code>.
 1379        *
 1380        * <p> If there are multiple compression types but none has been set,
 1381        * an <code>IllegalStateException</code> is thrown.
 1382        *
 1383        * <p> The default implementation checks that compression is
 1384        * supported and that the compression mode is
 1385        * <code>MODE_EXPLICIT</code>.  If so, if
 1386        * <code>getCompressionTypes()</code> is <code>null</code> or
 1387        * <code>getCompressionType()</code> is non-<code>null</code>, it
 1388        * returns <code>null</code>.
 1389        *
 1390        * @return an array of <code>String</code>s containing localized
 1391        * descriptions of the compression quality levels.
 1392        *
 1393        * @exception UnsupportedOperationException if the writer does not
 1394        * support compression.
 1395        * @exception IllegalStateException if the compression mode is not
 1396        * <code>MODE_EXPLICIT</code>.
 1397        * @exception IllegalStateException if the set of legal
 1398        * compression types is non-<code>null</code> and the current
 1399        * compression type is <code>null</code>.
 1400        *
 1401        * @see #getCompressionQualityValues
 1402        */
 1403       public String[] getCompressionQualityDescriptions() {
 1404           if (!canWriteCompressed()) {
 1405               throw new UnsupportedOperationException(
 1406                   "Compression not supported.");
 1407           }
 1408           if (getCompressionMode() != MODE_EXPLICIT) {
 1409               throw new IllegalStateException
 1410                   ("Compression mode not MODE_EXPLICIT!");
 1411           }
 1412           if ((getCompressionTypes() != null) &&
 1413               (getCompressionType() == null)) {
 1414               throw new IllegalStateException("No compression type set!");
 1415           }
 1416           return null;
 1417       }
 1418   
 1419       /**
 1420        * Returns an array of <code>float</code>s that may be used along
 1421        * with <code>getCompressionQualityDescriptions</code> as part of a user
 1422        * interface for setting or displaying the compression quality
 1423        * level.  See {@link #getCompressionQualityDescriptions
 1424        * <code>getCompressionQualityDescriptions</code>} for more information.
 1425        *
 1426        * <p> If no descriptions are available, <code>null</code> is
 1427        * returned.  If <code>null</code> is returned from
 1428        * <code>getCompressionQualityDescriptions</code>, this method
 1429        * must also return <code>null</code>.
 1430        *
 1431        * <p> If there are multiple compression types but none has been set,
 1432        * an <code>IllegalStateException</code> is thrown.
 1433        *
 1434        * <p> The default implementation checks that compression is
 1435        * supported and that the compression mode is
 1436        * <code>MODE_EXPLICIT</code>.  If so, if
 1437        * <code>getCompressionTypes()</code> is <code>null</code> or
 1438        * <code>getCompressionType()</code> is non-<code>null</code>, it
 1439        * returns <code>null</code>.
 1440        *
 1441        * @return an array of <code>float</code>s indicating the
 1442        * boundaries between the compression quality levels as described
 1443        * by the <code>String</code>s from
 1444        * <code>getCompressionQualityDescriptions</code>.
 1445        *
 1446        * @exception UnsupportedOperationException if the writer does not
 1447        * support compression.
 1448        * @exception IllegalStateException if the compression mode is not
 1449        * <code>MODE_EXPLICIT</code>.
 1450        * @exception IllegalStateException if the set of legal
 1451        * compression types is non-<code>null</code> and the current
 1452        * compression type is <code>null</code>.
 1453        *
 1454        * @see #getCompressionQualityDescriptions
 1455        */
 1456       public float[] getCompressionQualityValues() {
 1457           if (!canWriteCompressed()) {
 1458               throw new UnsupportedOperationException(
 1459                   "Compression not supported.");
 1460           }
 1461           if (getCompressionMode() != MODE_EXPLICIT) {
 1462               throw new IllegalStateException
 1463                   ("Compression mode not MODE_EXPLICIT!");
 1464           }
 1465           if ((getCompressionTypes() != null) &&
 1466               (getCompressionType() == null)) {
 1467               throw new IllegalStateException("No compression type set!");
 1468           }
 1469           return null;
 1470       }
 1471   }

Save This Page
Home » openjdk-7 » javax » imageio » [javadoc | source]