140 */ 141 public static final JPEGHuffmanTable 142 StdACLuminance = new JPEGHuffmanTable(StdACLuminanceLengths, 143 StdACLuminanceValues, false); 144 145 /** 146 * The standard AC chrominance Huffman table. 147 */ 148 public static final JPEGHuffmanTable 149 StdACChrominance = new JPEGHuffmanTable(StdACChrominanceLengths, 150 StdACChrominanceValues, false); 151 152 private short[] lengths; 153 private short[] values; 154 155 /** 156 * Creates a Huffman table and initializes it. The input arrays are copied. 157 * The arrays must describe a possible Huffman table. 158 * For example, 3 codes cannot be expressed with a single bit. 159 * 160 * @param lengths an array of {@code short}s where <code>lengths[k]</code> 161 * is equal to the number of values with corresponding codes of 162 * length <code>k + 1</code> bits. 163 * @param values an array of shorts containing the values in 164 * order of increasing code length. 165 * @throws IllegalArgumentException if <code>lengths</code> or 166 * <code>values</code> are null, the length of <code>lengths</code> is 167 * greater than 16, the length of <code>values</code> is greater than 256, 168 * if any value in <code>lengths</code> or <code>values</code> is less 169 * than zero, or if the arrays do not describe a valid Huffman table. 170 */ 171 public JPEGHuffmanTable(short[] lengths, short[] values) { 172 if (lengths == null || values == null || 173 lengths.length == 0 || values.length == 0 || 174 lengths.length > 16 || values.length > 256) { 175 throw new IllegalArgumentException("Illegal lengths or values"); 176 } 177 for (int i = 0; i<lengths.length; i++) { 178 if (lengths[i] < 0) { 179 throw new IllegalArgumentException("lengths["+i+"] < 0"); 180 } 181 } 182 for (int i = 0; i<values.length; i++) { 183 if (values[i] < 0) { 184 throw new IllegalArgumentException("values["+i+"] < 0"); 185 } 186 } 187 this.lengths = Arrays.copyOf(lengths, lengths.length); 188 this.values = Arrays.copyOf(values, values.length); 195 sumOfLengths += lengths[i]; 196 } 197 if (sumOfLengths != values.length) { 198 throw new IllegalArgumentException("lengths do not correspond " + 199 "to length of value table"); 200 } 201 } 202 203 /* Internal version which avoids the overhead of copying and checking */ 204 private JPEGHuffmanTable(short[] lengths, short[] values, boolean copy) { 205 if (copy) { 206 this.lengths = Arrays.copyOf(lengths, lengths.length); 207 this.values = Arrays.copyOf(values, values.length); 208 } else { 209 this.lengths = lengths; 210 this.values = values; 211 } 212 } 213 214 /** 215 * Returns an array of <code>short</code>s containing the number of values 216 * for each length in the Huffman table. The returned array is a copy. 217 * 218 * @return a <code>short</code> array where <code>array[k-1]</code> 219 * is equal to the number of values in the table of length <code>k</code>. 220 * @see #getValues 221 */ 222 public short[] getLengths() { 223 return Arrays.copyOf(lengths, lengths.length); 224 } 225 226 /** 227 * Returns an array of <code>short</code>s containing the values arranged 228 * by increasing length of their corresponding codes. 229 * The interpretation of the array is dependent on the values returned 230 * from <code>getLengths</code>. The returned array is a copy. 231 * 232 * @return a <code>short</code> array of values. 233 * @see #getLengths 234 */ 235 public short[] getValues() { 236 return Arrays.copyOf(values, values.length); 237 } 238 239 /** 240 * Returns a {@code String} representing this Huffman table. 241 * @return a {@code String} representing this Huffman table. 242 */ 243 public String toString() { 244 String ls = System.getProperty("line.separator", "\n"); 245 StringBuilder sb = new StringBuilder("JPEGHuffmanTable"); 246 sb.append(ls).append("lengths:"); 247 for (int i=0; i<lengths.length; i++) { 248 sb.append(" ").append(lengths[i]); 249 } 250 sb.append(ls).append("values:"); 251 for (int i=0; i<values.length; i++) { 252 sb.append(" ").append(values[i]); | 140 */ 141 public static final JPEGHuffmanTable 142 StdACLuminance = new JPEGHuffmanTable(StdACLuminanceLengths, 143 StdACLuminanceValues, false); 144 145 /** 146 * The standard AC chrominance Huffman table. 147 */ 148 public static final JPEGHuffmanTable 149 StdACChrominance = new JPEGHuffmanTable(StdACChrominanceLengths, 150 StdACChrominanceValues, false); 151 152 private short[] lengths; 153 private short[] values; 154 155 /** 156 * Creates a Huffman table and initializes it. The input arrays are copied. 157 * The arrays must describe a possible Huffman table. 158 * For example, 3 codes cannot be expressed with a single bit. 159 * 160 * @param lengths an array of {@code short}s where {@code lengths[k]} 161 * is equal to the number of values with corresponding codes of 162 * length {@code k + 1} bits. 163 * @param values an array of shorts containing the values in 164 * order of increasing code length. 165 * @throws IllegalArgumentException if {@code lengths} or 166 * {@code values} are null, the length of {@code lengths} is 167 * greater than 16, the length of {@code values} is greater than 256, 168 * if any value in {@code lengths} or {@code values} is less 169 * than zero, or if the arrays do not describe a valid Huffman table. 170 */ 171 public JPEGHuffmanTable(short[] lengths, short[] values) { 172 if (lengths == null || values == null || 173 lengths.length == 0 || values.length == 0 || 174 lengths.length > 16 || values.length > 256) { 175 throw new IllegalArgumentException("Illegal lengths or values"); 176 } 177 for (int i = 0; i<lengths.length; i++) { 178 if (lengths[i] < 0) { 179 throw new IllegalArgumentException("lengths["+i+"] < 0"); 180 } 181 } 182 for (int i = 0; i<values.length; i++) { 183 if (values[i] < 0) { 184 throw new IllegalArgumentException("values["+i+"] < 0"); 185 } 186 } 187 this.lengths = Arrays.copyOf(lengths, lengths.length); 188 this.values = Arrays.copyOf(values, values.length); 195 sumOfLengths += lengths[i]; 196 } 197 if (sumOfLengths != values.length) { 198 throw new IllegalArgumentException("lengths do not correspond " + 199 "to length of value table"); 200 } 201 } 202 203 /* Internal version which avoids the overhead of copying and checking */ 204 private JPEGHuffmanTable(short[] lengths, short[] values, boolean copy) { 205 if (copy) { 206 this.lengths = Arrays.copyOf(lengths, lengths.length); 207 this.values = Arrays.copyOf(values, values.length); 208 } else { 209 this.lengths = lengths; 210 this.values = values; 211 } 212 } 213 214 /** 215 * Returns an array of {@code short}s containing the number of values 216 * for each length in the Huffman table. The returned array is a copy. 217 * 218 * @return a {@code short} array where {@code array[k-1]} 219 * is equal to the number of values in the table of length {@code k}. 220 * @see #getValues 221 */ 222 public short[] getLengths() { 223 return Arrays.copyOf(lengths, lengths.length); 224 } 225 226 /** 227 * Returns an array of {@code short}s containing the values arranged 228 * by increasing length of their corresponding codes. 229 * The interpretation of the array is dependent on the values returned 230 * from {@code getLengths}. The returned array is a copy. 231 * 232 * @return a {@code short} array of values. 233 * @see #getLengths 234 */ 235 public short[] getValues() { 236 return Arrays.copyOf(values, values.length); 237 } 238 239 /** 240 * Returns a {@code String} representing this Huffman table. 241 * @return a {@code String} representing this Huffman table. 242 */ 243 public String toString() { 244 String ls = System.getProperty("line.separator", "\n"); 245 StringBuilder sb = new StringBuilder("JPEGHuffmanTable"); 246 sb.append(ls).append("lengths:"); 247 for (int i=0; i<lengths.length; i++) { 248 sb.append(" ").append(lengths[i]); 249 } 250 sb.append(ls).append("values:"); 251 for (int i=0; i<values.length; i++) { 252 sb.append(" ").append(values[i]); |