001 /* JPEGHuffmanTable.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 import gnu.java.lang.CPStringBuilder;
042
043 /**
044 * The JPEGHuffmanTable class represents a Huffman table read from a
045 * JPEG image file. The standard JPEG AC and DC chrominance and
046 * luminance values are provided as static fields.
047 */
048 public class JPEGHuffmanTable
049 {
050 /**
051 * Huffman code lengths.
052 */
053 private short[] lengths;
054
055 /**
056 * Huffman values.
057 */
058 private short[] values;
059
060 // The private constructors are used for these final fields to avoid
061 // unnecessary copying.
062 /**
063 * The standard JPEG AC chrominance Huffman table.
064 */
065 public static final JPEGHuffmanTable StdACChrominance =
066 new JPEGHuffmanTable(new short[] { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5,
067 4, 4, 0, 1, 2, 0x77 },
068 new short[] { 0x00, 0x01, 0x02, 0x03, 0x11,
069 0x04, 0x05, 0x21, 0x31, 0x06,
070 0x12, 0x41, 0x51, 0x07, 0x61,
071 0x71, 0x13, 0x22, 0x32, 0x81,
072 0x08, 0x14, 0x42, 0x91, 0xa1,
073 0xb1, 0xc1, 0x09, 0x23, 0x33,
074 0x52, 0xf0, 0x15, 0x62, 0x72,
075 0xd1, 0x0a, 0x16, 0x24, 0x34,
076 0xe1, 0x25, 0xf1, 0x17, 0x18,
077 0x19, 0x1a, 0x26, 0x27, 0x28,
078 0x29, 0x2a, 0x35, 0x36, 0x37,
079 0x38, 0x39, 0x3a, 0x43, 0x44,
080 0x45, 0x46, 0x47, 0x48, 0x49,
081 0x4a, 0x53, 0x54, 0x55, 0x56,
082 0x57, 0x58, 0x59, 0x5a, 0x63,
083 0x64, 0x65, 0x66, 0x67, 0x68,
084 0x69, 0x6a, 0x73, 0x74, 0x75,
085 0x76, 0x77, 0x78, 0x79, 0x7a,
086 0x82, 0x83, 0x84, 0x85, 0x86,
087 0x87, 0x88, 0x89, 0x8a, 0x92,
088 0x93, 0x94, 0x95, 0x96, 0x97,
089 0x98, 0x99, 0x9a, 0xa2, 0xa3,
090 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
091 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
092 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
093 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
094 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
095 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
096 0xd7, 0xd8, 0xd9, 0xda, 0xe2,
097 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
098 0xe8, 0xe9, 0xea, 0xf2, 0xf3,
099 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
100 0xf9, 0xfa }, false);
101
102 /**
103 * The standard JPEG AC luminance Huffman table.
104 */
105 public static final JPEGHuffmanTable StdACLuminance =
106 new JPEGHuffmanTable(new short[] { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5,
107 4, 4, 0, 0, 1, 0x7d },
108 new short[] { 0x01, 0x02, 0x03, 0x00, 0x04,
109 0x11, 0x05, 0x12, 0x21, 0x31,
110 0x41, 0x06, 0x13, 0x51, 0x61,
111 0x07, 0x22, 0x71, 0x14, 0x32,
112 0x81, 0x91, 0xa1, 0x08, 0x23,
113 0x42, 0xb1, 0xc1, 0x15, 0x52,
114 0xd1, 0xf0, 0x24, 0x33, 0x62,
115 0x72, 0x82, 0x09, 0x0a, 0x16,
116 0x17, 0x18, 0x19, 0x1a, 0x25,
117 0x26, 0x27, 0x28, 0x29, 0x2a,
118 0x34, 0x35, 0x36, 0x37, 0x38,
119 0x39, 0x3a, 0x43, 0x44, 0x45,
120 0x46, 0x47, 0x48, 0x49, 0x4a,
121 0x53, 0x54, 0x55, 0x56, 0x57,
122 0x58, 0x59, 0x5a, 0x63, 0x64,
123 0x65, 0x66, 0x67, 0x68, 0x69,
124 0x6a, 0x73, 0x74, 0x75, 0x76,
125 0x77, 0x78, 0x79, 0x7a, 0x83,
126 0x84, 0x85, 0x86, 0x87, 0x88,
127 0x89, 0x8a, 0x92, 0x93, 0x94,
128 0x95, 0x96, 0x97, 0x98, 0x99,
129 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
130 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
131 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
132 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
133 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
134 0xc8, 0xc9, 0xca, 0xd2, 0xd3,
135 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
136 0xd9, 0xda, 0xe1, 0xe2, 0xe3,
137 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
138 0xe9, 0xea, 0xf1, 0xf2, 0xf3,
139 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
140 0xf9, 0xfa }, false);
141
142 /**
143 * The standard JPEG DC chrominance Huffman table.
144 */
145 public static final JPEGHuffmanTable StdDCChrominance =
146 new JPEGHuffmanTable(new short[] { 0, 3, 1, 1, 1, 1, 1, 1, 1, 1,
147 1, 0, 0, 0, 0, 0 },
148 new short[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
149 10, 11 }, false);
150
151 /**
152 * The standard JPEG DC luminance Huffman table.
153 */
154 public static final JPEGHuffmanTable StdDCLuminance =
155 new JPEGHuffmanTable(new short[] { 0, 1, 5, 1, 1, 1, 1, 1, 1, 0,
156 0, 0, 0, 0, 0, 0 },
157 new short[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
158 10, 11 }, false);
159
160 /**
161 * Construct and initialize a Huffman table. Copies are created of
162 * the array arguments. lengths[index] stores the number of Huffman
163 * values with Huffman codes of length index + 1. The values array
164 * stores the Huffman values in order of increasing code length.
165 *
166 * @param lengths an array of Huffman code lengths
167 * @param values a sorted array of Huffman values
168 * @throws IllegalArgumentException if either parameter is null, if
169 * lengths.length > 16 or values.length > 256, if any value in
170 * length or values is negative, or if the parameters do not
171 * describe a valid Huffman table
172 */
173 public JPEGHuffmanTable(short[] lengths, short[] values)
174 {
175 // Create copies of the lengths and values arguments.
176 this(checkLengths(lengths), checkValues(values, lengths), true);
177 }
178
179 /**
180 * Private constructor that avoids unnecessary copying and argument
181 * checking.
182 *
183 * @param lengths an array of Huffman code lengths
184 * @param values a sorted array of Huffman values
185 * @param copy true if copies should be created of the given arrays
186 */
187 private JPEGHuffmanTable(short[] lengths, short[] values, boolean copy)
188 {
189 this.lengths = copy ? (short[]) lengths.clone() : lengths;
190 this.values = copy ? (short[]) values.clone() : values;
191 }
192
193 private static short[] checkLengths(short[] lengths)
194 {
195 if (lengths == null || lengths.length > 16)
196 throw new IllegalArgumentException("invalid length array");
197
198 for (int i = 0; i < lengths.length; i++)
199 {
200 if (lengths[i] < 0)
201 throw new IllegalArgumentException("negative length");
202 }
203
204 int sum = 0;
205 for (int i = 0; i < lengths.length; i++)
206 {
207 if (lengths[i] > ((1 << (i + 1)) - 1))
208 throw new IllegalArgumentException("invalid number of codes"
209 + " for code length " + (i + 1));
210 sum += lengths[i];
211 }
212
213 return lengths;
214 }
215
216 private static short[] checkValues(short[] values, short[] lengths)
217 {
218 if (values == null || values.length > 256)
219 throw new IllegalArgumentException("invalid values array");
220
221 for (int i = 0; i < values.length; i++)
222 {
223 if (values[i] < 0)
224 throw new IllegalArgumentException("negative value");
225 }
226 // lengths is known-valid by this point.
227 int sum = 0;
228 for (int i = 0; i < lengths.length; i++)
229 sum += lengths[i];
230
231 if (values.length != sum)
232 throw new IllegalArgumentException("invalid number of values"
233 + " for number of codes");
234
235 return values;
236 }
237
238 /**
239 * Retrieve a copy of the array of Huffman code lengths. If the
240 * returned array is called lengthcount, there are
241 * lengthcount[index] codes of length index + 1.
242 *
243 * @return a copy of the array of Huffman code lengths
244 */
245 public short[] getLengths()
246 {
247 return (short[]) lengths.clone();
248 }
249
250 /**
251 * Retrieve a copy of the array of Huffman values, sorted in order
252 * of increasing code length.
253 *
254 * @return a copy of the array of Huffman values
255 */
256 public short[] getValues()
257 {
258 return (short[]) values.clone();
259 }
260
261 /**
262 * Create a string representation of this JPEG Huffman table.
263 *
264 * @return a string representation of this JPEG Huffman table.
265 */
266 public String toString()
267 {
268 CPStringBuilder buffer = new CPStringBuilder();
269
270 buffer.append("JPEGHuffmanTable:\nlengths:");
271
272 for (int i = 0; i < lengths.length; i++)
273 buffer.append(" " + lengths[i]);
274
275 buffer.append("\nvalues:");
276
277 for (int i = 0; i < values.length; i++)
278 buffer.append(" " + values[i]);
279
280 return buffer.toString();
281 }
282 }