Save This Page
Home » openjdk-7 » javax.imageio.plugins » jpeg » [javadoc | source]
    1   /*
    2    * Copyright 2000-2005 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.plugins.jpeg;
   27   
   28   import java.util.Locale;
   29   import javax.imageio.ImageWriteParam;
   30   
   31   import com.sun.imageio.plugins.jpeg.JPEG;
   32   
   33   /**
   34    * This class adds the ability to set JPEG quantization and Huffman
   35    * tables when using the built-in JPEG writer plug-in, and to request that
   36    * optimized Huffman tables be computed for an image.  An instance of
   37    * this class will be returned from the
   38    * <code>getDefaultImageWriteParam</code> methods of the built-in JPEG
   39    * <code>ImageWriter</code>.
   40   
   41    * <p> The principal purpose of these additions is to allow the
   42    * specification of tables to use in encoding abbreviated streams.
   43    * The built-in JPEG writer will also accept an ordinary
   44    * <code>ImageWriteParam</code>, in which case the writer will
   45    * construct the necessary tables internally.
   46    *
   47    * <p> In either case, the quality setting in an <code>ImageWriteParam</code>
   48    * has the same meaning as for the underlying library: 1.00 means a
   49    * quantization table of all 1's, 0.75 means the "standard", visually
   50    * lossless quantization table, and 0.00 means aquantization table of
   51    * all 255's.
   52    *
   53    * <p> While tables for abbreviated streams are often specified by
   54    * first writing an abbreviated stream containing only the tables, in
   55    * some applications the tables are fixed ahead of time.  This class
   56    * allows the tables to be specified directly from client code.
   57    *
   58    * <p> Normally, the tables are specified in the
   59    * <code>IIOMetadata</code> objects passed in to the writer, and any
   60    * tables included in these objects are written to the stream.
   61    * If no tables are specified in the metadata, then an abbreviated
   62    * stream is written.  If no tables are included in the metadata and
   63    * no tables are specified in a <code>JPEGImageWriteParam</code>, then
   64    * an abbreviated stream is encoded using the "standard" visually
   65    * lossless tables.  This class is necessary for specifying tables
   66    * when an abbreviated stream must be written without writing any tables
   67    * to a stream first.  In order to use this class, the metadata object
   68    * passed into the writer must contain no tables, and no stream metadata
   69    * must be provided.  See {@link JPEGQTable <code>JPEGQTable</code>} and
   70    * {@link JPEGHuffmanTable <code>JPEGHuffmanTable</code>} for more
   71    * information on the default tables.
   72    *
   73    * <p> The default <code>JPEGImageWriteParam</code> returned by the
   74    * <code>getDefaultWriteParam</code> method of the writer contains no
   75    * tables.  Default tables are included in the default
   76    * <code>IIOMetadata</code> objects returned by the writer.
   77    *
   78    * <p> If the metadata does contain tables, the tables given in a
   79    * <code>JPEGImageWriteParam</code> are ignored.  Furthermore, once a
   80    * set of tables has been written, only tables in the metadata can
   81    * override them for subsequent writes, whether to the same stream or
   82    * a different one.  In order to specify new tables using this class,
   83    * the {@link javax.imageio.ImageWriter#reset <code>reset</code>}
   84    * method of the writer must be called.
   85    *
   86    * <p>
   87    * For more information about the operation of the built-in JPEG plug-ins,
   88    * see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
   89    * metadata format specification and usage notes</A>.
   90    *
   91    */
   92   public class JPEGImageWriteParam extends ImageWriteParam {
   93   
   94       private JPEGQTable[] qTables = null;
   95       private JPEGHuffmanTable[] DCHuffmanTables = null;
   96       private JPEGHuffmanTable[] ACHuffmanTables = null;
   97       private boolean optimizeHuffman = false;
   98       private String[] compressionNames = {"JPEG"};
   99       private float[] qualityVals = { 0.00F, 0.30F, 0.75F, 1.00F };
  100       private String[] qualityDescs = {
  101           "Low quality",       // 0.00 -> 0.30
  102           "Medium quality",    // 0.30 -> 0.75
  103           "Visually lossless"  // 0.75 -> 1.00
  104       };
  105   
  106       /**
  107        * Constructs a <code>JPEGImageWriteParam</code>.  Tiling is not
  108        * supported.  Progressive encoding is supported. The default
  109        * progressive mode is MODE_DISABLED.  A single form of compression,
  110        * named "JPEG", is supported.  The default compression quality is
  111        * 0.75.
  112        *
  113        * @param locale a <code>Locale</code> to be used by the
  114        * superclass to localize compression type names and quality
  115        * descriptions, or <code>null</code>.
  116        */
  117       public JPEGImageWriteParam(Locale locale) {
  118           super(locale);
  119           this.canWriteProgressive = true;
  120           this.progressiveMode = MODE_DISABLED;
  121           this.canWriteCompressed = true;
  122           this.compressionTypes = compressionNames;
  123           this.compressionType = compressionTypes[0];
  124           this.compressionQuality = JPEG.DEFAULT_QUALITY;
  125       }
  126   
  127       /**
  128        * Removes any previous compression quality setting.
  129        *
  130        * <p> The default implementation resets the compression quality
  131        * to <code>0.75F</code>.
  132        *
  133        * @exception IllegalStateException if the compression mode is not
  134        * <code>MODE_EXPLICIT</code>.
  135        */
  136       public void unsetCompression() {
  137           if (getCompressionMode() != MODE_EXPLICIT) {
  138               throw new IllegalStateException
  139                   ("Compression mode not MODE_EXPLICIT!");
  140           }
  141           this.compressionQuality = JPEG.DEFAULT_QUALITY;
  142       }
  143   
  144       /**
  145        * Returns <code>false</code> since the JPEG plug-in only supports
  146        * lossy compression.
  147        *
  148        * @return <code>false</code>.
  149        *
  150        * @exception IllegalStateException if the compression mode is not
  151        * <code>MODE_EXPLICIT</code>.
  152        */
  153       public boolean isCompressionLossless() {
  154           if (getCompressionMode() != MODE_EXPLICIT) {
  155               throw new IllegalStateException
  156                   ("Compression mode not MODE_EXPLICIT!");
  157           }
  158           return false;
  159       }
  160   
  161       public String[] getCompressionQualityDescriptions() {
  162           if (getCompressionMode() != MODE_EXPLICIT) {
  163               throw new IllegalStateException
  164                   ("Compression mode not MODE_EXPLICIT!");
  165           }
  166           if ((getCompressionTypes() != null) &&
  167               (getCompressionType() == null)) {
  168               throw new IllegalStateException("No compression type set!");
  169           }
  170           return (String[])qualityDescs.clone();
  171       }
  172   
  173       public float[] getCompressionQualityValues() {
  174           if (getCompressionMode() != MODE_EXPLICIT) {
  175               throw new IllegalStateException
  176                   ("Compression mode not MODE_EXPLICIT!");
  177           }
  178           if ((getCompressionTypes() != null) &&
  179               (getCompressionType() == null)) {
  180               throw new IllegalStateException("No compression type set!");
  181           }
  182           return (float[])qualityVals.clone();
  183       }
  184       /**
  185        * Returns <code>true</code> if tables are currently set.
  186        *
  187        * @return <code>true</code> if tables are present.
  188        */
  189       public boolean areTablesSet() {
  190           return (qTables != null);
  191       }
  192   
  193       /**
  194        * Sets the quantization and Huffman tables to use in encoding
  195        * abbreviated streams.  There may be a maximum of 4 tables of
  196        * each type.  These tables are ignored if tables are specified in
  197        * the metadata.  All arguments must be non-<code>null</code>.
  198        * The two arrays of Huffman tables must have the same number of
  199        * elements.  The table specifiers in the frame and scan headers
  200        * in the metadata are assumed to be equivalent to indices into
  201        * these arrays.  The argument arrays are copied by this method.
  202        *
  203        * @param qTables An array of quantization table objects.
  204        * @param DCHuffmanTables An array of Huffman table objects.
  205        * @param ACHuffmanTables An array of Huffman table objects.
  206        *
  207        * @exception IllegalArgumentException if any of the arguments
  208        * is <code>null</code> or has more than 4 elements, or if the
  209        * numbers of DC and AC tables differ.
  210        *
  211        * @see #unsetEncodeTables
  212        */
  213       public void setEncodeTables(JPEGQTable[] qTables,
  214                                   JPEGHuffmanTable[] DCHuffmanTables,
  215                                   JPEGHuffmanTable[] ACHuffmanTables) {
  216           if ((qTables == null) ||
  217               (DCHuffmanTables == null) ||
  218               (ACHuffmanTables == null) ||
  219               (qTables.length > 4) ||
  220               (DCHuffmanTables.length > 4) ||
  221               (ACHuffmanTables.length > 4) ||
  222               (DCHuffmanTables.length != ACHuffmanTables.length)) {
  223                   throw new IllegalArgumentException("Invalid JPEG table arrays");
  224           }
  225           this.qTables = (JPEGQTable[])qTables.clone();
  226           this.DCHuffmanTables = (JPEGHuffmanTable[])DCHuffmanTables.clone();
  227           this.ACHuffmanTables = (JPEGHuffmanTable[])ACHuffmanTables.clone();
  228       }
  229   
  230       /**
  231        * Removes any quantization and Huffman tables that are currently
  232        * set.
  233        *
  234        * @see #setEncodeTables
  235        */
  236       public void unsetEncodeTables() {
  237           this.qTables = null;
  238           this.DCHuffmanTables = null;
  239           this.ACHuffmanTables = null;
  240       }
  241   
  242       /**
  243        * Returns a copy of the array of quantization tables set on the
  244        * most recent call to <code>setEncodeTables</code>, or
  245        * <code>null</code> if tables are not currently set.
  246        *
  247        * @return an array of <code>JPEGQTable</code> objects, or
  248        * <code>null</code>.
  249        *
  250        * @see #setEncodeTables
  251        */
  252       public JPEGQTable[] getQTables() {
  253           return (qTables != null) ? (JPEGQTable[])qTables.clone() : null;
  254       }
  255   
  256       /**
  257        * Returns a copy of the array of DC Huffman tables set on the
  258        * most recent call to <code>setEncodeTables</code>, or
  259        * <code>null</code> if tables are not currently set.
  260        *
  261        * @return an array of <code>JPEGHuffmanTable</code> objects, or
  262        * <code>null</code>.
  263        *
  264        * @see #setEncodeTables
  265        */
  266       public JPEGHuffmanTable[] getDCHuffmanTables() {
  267           return (DCHuffmanTables != null)
  268               ? (JPEGHuffmanTable[])DCHuffmanTables.clone()
  269               : null;
  270       }
  271   
  272       /**
  273        * Returns a copy of the array of AC Huffman tables set on the
  274        * most recent call to <code>setEncodeTables</code>, or
  275        * <code>null</code> if tables are not currently set.
  276        *
  277        * @return an array of <code>JPEGHuffmanTable</code> objects, or
  278        * <code>null</code>.
  279        *
  280        * @see #setEncodeTables
  281        */
  282       public JPEGHuffmanTable[] getACHuffmanTables() {
  283           return (ACHuffmanTables != null)
  284               ? (JPEGHuffmanTable[])ACHuffmanTables.clone()
  285               : null;
  286       }
  287   
  288       /**
  289        * Tells the writer to generate optimized Huffman tables
  290        * for the image as part of the writing process.  The
  291        * default is <code>false</code>.  If this flag is set
  292        * to <code>true</code>, it overrides any tables specified
  293        * in the metadata.  Note that this means that any image
  294        * written with this flag set to <code>true</code> will
  295        * always contain Huffman tables.
  296        *
  297        * @param optimize A boolean indicating whether to generate
  298        * optimized Huffman tables when writing.
  299        *
  300        * @see #getOptimizeHuffmanTables
  301        */
  302       public void setOptimizeHuffmanTables(boolean optimize) {
  303           optimizeHuffman = optimize;
  304       }
  305   
  306       /**
  307        * Returns the value passed into the most recent call
  308        * to <code>setOptimizeHuffmanTables</code>, or
  309        * <code>false</code> if <code>setOptimizeHuffmanTables</code>
  310        * has never been called.
  311        *
  312        * @return <code>true</code> if the writer will generate optimized
  313        * Huffman tables.
  314        *
  315        * @see #setOptimizeHuffmanTables
  316        */
  317       public boolean getOptimizeHuffmanTables() {
  318           return optimizeHuffman;
  319       }
  320   }

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