Source for javax.imageio.plugins.jpeg.JPEGQTable

   1: /* JPEGQTable.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: /**
  42:  * The JPEGQTable class represents a quantization table that can be
  43:  * used to encode or decode a JPEG stream.  The standard JPEG
  44:  * luminance and chrominance quantization tables are provided as
  45:  * static fields.  Table entries are stored in natural order, not
  46:  * zig-zag order.
  47:  */
  48: public class JPEGQTable
  49: {
  50:   /**
  51:    * The table entries, stored in natural order.
  52:    */
  53:   private int[] table;
  54: 
  55:   /**
  56:    * The standard JPEG luminance quantization table.  Values are
  57:    * stored in natural order.
  58:    */
  59:   public static final JPEGQTable K1Luminance = new JPEGQTable(new int[]
  60:       {
  61:         16, 11, 10, 16,  24,  40,  51,  61,
  62:         12, 12, 14, 19,  26,  58,  60,  55,
  63:         14, 13, 16, 24,  40,  57,  69,  56,
  64:         14, 17, 22, 29,  51,  87,  80,  62,
  65:         18, 22, 37, 56,  68, 109, 103,  77,
  66:         24, 35, 55, 64,  81, 104, 113,  92,
  67:         49, 64, 78, 87, 103, 121, 120, 101,
  68:         72, 92, 95, 98, 112, 100, 103,  99
  69:       }, false);
  70: 
  71:   /**
  72:    * The standard JPEG luminance quantization table, scaled by
  73:    * one-half.  Values are stored in natural order.
  74:    */
  75:   public static final JPEGQTable K1Div2Luminance =
  76:     K1Luminance.getScaledInstance(0.5f, true);
  77: 
  78:   /**
  79:    * The standard JPEG chrominance quantization table.  Values are
  80:    * stored in natural order.
  81:    */
  82:   public static final JPEGQTable K2Chrominance = new JPEGQTable(new int[]
  83:       {
  84:         17, 18, 24, 47, 99, 99, 99, 99,
  85:         18, 21, 26, 66, 99, 99, 99, 99,
  86:         24, 26, 56, 99, 99, 99, 99, 99,
  87:         47, 66, 99, 99, 99, 99, 99, 99,
  88:         99, 99, 99, 99, 99, 99, 99, 99,
  89:         99, 99, 99, 99, 99, 99, 99, 99,
  90:         99, 99, 99, 99, 99, 99, 99, 99,
  91:         99, 99, 99, 99, 99, 99, 99, 99
  92:       }, false);
  93: 
  94:   /**
  95:    * The standard JPEG chrominance quantization table, scaled by
  96:    * one-half.  Values are stored in natural order.
  97:    */
  98:   public static final JPEGQTable K2Div2Chrominance =
  99:     K2Chrominance.getScaledInstance(0.5f, true);
 100: 
 101:   /**
 102:    * Construct a new JPEG quantization table.  A copy is created of
 103:    * the table argument.
 104:    *
 105:    * @param table the 64-element value table, stored in natural order
 106:    *
 107:    * @throws IllegalArgumentException if the table is null or if
 108:    * table's length is not equal to 64.
 109:    */
 110:   public JPEGQTable(int[] table)
 111:   {
 112:     this(checkTable(table), true);
 113:   }
 114: 
 115:   /**
 116:    * Private constructor that avoids unnecessary copying and argument
 117:    * checking.
 118:    *
 119:    * @param table the 64-element value table, stored in natural order
 120:    * @param copy true if a copy should be created of the given table
 121:    */
 122:   private JPEGQTable(int[] table, boolean copy)
 123:   {
 124:     this.table = copy ? (int[]) table.clone() : table;
 125:   }
 126: 
 127:   private static int[] checkTable(int[] table)
 128:   {
 129:     if (table == null || table.length != 64)
 130:       throw new IllegalArgumentException("invalid JPEG quantization table");
 131: 
 132:     return table;
 133:   }
 134: 
 135:   /**
 136:    * Retrieve a copy of the quantization values for this table.
 137:    *
 138:    * @return a copy of the quantization value array
 139:    */
 140:   public int[] getTable()
 141:   {
 142:     return (int[]) table.clone();
 143:   }
 144: 
 145:   /**
 146:    * Retrieve a copy of this JPEG quantization table with every value
 147:    * scaled by the given scale factor, and clamped from 1 to 255
 148:    * baseline or from 1 to 32767 otherwise.
 149:    *
 150:    * @param scaleFactor the factor by which to scale this table
 151:    * @param forceBaseline clamp scaled values to a maximum of 255 if
 152:    * true, 32767 if false
 153:    *
 154:    * @return a new scaled JPEG quantization table
 155:    */
 156:   public JPEGQTable getScaledInstance(float scaleFactor,
 157:                                       boolean forceBaseline)
 158:   {
 159:     int[] scaledTable = getTable();
 160:     int max = forceBaseline ? 255 : 32767;
 161: 
 162:     for (int i = 0; i < scaledTable.length; i++)
 163:       {
 164:         scaledTable[i] = Math.round (scaleFactor * (float) scaledTable[i]);
 165:         if (scaledTable[i] < 1)
 166:           scaledTable[i] = 1;
 167:         else if (scaledTable[i] > max)
 168:           scaledTable[i] = max;
 169:       }
 170: 
 171:     // Do not copy scaledTable.  It is already a copy because we used
 172:     // getTable to retrieve it.
 173:     return new JPEGQTable(scaledTable, false);
 174:   }
 175: 
 176:   /**
 177:    * Create a string representing this JPEG quantization table.
 178:    */
 179:   public String toString()
 180:   {
 181:     StringBuffer buffer = new StringBuffer();
 182: 
 183:     buffer.append("JPEGQTable:\n");
 184:     for (int i = 0; i < 8; i++)
 185:       {
 186:         buffer.append("        ");
 187:         for (int j = 0; j < 8; j++)
 188:           {
 189:             buffer.append(table[i * 8 + j] + " ");
 190:           }
 191:         buffer.append("\n");
 192:       }
 193: 
 194:     return buffer.toString();
 195:   }
 196: }