1 | /*
|
---|
2 | * Copyright 2002-2017 Drew Noakes
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | * More information about this project is available at:
|
---|
17 | *
|
---|
18 | * https://drewnoakes.com/code/exif/
|
---|
19 | * https://github.com/drewnoakes/metadata-extractor
|
---|
20 | */
|
---|
21 | package com.drew.metadata.jpeg;
|
---|
22 |
|
---|
23 | import java.util.ArrayList;
|
---|
24 | import java.util.Arrays;
|
---|
25 | import java.util.HashMap;
|
---|
26 | import java.util.List;
|
---|
27 | import com.drew.lang.annotations.NotNull;
|
---|
28 | import com.drew.metadata.Directory;
|
---|
29 | import com.drew.metadata.MetadataException;
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * Directory of tables for the DHT (Define Huffman Table(s)) segment.
|
---|
33 | *
|
---|
34 | * @author Nadahar
|
---|
35 | */
|
---|
36 | @SuppressWarnings("WeakerAccess")
|
---|
37 | public class HuffmanTablesDirectory extends Directory {
|
---|
38 |
|
---|
39 | public static final int TAG_NUMBER_OF_TABLES = 1;
|
---|
40 |
|
---|
41 | protected static final byte[] TYPICAL_LUMINANCE_DC_LENGTHS = {
|
---|
42 | (byte) 0x00, (byte) 0x01, (byte) 0x05, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01,
|
---|
43 | (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
|
---|
44 | };
|
---|
45 |
|
---|
46 | protected static final byte[] TYPICAL_LUMINANCE_DC_VALUES = {
|
---|
47 | (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
|
---|
48 | (byte) 0x08, (byte) 0x09, (byte) 0x0A, (byte) 0x0B
|
---|
49 | };
|
---|
50 |
|
---|
51 | protected static final byte[] TYPICAL_CHROMINANCE_DC_LENGTHS = {
|
---|
52 | (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01,
|
---|
53 | (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
|
---|
54 | };
|
---|
55 |
|
---|
56 | protected static final byte[] TYPICAL_CHROMINANCE_DC_VALUES = {
|
---|
57 | (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
|
---|
58 | (byte) 0x08, (byte) 0x09, (byte) 0x0A, (byte) 0x0B
|
---|
59 | };
|
---|
60 |
|
---|
61 | protected static final byte[] TYPICAL_LUMINANCE_AC_LENGTHS = {
|
---|
62 | (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x03,
|
---|
63 | (byte) 0x05, (byte) 0x05, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x7D
|
---|
64 | };
|
---|
65 |
|
---|
66 | protected static final byte[] TYPICAL_LUMINANCE_AC_VALUES = {
|
---|
67 | (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x04, (byte) 0x11, (byte) 0x05, (byte) 0x12,
|
---|
68 | (byte) 0x21, (byte) 0x31, (byte) 0x41, (byte) 0x06, (byte) 0x13, (byte) 0x51, (byte) 0x61, (byte) 0x07,
|
---|
69 | (byte) 0x22, (byte) 0x71, (byte) 0x14, (byte) 0x32, (byte) 0x81, (byte) 0x91, (byte) 0xA1, (byte) 0x08,
|
---|
70 | (byte) 0x23, (byte) 0x42, (byte) 0xB1, (byte) 0xC1, (byte) 0x15, (byte) 0x52, (byte) 0xD1, (byte) 0xF0,
|
---|
71 | (byte) 0x24, (byte) 0x33, (byte) 0x62, (byte) 0x72, (byte) 0x82, (byte) 0x09, (byte) 0x0A, (byte) 0x16,
|
---|
72 | (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1A, (byte) 0x25, (byte) 0x26, (byte) 0x27, (byte) 0x28,
|
---|
73 | (byte) 0x29, (byte) 0x2A, (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39,
|
---|
74 | (byte) 0x3A, (byte) 0x43, (byte) 0x44, (byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49,
|
---|
75 | (byte) 0x4A, (byte) 0x53, (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59,
|
---|
76 | (byte) 0x5A, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68, (byte) 0x69,
|
---|
77 | (byte) 0x6A, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78, (byte) 0x79,
|
---|
78 | (byte) 0x7A, (byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89,
|
---|
79 | (byte) 0x8A, (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98,
|
---|
80 | (byte) 0x99, (byte) 0x9A, (byte) 0xA2, (byte) 0xA3, (byte) 0xA4, (byte) 0xA5, (byte) 0xA6, (byte) 0xA7,
|
---|
81 | (byte) 0xA8, (byte) 0xA9, (byte) 0xAA, (byte) 0xB2, (byte) 0xB3, (byte) 0xB4, (byte) 0xB5, (byte) 0xB6,
|
---|
82 | (byte) 0xB7, (byte) 0xB8, (byte) 0xB9, (byte) 0xBA, (byte) 0xC2, (byte) 0xC3, (byte) 0xC4, (byte) 0xC5,
|
---|
83 | (byte) 0xC6, (byte) 0xC7, (byte) 0xC8, (byte) 0xC9, (byte) 0xCA, (byte) 0xD2, (byte) 0xD3, (byte) 0xD4,
|
---|
84 | (byte) 0xD5, (byte) 0xD6, (byte) 0xD7, (byte) 0xD8, (byte) 0xD9, (byte) 0xDA, (byte) 0xE1, (byte) 0xE2,
|
---|
85 | (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, (byte) 0xE8, (byte) 0xE9, (byte) 0xEA,
|
---|
86 | (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, (byte) 0xF8,
|
---|
87 | (byte) 0xF9, (byte) 0xFA
|
---|
88 | };
|
---|
89 |
|
---|
90 | protected static final byte[] TYPICAL_CHROMINANCE_AC_LENGTHS = {
|
---|
91 | (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x03, (byte) 0x04,
|
---|
92 | (byte) 0x07, (byte) 0x05, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x77
|
---|
93 | };
|
---|
94 |
|
---|
95 | protected static final byte[] TYPICAL_CHROMINANCE_AC_VALUES = {
|
---|
96 | (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x11, (byte) 0x04, (byte) 0x05, (byte) 0x21,
|
---|
97 | (byte) 0x31, (byte) 0x06, (byte) 0x12, (byte) 0x41, (byte) 0x51, (byte) 0x07, (byte) 0x61, (byte) 0x71,
|
---|
98 | (byte) 0x13, (byte) 0x22, (byte) 0x32, (byte) 0x81, (byte) 0x08, (byte) 0x14, (byte) 0x42, (byte) 0x91,
|
---|
99 | (byte) 0xA1, (byte) 0xB1, (byte) 0xC1, (byte) 0x09, (byte) 0x23, (byte) 0x33, (byte) 0x52, (byte) 0xF0,
|
---|
100 | (byte) 0x15, (byte) 0x62, (byte) 0x72, (byte) 0xD1, (byte) 0x0A, (byte) 0x16, (byte) 0x24, (byte) 0x34,
|
---|
101 | (byte) 0xE1, (byte) 0x25, (byte) 0xF1, (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1A, (byte) 0x26,
|
---|
102 | (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2A, (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38,
|
---|
103 | (byte) 0x39, (byte) 0x3A, (byte) 0x43, (byte) 0x44, (byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48,
|
---|
104 | (byte) 0x49, (byte) 0x4A, (byte) 0x53, (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58,
|
---|
105 | (byte) 0x59, (byte) 0x5A, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68,
|
---|
106 | (byte) 0x69, (byte) 0x6A, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78,
|
---|
107 | (byte) 0x79, (byte) 0x7A, (byte) 0x82, (byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87,
|
---|
108 | (byte) 0x88, (byte) 0x89, (byte) 0x8A, (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96,
|
---|
109 | (byte) 0x97, (byte) 0x98, (byte) 0x99, (byte) 0x9A, (byte) 0xA2, (byte) 0xA3, (byte) 0xA4, (byte) 0xA5,
|
---|
110 | (byte) 0xA6, (byte) 0xA7, (byte) 0xA8, (byte) 0xA9, (byte) 0xAA, (byte) 0xB2, (byte) 0xB3, (byte) 0xB4,
|
---|
111 | (byte) 0xB5, (byte) 0xB6, (byte) 0xB7, (byte) 0xB8, (byte) 0xB9, (byte) 0xBA, (byte) 0xC2, (byte) 0xC3,
|
---|
112 | (byte) 0xC4, (byte) 0xC5, (byte) 0xC6, (byte) 0xC7, (byte) 0xC8, (byte) 0xC9, (byte) 0xCA, (byte) 0xD2,
|
---|
113 | (byte) 0xD3, (byte) 0xD4, (byte) 0xD5, (byte) 0xD6, (byte) 0xD7, (byte) 0xD8, (byte) 0xD9, (byte) 0xDA,
|
---|
114 | (byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, (byte) 0xE8, (byte) 0xE9,
|
---|
115 | (byte) 0xEA, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, (byte) 0xF8,
|
---|
116 | (byte) 0xF9, (byte) 0xFA
|
---|
117 | };
|
---|
118 |
|
---|
119 | @NotNull
|
---|
120 | protected final List<HuffmanTable> tables = new ArrayList<HuffmanTable>(4);
|
---|
121 |
|
---|
122 | @NotNull
|
---|
123 | protected static final HashMap<Integer, String> _tagNameMap = new HashMap<Integer, String>();
|
---|
124 |
|
---|
125 | static
|
---|
126 | {
|
---|
127 | _tagNameMap.put(TAG_NUMBER_OF_TABLES, "Number of Tables");
|
---|
128 | }
|
---|
129 |
|
---|
130 | public HuffmanTablesDirectory()
|
---|
131 | {
|
---|
132 | this.setDescriptor(new HuffmanTablesDescriptor(this));
|
---|
133 | }
|
---|
134 |
|
---|
135 | @Override
|
---|
136 | @NotNull
|
---|
137 | public String getName()
|
---|
138 | {
|
---|
139 | return "Huffman";
|
---|
140 | }
|
---|
141 |
|
---|
142 | @Override
|
---|
143 | @NotNull
|
---|
144 | protected HashMap<Integer, String> getTagNameMap()
|
---|
145 | {
|
---|
146 | return _tagNameMap;
|
---|
147 | }
|
---|
148 |
|
---|
149 | /**
|
---|
150 | * @param tableNumber The zero-based index of the table. This number is normally between 0 and 3.
|
---|
151 | * Use {@link #getNumberOfTables} for bounds-checking.
|
---|
152 | * @return The {@link HuffmanTable} having the specified number.
|
---|
153 | */
|
---|
154 | @NotNull
|
---|
155 | public HuffmanTable getTable(int tableNumber)
|
---|
156 | {
|
---|
157 | return tables.get(tableNumber);
|
---|
158 | }
|
---|
159 |
|
---|
160 | /**
|
---|
161 | * @return The number of Huffman tables held by this {@link HuffmanTablesDirectory} instance.
|
---|
162 | */
|
---|
163 | public int getNumberOfTables() throws MetadataException
|
---|
164 | {
|
---|
165 | return getInt(HuffmanTablesDirectory.TAG_NUMBER_OF_TABLES);
|
---|
166 | }
|
---|
167 |
|
---|
168 | /**
|
---|
169 | * @return The {@link List} of {@link HuffmanTable}s in this
|
---|
170 | * {@link Directory}.
|
---|
171 | */
|
---|
172 | @NotNull
|
---|
173 | protected List<HuffmanTable> getTables() {
|
---|
174 | return tables;
|
---|
175 | }
|
---|
176 |
|
---|
177 | /**
|
---|
178 | * Evaluates whether all the tables in this {@link HuffmanTablesDirectory}
|
---|
179 | * are "typical" Huffman tables.
|
---|
180 | * <p>
|
---|
181 | * "Typical" has a special meaning in this context as the JPEG standard
|
---|
182 | * (ISO/IEC 10918 or ITU-T T.81) defines 4 Huffman tables that has been
|
---|
183 | * developed from the average statistics of a large set of images with 8-bit
|
---|
184 | * precision. Using these instead of calculating the optimal Huffman tables
|
---|
185 | * for a given image is faster, and is preferred by many hardware encoders
|
---|
186 | * and some hardware decoders.
|
---|
187 | * <p>
|
---|
188 | * Even though the JPEG standard doesn't define these as "standard tables"
|
---|
189 | * and requires a decoder to be able to read any valid Huffman tables, some
|
---|
190 | * are in reality limited decoding images using these "typical" tables.
|
---|
191 | * Standards like DCF (Design rule for Camera File system) and DLNA (Digital
|
---|
192 | * Living Network Alliance) actually requires any compliant JPEG to use only
|
---|
193 | * the "typical" Huffman tables.
|
---|
194 | * <p>
|
---|
195 | * This is also related to the term "optimized" JPEG. An "optimized" JPEG is
|
---|
196 | * a JPEG that doesn't use the "typical" Huffman tables.
|
---|
197 | *
|
---|
198 | * @return Whether or not all the tables in this
|
---|
199 | * {@link HuffmanTablesDirectory} are the predefined "typical"
|
---|
200 | * Huffman tables.
|
---|
201 | */
|
---|
202 | public boolean isTypical() {
|
---|
203 | if (tables.size() == 0) {
|
---|
204 | return false;
|
---|
205 | }
|
---|
206 | for (HuffmanTable table : tables) {
|
---|
207 | if (!table.isTypical()) {
|
---|
208 | return false;
|
---|
209 | }
|
---|
210 | }
|
---|
211 | return true;
|
---|
212 | }
|
---|
213 |
|
---|
214 | /**
|
---|
215 | * The opposite of {@link #isTypical()}.
|
---|
216 | *
|
---|
217 | * @return Whether or not the tables in this {@link HuffmanTablesDirectory}
|
---|
218 | * are "optimized" - which means that at least one of them aren't
|
---|
219 | * one of the "typical" Huffman tables.
|
---|
220 | */
|
---|
221 | public boolean isOptimized() {
|
---|
222 | return !isTypical();
|
---|
223 | }
|
---|
224 |
|
---|
225 | /**
|
---|
226 | * An instance of this class holds a JPEG Huffman table.
|
---|
227 | */
|
---|
228 | public static class HuffmanTable {
|
---|
229 | private final int tableLength;
|
---|
230 | private final HuffmanTableClass tableClass;
|
---|
231 | private final int tableDestinationId;
|
---|
232 | private final byte[] lengthBytes;
|
---|
233 | private final byte[] valueBytes;
|
---|
234 |
|
---|
235 | public HuffmanTable (
|
---|
236 | @NotNull HuffmanTableClass
|
---|
237 | tableClass,
|
---|
238 | int tableDestinationId,
|
---|
239 | @NotNull byte[] lBytes,
|
---|
240 | @NotNull byte[] vBytes
|
---|
241 | ) {
|
---|
242 | this.tableClass = tableClass;
|
---|
243 | this.tableDestinationId = tableDestinationId;
|
---|
244 | this.lengthBytes = lBytes;
|
---|
245 | this.valueBytes = vBytes;
|
---|
246 | this.tableLength = vBytes.length + 17;
|
---|
247 | }
|
---|
248 |
|
---|
249 | /**
|
---|
250 | * @return The table length in bytes.
|
---|
251 | */
|
---|
252 | public int getTableLength() {
|
---|
253 | return tableLength;
|
---|
254 | }
|
---|
255 |
|
---|
256 |
|
---|
257 | /**
|
---|
258 | * @return The {@link HuffmanTableClass} of this table.
|
---|
259 | */
|
---|
260 | public HuffmanTableClass getTableClass() {
|
---|
261 | return tableClass;
|
---|
262 | }
|
---|
263 |
|
---|
264 |
|
---|
265 | /**
|
---|
266 | * @return the the destination identifier for this table.
|
---|
267 | */
|
---|
268 | public int getTableDestinationId() {
|
---|
269 | return tableDestinationId;
|
---|
270 | }
|
---|
271 |
|
---|
272 |
|
---|
273 | /**
|
---|
274 | * @return A byte array with the L values for this table.
|
---|
275 | */
|
---|
276 | public byte[] getLengthBytes() {
|
---|
277 | if (lengthBytes == null)
|
---|
278 | return null;
|
---|
279 | byte[] result = new byte[lengthBytes.length];
|
---|
280 | System.arraycopy(lengthBytes, 0, result, 0, lengthBytes.length);
|
---|
281 | return result;
|
---|
282 | }
|
---|
283 |
|
---|
284 |
|
---|
285 | /**
|
---|
286 | * @return A byte array with the V values for this table.
|
---|
287 | */
|
---|
288 | public byte[] getValueBytes() {
|
---|
289 | if (valueBytes == null)
|
---|
290 | return null;
|
---|
291 | byte[] result = new byte[valueBytes.length];
|
---|
292 | System.arraycopy(valueBytes, 0, result, 0, valueBytes.length);
|
---|
293 | return result;
|
---|
294 | }
|
---|
295 |
|
---|
296 | /**
|
---|
297 | * Evaluates whether this table is a "typical" Huffman table.
|
---|
298 | * <p>
|
---|
299 | * "Typical" has a special meaning in this context as the JPEG standard
|
---|
300 | * (ISO/IEC 10918 or ITU-T T.81) defines 4 Huffman tables that has been
|
---|
301 | * developed from the average statistics of a large set of images with
|
---|
302 | * 8-bit precision. Using these instead of calculating the optimal
|
---|
303 | * Huffman tables for a given image is faster, and is preferred by many
|
---|
304 | * hardware encoders and some hardware decoders.
|
---|
305 | * <p>
|
---|
306 | * Even though the JPEG standard doesn't define these as
|
---|
307 | * "standard tables" and requires a decoder to be able to read any valid
|
---|
308 | * Huffman tables, some are in reality limited decoding images using
|
---|
309 | * these "typical" tables. Standards like DCF (Design rule for Camera
|
---|
310 | * File system) and DLNA (Digital Living Network Alliance) actually
|
---|
311 | * requires any compliant JPEG to use only the "typical" Huffman tables.
|
---|
312 | * <p>
|
---|
313 | * This is also related to the term "optimized" JPEG. An "optimized"
|
---|
314 | * JPEG is a JPEG that doesn't use the "typical" Huffman tables.
|
---|
315 | *
|
---|
316 | * @return Whether or not this table is one of the predefined "typical"
|
---|
317 | * Huffman tables.
|
---|
318 | */
|
---|
319 | public boolean isTypical() {
|
---|
320 | if (tableClass == HuffmanTableClass.DC) {
|
---|
321 | return
|
---|
322 | Arrays.equals(lengthBytes, TYPICAL_LUMINANCE_DC_LENGTHS) &&
|
---|
323 | Arrays.equals(valueBytes, TYPICAL_LUMINANCE_DC_VALUES) ||
|
---|
324 | Arrays.equals(lengthBytes, TYPICAL_CHROMINANCE_DC_LENGTHS) &&
|
---|
325 | Arrays.equals(valueBytes, TYPICAL_CHROMINANCE_DC_VALUES);
|
---|
326 | } else if (tableClass == HuffmanTableClass.AC) {
|
---|
327 | return
|
---|
328 | Arrays.equals(lengthBytes, TYPICAL_LUMINANCE_AC_LENGTHS) &&
|
---|
329 | Arrays.equals(valueBytes, TYPICAL_LUMINANCE_AC_VALUES) ||
|
---|
330 | Arrays.equals(lengthBytes, TYPICAL_CHROMINANCE_AC_LENGTHS) &&
|
---|
331 | Arrays.equals(valueBytes, TYPICAL_CHROMINANCE_AC_VALUES);
|
---|
332 | }
|
---|
333 | return false;
|
---|
334 | }
|
---|
335 |
|
---|
336 | /**
|
---|
337 | * The opposite of {@link #isTypical()}.
|
---|
338 | *
|
---|
339 | * @return Whether or not this table is "optimized" - which means that
|
---|
340 | * it isn't one of the "typical" Huffman tables.
|
---|
341 | */
|
---|
342 | public boolean isOptimized() {
|
---|
343 | return !isTypical();
|
---|
344 | }
|
---|
345 |
|
---|
346 | public enum HuffmanTableClass {
|
---|
347 | DC,
|
---|
348 | AC,
|
---|
349 | UNKNOWN;
|
---|
350 |
|
---|
351 | public static HuffmanTableClass typeOf(int value) {
|
---|
352 | switch (value) {
|
---|
353 | case 0: return DC;
|
---|
354 | case 1 : return AC;
|
---|
355 | default: return UNKNOWN;
|
---|
356 | }
|
---|
357 | }
|
---|
358 | }
|
---|
359 | }
|
---|
360 | }
|
---|