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    }