1 /* 2 * Copyright (c) 2007, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.imageio.plugins.jpeg; 27 28 import java.util.Arrays; 29 30 /** 31 * A class encapsulating a single JPEG quantization table. 32 * The elements appear in natural order (as opposed to zig-zag order). 33 * Static variables are provided for the "standard" tables taken from 34 * Annex K of the JPEG specification, as well as the default tables 35 * conventionally used for visually lossless encoding. 36 * <p> 37 * For more information about the operation of the standard JPEG plug-in, 38 * see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG 39 * metadata format specification and usage notes</A> 40 */ 41 42 public class JPEGQTable { 43 44 private static final int[] k1 = { 45 16, 11, 10, 16, 24, 40, 51, 61, 46 12, 12, 14, 19, 26, 58, 60, 55, 47 14, 13, 16, 24, 40, 57, 69, 56, 48 14, 17, 22, 29, 51, 87, 80, 62, 49 18, 22, 37, 56, 68, 109, 103, 77, 50 24, 35, 55, 64, 81, 104, 113, 92, 51 49, 64, 78, 87, 103, 121, 120, 101, 52 72, 92, 95, 98, 112, 100, 103, 99, 53 }; 54 55 private static final int[] k1div2 = { 56 8, 6, 5, 8, 12, 20, 26, 31, 57 6, 6, 7, 10, 13, 29, 30, 28, 58 7, 7, 8, 12, 20, 29, 35, 28, 59 7, 9, 11, 15, 26, 44, 40, 31, 60 9, 11, 19, 28, 34, 55, 52, 39, 61 12, 18, 28, 32, 41, 52, 57, 46, 62 25, 32, 39, 44, 52, 61, 60, 51, 63 36, 46, 48, 49, 56, 50, 52, 50, 64 }; 65 66 private static final int[] k2 = { 67 17, 18, 24, 47, 99, 99, 99, 99, 68 18, 21, 26, 66, 99, 99, 99, 99, 69 24, 26, 56, 99, 99, 99, 99, 99, 70 47, 66, 99, 99, 99, 99, 99, 99, 71 99, 99, 99, 99, 99, 99, 99, 99, 72 99, 99, 99, 99, 99, 99, 99, 99, 73 99, 99, 99, 99, 99, 99, 99, 99, 74 99, 99, 99, 99, 99, 99, 99, 99, 75 }; 76 77 private static final int[] k2div2 = { 78 9, 9, 12, 24, 50, 50, 50, 50, 79 9, 11, 13, 33, 50, 50, 50, 50, 80 12, 13, 28, 50, 50, 50, 50, 50, 81 24, 33, 50, 50, 50, 50, 50, 50, 82 50, 50, 50, 50, 50, 50, 50, 50, 83 50, 50, 50, 50, 50, 50, 50, 50, 84 50, 50, 50, 50, 50, 50, 50, 50, 85 50, 50, 50, 50, 50, 50, 50, 50, 86 }; 87 88 /** 89 * The sample luminance quantization table given in the JPEG 90 * specification, table K.1. According to the specification, 91 * these values produce "good" quality output. 92 * @see #K1Div2Luminance 93 */ 94 public static final JPEGQTable 95 K1Luminance = new JPEGQTable(k1, false); 96 97 /** 98 * The sample luminance quantization table given in the JPEG 99 * specification, table K.1, with all elements divided by 2. 100 * According to the specification, these values produce "very good" 101 * quality output. This is the table usually used for "visually lossless" 102 * encoding, and is the default luminance table used if the default 103 * tables and quality settings are used. 104 * @see #K1Luminance 105 */ 106 public static final JPEGQTable 107 K1Div2Luminance = new JPEGQTable(k1div2, false); 108 109 /** 110 * The sample chrominance quantization table given in the JPEG 111 * specification, table K.2. According to the specification, 112 * these values produce "good" quality output. 113 * @see #K2Div2Chrominance 114 */ 115 public static final JPEGQTable K2Chrominance = 116 new JPEGQTable(k2, false); 117 118 /** 119 * The sample chrominance quantization table given in the JPEG 120 * specification, table K.1, with all elements divided by 2. 121 * According to the specification, these values produce "very good" 122 * quality output. This is the table usually used for "visually lossless" 123 * encoding, and is the default chrominance table used if the default 124 * tables and quality settings are used. 125 * @see #K2Chrominance 126 */ 127 public static final JPEGQTable K2Div2Chrominance = 128 new JPEGQTable(k2div2, false); 129 130 private int[] qTable; 131 JPEGQTable(int[] table, boolean copy)132 private JPEGQTable(int[] table, boolean copy) { 133 qTable = (copy) ? Arrays.copyOf(table, table.length) : table; 134 } 135 136 /** 137 * Constructs a quantization table from the argument, which must 138 * contain 64 elements in natural order (not zig-zag order). 139 * A copy is made of the the input array. 140 * @param table the quantization table, as an <code>int</code> array. 141 * @throws IllegalArgumentException if <code>table</code> is 142 * <code>null</code> or <code>table.length</code> is not equal to 64. 143 */ JPEGQTable(int[] table)144 public JPEGQTable(int[] table) { 145 if (table == null) { 146 throw new IllegalArgumentException("table must not be null."); 147 } 148 if (table.length != 64) { 149 throw new IllegalArgumentException("table.length != 64"); 150 } 151 qTable = Arrays.copyOf(table, table.length); 152 } 153 154 /** 155 * Returns a copy of the current quantization table as an array 156 * of {@code int}s in natural (not zig-zag) order. 157 * @return A copy of the current quantization table. 158 */ getTable()159 public int[] getTable() { 160 return Arrays.copyOf(qTable, qTable.length); 161 } 162 163 /** 164 * Returns a new quantization table where the values are multiplied 165 * by <code>scaleFactor</code> and then clamped to the range 1..32767 166 * (or to 1..255 if <code>forceBaseline</code> is true). 167 * <p> 168 * Values of <code>scaleFactor</code> less than 1 tend to improve 169 * the quality level of the table, and values greater than 1.0 170 * degrade the quality level of the table. 171 * @param scaleFactor multiplication factor for the table. 172 * @param forceBaseline if <code>true</code>, 173 * the values will be clamped to the range 1..255 174 * @return a new quantization table that is a linear multiple 175 * of the current table. 176 */ getScaledInstance(float scaleFactor, boolean forceBaseline)177 public JPEGQTable getScaledInstance(float scaleFactor, 178 boolean forceBaseline) { 179 int max = (forceBaseline) ? 255 : 32767; 180 int[] scaledTable = new int[qTable.length]; 181 for (int i=0; i<qTable.length; i++) { 182 int sv = (int)((qTable[i] * scaleFactor)+0.5f); 183 if (sv < 1) { 184 sv = 1; 185 } 186 if (sv > max) { 187 sv = max; 188 } 189 scaledTable[i] = sv; 190 } 191 return new JPEGQTable(scaledTable); 192 } 193 194 /** 195 * Returns a {@code String} representing this quantization table. 196 * @return a {@code String} representing this quantization table. 197 */ toString()198 public String toString() { 199 String ls = System.getProperty("line.separator", "\n"); 200 StringBuilder sb = new StringBuilder("JPEGQTable:"+ls); 201 for (int i=0; i < qTable.length; i++) { 202 if (i % 8 == 0) { 203 sb.append('\t'); 204 } 205 sb.append(qTable[i]); 206 sb.append(((i % 8) == 7) ? ls : ' '); 207 } 208 return sb.toString(); 209 } 210 } 211