KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > imageio > plugins > jpeg > JPEGHuffmanTable


1 /*
2  * @(#)JPEGHuffmanTable.java 1.13 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 /**********************************************************************
9  **********************************************************************
10  **********************************************************************
11  *** COPYRIGHT (c) 1997-1998 Eastman Kodak Company. ***
12  *** As an unpublished work pursuant to Title 17 of the United ***
13  *** States Code. All rights reserved. ***
14  **********************************************************************
15  **********************************************************************
16  **********************************************************************/

17
18 package javax.imageio.plugins.jpeg;
19
20 /**
21  * A class encapsulating a single JPEG Huffman table. Fields are
22  * provided for the "standard" tables from taken from Annex K of the
23  * JPEG specification. These are the tables used as defaults.
24  * This class differs from the old unsupported
25  * com.sun.image.codec.jpeg.JPEGHuffmanTable in two ways:
26  * <ol>
27  * <li>The lengths arrays for this class do not contain an ignored 0th
28  * entry. The lengths array in a JPEG stream does not contain an extra
29  * entry, and this class is used to represent the contents of a JPEG
30  * stream.
31  * </li>
32  * <li>The old class incorrectly referred to Huffman "symbols", while
33  * expecting an array of values to be encoded. This class has a
34  * <code>getValues</code> method instead of a <code>getSymbols</code>
35  * method.
36  * </li>
37  * </ol>
38  *
39  * <p>
40  * For more information about the operation of the built-in JPEG plug-ins,
41  * see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
42  * metadata format specification and usage notes</A>.
43  *
44  * @version 0.5
45  */

46 public class JPEGHuffmanTable {
47
48     /**
49      * The maximum number of symbol lengths
50      * (max symbol length in bits = 16).
51      */

52     private static final int HUFF_MAX_LEN = 16;
53     
54     /** The maximum number of values. */
55     private static final int HUFF_MAX_VALS = 256;
56     
57     /** lengths[k-1] = number of symbols with length k bits. */
58     private short lengths[] = null;
59     
60     /** Values in order of increasing length of the corresponding symbols. */
61     private short values[] = null;
62     
63     /** The standard DC luminance Huffman table. */
64     public static final JPEGHuffmanTable JavaDoc StdDCLuminance =
65         new JPEGHuffmanTable JavaDoc();
66     static {
67         short lengths[] = {
68             0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
69         short values[] = {
70             0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
71         
72         StdDCLuminance.lengths = lengths;
73         StdDCLuminance.values = values;
74         StdDCLuminance.checkTable();
75     }
76     
77     
78     /** The standard DC chrominance Huffman table. */
79     public static final JPEGHuffmanTable JavaDoc StdDCChrominance =
80         new JPEGHuffmanTable JavaDoc();
81     static {
82         short lengths[] = {
83             0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
84         short values[] = {
85             0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
86         
87         StdDCChrominance.lengths = lengths;
88         StdDCChrominance.values = values;
89         StdDCChrominance.checkTable();
90     }
91     
92     /** The standard AC luminance Huffman table. */
93     public static final JPEGHuffmanTable JavaDoc StdACLuminance =
94         new JPEGHuffmanTable JavaDoc();
95     static {
96         short lengths[] = {
97             0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
98         short values[] = {
99             0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
100             0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
101             0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
102             0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
103             0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
104             0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
105             0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
106             0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
107             0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
108             0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
109             0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
110             0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
111             0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
112             0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
113             0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
114             0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
115             0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
116             0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
117             0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
118             0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
119             0xf9, 0xfa };
120         
121         StdACLuminance.lengths = lengths;
122         StdACLuminance.values = values;
123         StdACLuminance.checkTable();
124     }
125     
126     /** The standard AC chrominance Huffman table. */
127     public static final JPEGHuffmanTable JavaDoc StdACChrominance =
128         new JPEGHuffmanTable JavaDoc();
129     static {
130         short lengths[] = {
131             0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
132         short values[] = {
133             0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
134             0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
135             0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
136             0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
137             0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
138             0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
139             0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
140             0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
141             0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
142             0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
143             0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
144             0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
145             0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
146             0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
147             0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
148             0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
149             0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
150             0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
151             0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
152             0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
153             0xf9, 0xfa };
154         
155         StdACChrominance.lengths = lengths;
156         StdACChrominance.values = values;
157         StdACChrominance.checkTable();
158     }
159     
160     /**
161      * Private constructor used to construct the Standard Huffman tables
162      */

163     private JPEGHuffmanTable() {}
164     
165     /**
166      * Creates a Huffman table and initializes it. The input arrays
167      * are copied. The arrays must describe a possible Huffman table.
168      * For example, 3 codes cannot be expressed with a single bit.
169      *
170      * @param lengths an array of <code>short</code>s where
171      * <code>lengths[k]</code> is equal to the number of values with
172      * corresponding codes of length <code>k + 1</code> bits.
173      * @param values an array of <code>short</code>s containing the
174      * values in order of increasing code length.
175      *
176      * @exception IllegalArgumentException if <code>lengths</code> or
177      * <code>values</code> are <code>null</code>, the length of
178      * <code>lengths</code> is greater than 16, the length of
179      * <code>values</code> is greater than 256, if any value in
180      * <code>lengths</code> or <code>values</code> is less than zero,
181      * or if the arrays do not describe a valid Huffman table.
182      */

183     public JPEGHuffmanTable(short[] lengths, short[] values) {
184         if (lengths == null) {
185             throw new IllegalArgumentException JavaDoc("lengths array is null!");
186         }
187         if (values == null) {
188             throw new IllegalArgumentException JavaDoc("values array is null!");
189         }
190         if (lengths.length > HUFF_MAX_LEN) {
191             throw new IllegalArgumentException JavaDoc("lengths array is too long!");
192         }
193         if (values.length > HUFF_MAX_VALS) {
194             throw new IllegalArgumentException JavaDoc("values array is too long");
195         }
196         for (int i = 1; i < lengths.length; i++) {
197             if (lengths[i] < 0) {
198                 throw new IllegalArgumentException JavaDoc
199                     ("Values in lengths array must be non-negative.");
200             }
201         }
202         for (int i = 0; i < values.length; i++) {
203             if (values[i] < 0) {
204                 throw new IllegalArgumentException JavaDoc
205                     ("Values in values array must be non-negative.");
206             }
207         }
208         
209         this.lengths = (short[])lengths.clone();
210         this.values = (short[])values.clone();
211
212         checkTable();
213     }
214     
215     /**
216      * This checks that the table they gave us isn't 'illegal' It
217      * checks that the symbol length counts are possible, and that
218      * they gave us at least enough values for the symbol length
219      * counts. Eventually this might check that there aren't duplicate
220      * values.
221      */

222     private void checkTable() {
223         int numVals = 2;
224         int sum = 0;
225
226         for (int i = 0; i < lengths.length; i++) {
227             sum += lengths[i];
228             numVals -= lengths[i];
229             numVals *= 2;
230         }
231         
232         if (numVals < 0) {
233             throw new IllegalArgumentException JavaDoc
234                 ("Invalid Huffman table provided, lengths are incorrect.");
235         }
236         
237         if (sum != values.length) {
238             throw new IllegalArgumentException JavaDoc
239                 ("Invalid Huffman table provided, sum of lengths != values.");
240         }
241     }
242     
243     /**
244      * Return an array of <code>short</code>s containing the number of
245      * values for each length in the Huffman table. The returned
246      * array is a copy.
247      *
248      * @return a <code>short</code> array where <code>array[k-1]</code>
249      * is equal to the number of values in the table of length
250      * <code>k</code>.
251      *
252      * @see #getValues
253      */

254     public short[] getLengths() {
255         return (short[])lengths.clone();
256     }
257     
258     /**
259      * Return an array of <code>short</code>s containing the
260      * values arranged by increasing length of their corresponding
261      * codes. The interpretation of
262      * the array is dependent on the values returned from
263      * <code>getLengths</code>. The returned array is a copy.
264      *
265      * @return a <code>short</code> array of values.
266      *
267      * @see #getLengths
268      */

269     public short[] getValues() {
270         return (short[])values.clone();
271     }
272
273     public String JavaDoc toString() {
274         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
275         sb.append("JPEGHuffmanTable:\nlengths:");
276         for (int i = 0; i< lengths.length; i++) {
277             sb.append(' ').append(lengths[i]);
278         }
279         sb.append("\nvalues:");
280         for (int i = 0; i< values.length; i++) {
281             sb.append(' ').append(values[i]);
282         }
283         return sb.toString();
284     }
285 }
286
Popular Tags