comparison dwt/internal/image/PngHuffmanTables.d @ 0:380af2bdd8e5

Upload of whole dwt tree
author Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com>
date Sat, 09 Aug 2008 17:00:02 +0200
parents
children 1a8b3cb347e0
comparison
equal deleted inserted replaced
-1:000000000000 0:380af2bdd8e5
1 /*******************************************************************************
2 * Copyright (c) 2000, 2006 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 module dwt.internal.image;
12
13 import java.io.IOException;
14
15 public class PngHuffmanTables {
16 PngHuffmanTable literalTable;
17 PngHuffmanTable distanceTable;
18
19 static PngHuffmanTable FixedLiteralTable;
20 static PngHuffmanTable FixedDistanceTable;
21
22 static final int LiteralTableSize = 288;
23 static final int[] FixedLiteralLengths = {
24 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
25 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
26 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
27 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
28 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
29 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
30 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
31 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
32 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
33 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
34 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7,
35 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
36 };
37
38 static final int DistanceTableSize = 32;
39 static final int[] FixedDistanceLengths = {
40 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
41 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
42 };
43
44 static final int LengthCodeTableSize = 19;
45 static final int[] LengthCodeOrder = {
46 16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
47 11, 4, 12, 3, 13, 2, 14, 1, 15
48 };
49
50 static PngHuffmanTables getDynamicTables(PngDecodingDataStream stream) throws IOException {
51 return new PngHuffmanTables(stream);
52 }
53 static PngHuffmanTables getFixedTables() {
54 return new PngHuffmanTables();
55 }
56
57 private PngHuffmanTable getFixedLiteralTable() {
58 if (FixedLiteralTable is null) {
59 FixedLiteralTable = new PngHuffmanTable(FixedLiteralLengths);
60 }
61 return FixedLiteralTable;
62 }
63
64 private PngHuffmanTable getFixedDistanceTable() {
65 if (FixedDistanceTable is null) {
66 FixedDistanceTable = new PngHuffmanTable(FixedDistanceLengths);
67 }
68 return FixedDistanceTable;
69 }
70
71 private PngHuffmanTables () {
72 literalTable = getFixedLiteralTable();
73 distanceTable = getFixedDistanceTable();
74 }
75
76 private PngHuffmanTables (PngDecodingDataStream stream) throws IOException {
77 int literals = PngLzBlockReader.FIRST_LENGTH_CODE
78 + stream.getNextIdatBits(5);
79 int distances = PngLzBlockReader.FIRST_DISTANCE_CODE
80 + stream.getNextIdatBits(5);
81 int codeLengthCodes = PngLzBlockReader.FIRST_CODE_LENGTH_CODE
82 + stream.getNextIdatBits(4);
83
84 if (codeLengthCodes > PngLzBlockReader.LAST_CODE_LENGTH_CODE) {
85 stream.error();
86 }
87
88 /* Tricky, tricky, tricky. The length codes are stored in
89 * a very odd order. (For the order, see the definition of
90 * the static field lengthCodeOrder.) Also, the data may
91 * not contain values for all the codes. It may just contain
92 * values for the first X number of codes. The table should
93 * be of size <LengthCodeTableSize> regardless of the number
94 * of values actually given in the table.
95 */
96 int[] lengthCodes = new int[LengthCodeTableSize];
97 for (int i = 0; i < codeLengthCodes; i++) {
98 lengthCodes[LengthCodeOrder[i]] = stream.getNextIdatBits(3);
99 }
100 PngHuffmanTable codeLengthsTable = new PngHuffmanTable(lengthCodes);
101
102 int[] literalLengths = readLengths(
103 stream, literals, codeLengthsTable, LiteralTableSize);
104 int[] distanceLengths = readLengths(
105 stream, distances, codeLengthsTable, DistanceTableSize);
106
107 literalTable = new PngHuffmanTable(literalLengths);
108 distanceTable = new PngHuffmanTable(distanceLengths);
109 }
110
111 private int [] readLengths (PngDecodingDataStream stream,
112 int numLengths,
113 PngHuffmanTable lengthsTable,
114 int tableSize) throws IOException
115 {
116 int[] lengths = new int[tableSize];
117
118 for (int index = 0; index < numLengths;) {
119 int value = lengthsTable.getNextValue(stream);
120 if (value < 16) {
121 // Literal value
122 lengths[index] = value;
123 index++;
124 } else if (value is 16) {
125 // Repeat the previous code 3-6 times.
126 int count = stream.getNextIdatBits(2) + 3;
127 for (int i = 0; i < count; i++) {
128 lengths[index] = lengths [index - 1];
129 index++;
130 }
131 } else if (value is 17) {
132 // Repeat 0 3-10 times.
133 int count = stream.getNextIdatBits(3) + 3;
134 for (int i = 0; i < count; i++) {
135 lengths[index] = 0;
136 index++;
137 }
138 } else if (value is 18) {
139 // Repeat 0 11-138 times.
140 int count = stream.getNextIdatBits(7) + 11;
141 for (int i = 0; i < count; i++) {
142 lengths[index] = 0;
143 index++;
144 }
145 } else {
146 stream.error();
147 }
148 }
149 return lengths;
150 }
151
152 int getNextLiteralValue(PngDecodingDataStream stream) throws IOException {
153 return literalTable.getNextValue(stream);
154 }
155
156 int getNextDistanceValue(PngDecodingDataStream stream) throws IOException {
157 return distanceTable.getNextValue(stream);
158 }
159
160 }