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