KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > image > codec > jpeg > JPEGHuffmanTable


1 /*
2  * @(#)JPEGHuffmanTable.java 1.10 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 com.sun.image.codec.jpeg;
19
20
21 /** A class to encapsulate a JPEG Huffman table.
22  * <p>
23  * Note that the classes in the com.sun.image.codec.jpeg package are not
24  * part of the core Java APIs. They are a part of Sun's JDK and JRE
25  * distributions. Although other licensees may choose to distribute these
26  * classes, developers cannot depend on their availability in non-Sun
27  * implementations. We expect that equivalent functionality will eventually
28  * be available in a core API or standard extension.
29  * <p>
30  */

31 public class JPEGHuffmanTable {
32
33     /**
34      * The maximum number of symbol lengths
35      * (max symbol length in bits = 16)
36      */

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

149     private JPEGHuffmanTable() {
150         lengths = null;
151         symbols = null;
152     }
153
154     /**
155      * Creates a Huffman Table and initializes it.
156      * @param lengths lengths[k] = # of symbols with codes of length k
157      * bits; lengths[0] is ignored
158      * @param symbols symbols in order of increasing code length
159      * @exception IllegalArgumentException if the length of
160      * <code>lengths</code> is greater than 17
161      * @exception IllegalArgumentException if the length of
162      * <code>symbols</code> is greater than 256
163      * @exception IllegalArgumentException if any of the values in
164      * <code>lengths</code> or <code>symbols</code> is less than zero
165      */

166     public JPEGHuffmanTable( short lengths[], short symbols[] ) {
167         if ( lengths.length > HUFF_MAX_LEN )
168             throw new IllegalArgumentException JavaDoc( "lengths array is too long" );
169         for (int i=1; i < lengths.length; i++)
170             if (lengths[i] < 0)
171                 throw new IllegalArgumentException JavaDoc
172                     ( "Values in lengths array must be non-negative." );
173
174         
175         if ( symbols.length > HUFF_MAX_SYM )
176             throw new IllegalArgumentException JavaDoc( "symbols array is too long" );
177         for (int i=0; i < symbols.length; i++)
178             if (symbols[i] < 0)
179                 throw new IllegalArgumentException JavaDoc
180                     ( "Values in symbols array must be non-negative." );
181         
182         this.lengths = new short[lengths.length];
183         this.symbols = new short[symbols.length];
184         
185         System.arraycopy( lengths, 0, this.lengths, 0, lengths.length );
186         System.arraycopy( symbols, 0, this.symbols, 0, symbols.length );
187
188         checkTable();
189     }
190
191     /**
192      * This checks that the table they gave us isn't 'illegal' It
193      * checks that the symbol length counts are possible, and that
194      * they gave us at least enough symbols for the symbol length
195      * counts. Eventually this might check that there aren't duplicate
196      * symbols.
197      */

198     private void checkTable() {
199         int numVals=2;
200         int sum=0;
201         for (int i=1; i<lengths.length; i++) {
202             sum += lengths[i];
203             numVals -= lengths[i];
204             numVals *= 2;
205         }
206
207         //System.out.println("NumVals: " + numVals);
208
//System.out.println("Sum: " + sum + " Symbols: " + symbols.length);
209

210         if (numVals < 0)
211             throw new IllegalArgumentException JavaDoc
212                 ("Invalid Huffman Table provided, lengths are incorrect.");
213
214         // I'll let them go if they gave us 'extra' symbols...
215
if (sum > symbols.length)
216             throw new IllegalArgumentException JavaDoc
217                 ("Invalid Huffman Table provided, not enough symbols.");
218     }
219
220     /**
221      * Return a copy of the array containing the number of symbols
222      * for each length in the Huffman table.
223      * @return A short array where array[k] = # of symbols in the
224      * table of length k. array[0] is unused
225      */

226     public short[] getLengths() {
227         short[] ret = new short[ lengths.length];
228         System.arraycopy( lengths, 0, ret, 0, lengths.length);
229         return ret;
230     }
231
232     /**
233      * Return an array containing the Huffman symbols arranged by
234      * increasing length. To make use of this array you must refer
235      * the the lengths array.
236      * @return A short array of Huffman symbols
237      */

238     public short[] getSymbols() {
239         short[] ret = new short[symbols.length];
240         System.arraycopy( symbols, 0, ret, 0, symbols.length);
241         return ret;
242     }
243 }
244
Popular Tags