Source for javax.imageio.plugins.jpeg.JPEGImageWriteParam

   1: /* JPEGImageWriteParam.java --
   2:  Copyright (C)  2006  Free Software Foundation, Inc.
   3: 
   4:  This file is part of GNU Classpath.
   5: 
   6:  GNU Classpath is free software; you can redistribute it and/or modify
   7:  it under the terms of the GNU General Public License as published by
   8:  the Free Software Foundation; either version 2, or (at your option)
   9:  any later version.
  10: 
  11:  GNU Classpath is distributed in the hope that it will be useful, but
  12:  WITHOUT ANY WARRANTY; without even the implied warranty of
  13:  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14:  General Public License for more details.
  15: 
  16:  You should have received a copy of the GNU General Public License
  17:  along with GNU Classpath; see the file COPYING.  If not, write to the
  18:  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19:  02110-1301 USA.
  20: 
  21:  Linking this library statically or dynamically with other modules is
  22:  making a combined work based on this library.  Thus, the terms and
  23:  conditions of the GNU General Public License cover the whole
  24:  combination.
  25: 
  26:  As a special exception, the copyright holders of this library give you
  27:  permission to link this library with independent modules to produce an
  28:  executable, regardless of the license terms of these independent
  29:  modules, and to copy and distribute the resulting executable under
  30:  terms of your choice, provided that you also meet, for each linked
  31:  independent module, the terms and conditions of the license of that
  32:  module.  An independent module is a module which is not derived from
  33:  or based on this library.  If you modify this library, you may extend
  34:  this exception to your version of the library, but you are not
  35:  obligated to do so.  If you do not wish to do so, delete this
  36:  exception statement from your version. */
  37: 
  38: 
  39: package javax.imageio.plugins.jpeg;
  40: 
  41: import java.util.Locale;
  42: import java.util.PropertyResourceBundle;
  43: import java.util.ResourceBundle;
  44: import javax.imageio.ImageWriteParam;
  45: 
  46: /**
  47:  * The JPEGImageWriteParam class can be used to specify tables and
  48:  * settings used in the JPEG encoding process.  Encoding tables are
  49:  * taken from the metadata associated with the output stream, and
  50:  * failing that (if the metadata tables are null) from an instance of
  51:  * JPEGImageWriteParam.  The default metadata uses the standard JPEG
  52:  * tables from the JPEGQTable and JPEGHuffmanTable classes.  Non-null
  53:  * metadata tables override JPEGImageWriteParam tables.  Compression
  54:  * settings range from 1.0, best compression, through 0.75, default
  55:  * compression, to 0.0, worst compression.
  56:  *
  57:  * A JPEGImageWriteParam instance is retrieved from the built-in JPEG
  58:  * ImageWriter using the getDefaultImageWriteParam method.
  59:  */
  60: public class JPEGImageWriteParam
  61:   extends ImageWriteParam
  62: {
  63:   private JPEGQTable[] qTables;
  64:   private JPEGHuffmanTable[] DCHuffmanTables;
  65:   private JPEGHuffmanTable[] ACHuffmanTables;
  66:   private boolean optimize;
  67:   private String[] compressionQualityDescriptions;
  68:   private float[] compressionQualityValues;
  69: 
  70:   /**
  71:    * Localized messages are stored in separate files.
  72:    */
  73:   private ResourceBundle messages;
  74: 
  75:   /**
  76:    * Construct a JPEGImageWriteParam with the following state: tiling
  77:    * is not supported, progressive mode is supported, initial
  78:    * progressive mode is MODE_DISABLED, compression is supported, one
  79:    * compression type named "JPEG" is supported and the default
  80:    * compression quality is 0.75f.  Compression type names and
  81:    * compression quality descriptions are localized to the given
  82:    * locale.
  83:    *
  84:    * @param locale the locale used for message localization
  85:    */
  86:   public JPEGImageWriteParam(Locale locale)
  87:   {
  88:     super(locale);
  89: 
  90:     // Get localized compression type and compression quality
  91:     // description strings for the given locale.
  92:     messages = PropertyResourceBundle.getBundle
  93:       ("javax/imageio/plugins/jpeg/MessagesBundle", locale);
  94: 
  95:     // Initialize inherited ImageWriter fields.
  96:     canWriteTiles = false;
  97:     canWriteProgressive = true;
  98:     progressiveMode = MODE_DISABLED;
  99:     canWriteCompressed = true;
 100:     compressionTypes = new String[]
 101:       {
 102:         messages.getString("compression.types.jpeg")
 103:       };
 104:     compressionType = compressionTypes[0];
 105:     compressionQuality = 0.75f;
 106:   }
 107: 
 108:   /**
 109:    * Reset the compression quality to 0.75f.
 110:    */
 111:   public void unsetCompression()
 112:   {
 113:     compressionQuality = 0.75f;
 114:   }
 115: 
 116:   /**
 117:    * Check if compression algorithm is lossless.  JPEGImageWriteParam
 118:    * overrides this ImageWriteParam method to always return false
 119:    * since JPEG compression is inherently lossy.
 120:    *
 121:    * @return false
 122:    */
 123:   public boolean isCompressionLossless()
 124:   {
 125:     return false;
 126:   }
 127: 
 128:   /**
 129:    * Retrieve an array of compression quality descriptions.  These
 130:    * messages are localized using the locale provided upon
 131:    * construction.  Each compression quality description in the
 132:    * returned array corresponds to the compression quality value at
 133:    * the same index in the array returned by
 134:    * getCompressionQualityValues.
 135:    *
 136:    * @return an array of strings each of which describes a compression
 137:    * quality value
 138:    */
 139:   public String[] getCompressionQualityDescriptions()
 140:   {
 141:     // Make sure exceptions are thrown when this image write param is
 142:     // in the wrong state.
 143:     super.getCompressionQualityDescriptions();
 144: 
 145:     if (compressionQualityDescriptions == null)
 146:       {
 147:         compressionQualityDescriptions = new String[]
 148:           {
 149:             messages.getString("compression.minimum"),
 150:             messages.getString("compression.default"),
 151:             messages.getString("compression.maximum")
 152:           };
 153:       }
 154: 
 155:     return compressionQualityDescriptions;
 156:   }
 157: 
 158:   /**
 159:    * Retrieve an array of compression quality values, ordered from
 160:    * lowest quality to highest quality.
 161:    *
 162:    * @return an array of compressions quality values
 163:    */
 164:   public float[] getCompressionQualityValues()
 165:   {
 166:     // Make sure exceptions are thrown when this image write param is
 167:     // in the wrong state.
 168:     super.getCompressionQualityValues();
 169: 
 170:     if (compressionQualityValues == null)
 171:       compressionQualityValues = new float[] { 0.05f, 0.75f, 0.95f };
 172: 
 173:     return compressionQualityValues;
 174:   }
 175: 
 176:   /**
 177:    * Check if the encoding tables are set.
 178:    *
 179:    * @return true if the encoding tables are set, false otherwise
 180:    */
 181:   public boolean areTablesSet()
 182:   {
 183:     // If qTables is not null then all tables are set.
 184:     return (qTables != null);
 185:   }
 186: 
 187:   /**
 188:    * Set the quantization and Huffman tables that will be used to
 189:    * encode the stream.  Copies are created of the array arguments.
 190:    * The number of Huffman tables must be the same in both Huffman
 191:    * table arrays.  No argument may be null and no array may be longer
 192:    * than four elements.
 193:    *
 194:    * @param qTables JPEG quantization tables
 195:    * @param DCHuffmanTables JPEG DC Huffman tables
 196:    * @param ACHuffmanTables JPEG AC Huffman tables
 197:    *
 198:    * @throws IllegalArgumentException if any argument is null, if any
 199:    * of the arrays are longer than four elements, or if the Huffman
 200:    * table arrays do not have the same number of elements
 201:    */
 202:   public void setEncodeTables(JPEGQTable[] qTables,
 203:                               JPEGHuffmanTable[] DCHuffmanTables,
 204:                               JPEGHuffmanTable[] ACHuffmanTables)
 205:   {
 206:     if (qTables == null || DCHuffmanTables == null || ACHuffmanTables == null)
 207:       throw new IllegalArgumentException("null argument");
 208: 
 209:     if (qTables.length > 4 || DCHuffmanTables.length > 4
 210:         || ACHuffmanTables.length > 4)
 211:       throw new IllegalArgumentException("argument has too many elements");
 212: 
 213:     if (DCHuffmanTables.length != ACHuffmanTables.length)
 214:       throw new IllegalArgumentException("Huffman table arrays differ in length");
 215: 
 216:     // Do a shallow copy.  JPEGQTable's data is not directly
 217:     // modifyable since JPEGQTable.getTable returns a copy.  Therefore
 218:     // it is safe to have multiple references to a single JPEGQTable.
 219:     // Likewise for JPEGHuffmanTable.
 220:     this.qTables = (JPEGQTable[]) qTables.clone();
 221:     this.DCHuffmanTables = (JPEGHuffmanTable[]) DCHuffmanTables.clone();
 222:     this.ACHuffmanTables = (JPEGHuffmanTable[]) ACHuffmanTables.clone();
 223:   }
 224: 
 225:   /**
 226:    * Clear the quantization and Huffman encoding tables.
 227:    */
 228:   public void unsetEncodeTables()
 229:   {
 230:     qTables = null;
 231:     DCHuffmanTables = null;
 232:     ACHuffmanTables = null;
 233:   }
 234: 
 235:   /**
 236:    * Retrieve the quantization tables.
 237:    *
 238:    * @returns an array of JPEG quantization tables
 239:    */
 240:   public JPEGQTable[] getQTables()
 241:   {
 242:     return qTables == null ? qTables : (JPEGQTable[]) qTables.clone();
 243:   }
 244: 
 245:   /**
 246:    * Retrieve the DC Huffman tables.
 247:    *
 248:    * @return an array of JPEG DC Huffman tables
 249:    */
 250:   public JPEGHuffmanTable[] getDCHuffmanTables()
 251:   {
 252:     return DCHuffmanTables == null ? DCHuffmanTables
 253:       : (JPEGHuffmanTable[]) DCHuffmanTables.clone();
 254:   }
 255: 
 256:   /**
 257:    * Retrieve the AC Huffman tables.
 258:    *
 259:    * @return an array of JPEG AC Huffman tables
 260:    */
 261:   public JPEGHuffmanTable[] getACHuffmanTables()
 262:   {
 263:     return ACHuffmanTables == null ? ACHuffmanTables
 264:       : (JPEGHuffmanTable[]) ACHuffmanTables.clone();
 265:   }
 266: 
 267:   /**
 268:    * Specify whether or not Huffman tables written to the output
 269:    * stream should be optimized.  Every image encoded with this flag
 270:    * set will contain a Huffman table, and the generated Huffman
 271:    * tables will override those specified in the metadata.
 272:    *
 273:    * @param optimize true to generate optimized Huffman tables, false
 274:    * otherwise
 275:    */
 276:   public void setOptimizeHuffmanTables(boolean optimize)
 277:   {
 278:     this.optimize = optimize;
 279:   }
 280: 
 281:   /**
 282:    * Check whether or not Huffman tables written to the output stream
 283:    * will be optimized.  Unless otherwise set using
 284:    * setOptimizeHuffmanTables, this returns false.
 285:    *
 286:    * @return true Huffman tables written to the output stream will be
 287:    * optimized, false otherwise
 288:    */
 289:   public boolean getOptimizeHuffmanTables()
 290:   {
 291:     return optimize;
 292:   }
 293: }