001 /* JPEGQTable.java -- 002 Copyright (C) 2006 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package javax.imageio.plugins.jpeg; 040 041 /** 042 * The JPEGQTable class represents a quantization table that can be 043 * used to encode or decode a JPEG stream. The standard JPEG 044 * luminance and chrominance quantization tables are provided as 045 * static fields. Table entries are stored in natural order, not 046 * zig-zag order. 047 */ 048 public class JPEGQTable 049 { 050 /** 051 * The table entries, stored in natural order. 052 */ 053 private int[] table; 054 055 /** 056 * The standard JPEG luminance quantization table. Values are 057 * stored in natural order. 058 */ 059 public static final JPEGQTable K1Luminance = new JPEGQTable(new int[] 060 { 061 16, 11, 10, 16, 24, 40, 51, 61, 062 12, 12, 14, 19, 26, 58, 60, 55, 063 14, 13, 16, 24, 40, 57, 69, 56, 064 14, 17, 22, 29, 51, 87, 80, 62, 065 18, 22, 37, 56, 68, 109, 103, 77, 066 24, 35, 55, 64, 81, 104, 113, 92, 067 49, 64, 78, 87, 103, 121, 120, 101, 068 72, 92, 95, 98, 112, 100, 103, 99 069 }, false); 070 071 /** 072 * The standard JPEG luminance quantization table, scaled by 073 * one-half. Values are stored in natural order. 074 */ 075 public static final JPEGQTable K1Div2Luminance = 076 K1Luminance.getScaledInstance(0.5f, true); 077 078 /** 079 * The standard JPEG chrominance quantization table. Values are 080 * stored in natural order. 081 */ 082 public static final JPEGQTable K2Chrominance = new JPEGQTable(new int[] 083 { 084 17, 18, 24, 47, 99, 99, 99, 99, 085 18, 21, 26, 66, 99, 99, 99, 99, 086 24, 26, 56, 99, 99, 99, 99, 99, 087 47, 66, 99, 99, 99, 99, 99, 99, 088 99, 99, 99, 99, 99, 99, 99, 99, 089 99, 99, 99, 99, 99, 99, 99, 99, 090 99, 99, 99, 99, 99, 99, 99, 99, 091 99, 99, 99, 99, 99, 99, 99, 99 092 }, false); 093 094 /** 095 * The standard JPEG chrominance quantization table, scaled by 096 * one-half. Values are stored in natural order. 097 */ 098 public static final JPEGQTable K2Div2Chrominance = 099 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 }