comparison org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/internal/image/JPEGHuffmanTable.d @ 25:f713da8bc051

Added SWT Linux GTK
author Frank Benoit <benoit@tionex.de>
date Fri, 20 Mar 2009 23:03:58 +0100
parents
children 536e43f63c81
comparison
equal deleted inserted replaced
24:b7a1d02a0e1f 25:f713da8bc051
1 /*******************************************************************************
2 * Copyright (c) 2000, 2005 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 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module org.eclipse.swt.internal.image.JPEGHuffmanTable;
14
15 import java.lang.all;
16
17 import org.eclipse.swt.internal.image.JPEGVariableSizeSegment;
18 import org.eclipse.swt.internal.image.LEDataInputStream;
19 import org.eclipse.swt.internal.image.JPEGFileFormat;
20
21 /**
22 * JPEGHuffmanTable class actually represents two types of object:
23 * 1) A DHT (Define Huffman Tables) segment, which may represent
24 * as many as 4 Huffman tables. In this case, the tables are
25 * stored in the allTables array.
26 * 2) A single Huffman table. In this case, the allTables array
27 * will be null.
28 * The 'reference' field is stored in both types of object, but
29 * 'initialize' is only called if the object represents a DHT.
30 */
31 final class JPEGHuffmanTable : JPEGVariableSizeSegment {
32 JPEGHuffmanTable[] allTables;
33 int tableClass;
34 int tableIdentifier;
35 int[] dhMaxCodes;
36 int[] dhMinCodes;
37 int[] dhValPtrs;
38 int[] dhValues;
39 int[] ehCodes;
40 byte[] ehCodeLengths;
41 static byte[] DCLuminanceTable = [
42 cast(byte)255, cast(byte)196, 0, 31, 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
43 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
44 ];
45 static byte[] DCChrominanceTable = [
46 cast(byte)255, cast(byte)196, 0, 31, 1, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
47 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
48 ];
49 static byte[] ACLuminanceTable = [
50 cast(byte)255, cast(byte)196, 0, cast(byte)181, 16, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125,
51 1, 2, 3, 0, 4, 17, 5, 18, 33, 49, 65, 6, 19, 81, 97, 7, 34, 113, 20,
52 50, cast(byte)129, cast(byte)145, cast(byte)161, 8, 35, 66, cast(byte)177, cast(byte)193, 21, 82, cast(byte)209, cast(byte)240, 36, 51, 98,
53 114, cast(byte)130, 9, 10, 22, 23, 24, 25, 26, 37, 38, 39, 40, 41, 42, 52, 53,
54 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87,
55 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118,
56 119, 120, 121, 122, cast(byte)131, cast(byte)132, cast(byte)133, cast(byte)134, cast(byte)135, cast(byte)136, cast(byte)137, cast(byte)138, cast(byte)146, cast(byte)147, cast(byte)148,
57 cast(byte)149, cast(byte)150, cast(byte)151, cast(byte)152, cast(byte)153, cast(byte)154, cast(byte)162, cast(byte)163, cast(byte)164, cast(byte)165, cast(byte)166, cast(byte)167, cast(byte)168, cast(byte)169, cast(byte)170,
58 cast(byte)178, cast(byte)179, cast(byte)180, cast(byte)181, cast(byte)182, cast(byte)183, cast(byte)184, cast(byte)185, cast(byte)186, cast(byte)194, cast(byte)195, cast(byte)196, cast(byte)197, cast(byte)198, cast(byte)199,
59 cast(byte)200, cast(byte)201, cast(byte)202, cast(byte)210, cast(byte)211, cast(byte)212, cast(byte)213, cast(byte)214, cast(byte)215, cast(byte)216, cast(byte)217, cast(byte)218, cast(byte)225, cast(byte)226, cast(byte)227,
60 cast(byte)228, cast(byte)229, cast(byte)230, cast(byte)231, cast(byte)232, cast(byte)233, cast(byte)234, cast(byte)241, cast(byte)242, cast(byte)243, cast(byte)244, cast(byte)245, cast(byte)246, cast(byte)247, cast(byte)248,
61 cast(byte)249, cast(byte)250
62 ];
63 static byte[] ACChrominanceTable = [
64 cast(byte)255, cast(byte)196, 0, cast(byte)181, 17, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0,
65 1, 2, 119, 0, 1, 2, 3, 17, 4, 5, 33, 49, 6, 18, 65, 81, 7, 97, 113, 19, 34,
66 50, cast(byte)129, 8, 20, 66, cast(byte)145, cast(byte)161, cast(byte)177, cast(byte)193, 9, 35,
67 51, 82, cast(byte)240, 21, 98, 114, cast(byte)209, 10, 22, 36, 52, cast(byte)225, 37,
68 cast(byte)241, 23, 24, 25, 26, 38, 39, 40, 41, 42, 53, 54, 55, 56, 57, 58, 67,
69 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102,
70 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, cast(byte)130,
71 cast(byte)131, cast(byte)132, cast(byte)133, cast(byte)134, cast(byte)135, cast(byte)136, cast(byte)137,
72 cast(byte)138, cast(byte)146, cast(byte)147, cast(byte)148, cast(byte)149, cast(byte)150, cast(byte)151,
73 cast(byte)152, cast(byte)153, cast(byte)154, cast(byte)162, cast(byte)163, cast(byte)164, cast(byte)165,
74 cast(byte)166, cast(byte)167, cast(byte)168, cast(byte)169, cast(byte)170, cast(byte)178, cast(byte)179,
75 cast(byte)180, cast(byte)181, cast(byte)182, cast(byte)183, cast(byte)184, cast(byte)185, cast(byte)186,
76 cast(byte)194, cast(byte)195, cast(byte)196, cast(byte)197, cast(byte)198, cast(byte)199, cast(byte)200,
77 cast(byte)201, cast(byte)202, cast(byte)210, cast(byte)211, cast(byte)212, cast(byte)213, cast(byte)214,
78 cast(byte)215, cast(byte)216, cast(byte)217, cast(byte)218, cast(byte)226, cast(byte)227, cast(byte)228,
79 cast(byte)229, cast(byte)230, cast(byte)231, cast(byte)232, cast(byte)233, cast(byte)234, cast(byte)242,
80 cast(byte)243, cast(byte)244, cast(byte)245, cast(byte)246, cast(byte)247, cast(byte)248, cast(byte)249,
81 cast(byte)250
82 ];
83
84 public this(byte[] reference) {
85 super(reference);
86 }
87
88 public this(LEDataInputStream byteStream) {
89 super(byteStream);
90 initialize();
91 }
92
93 public JPEGHuffmanTable[] getAllTables() {
94 return allTables;
95 }
96
97 public static JPEGHuffmanTable getDefaultACChrominanceTable() {
98 JPEGHuffmanTable result = new JPEGHuffmanTable(ACChrominanceTable);
99 result.initialize();
100 return result;
101 }
102
103 public static JPEGHuffmanTable getDefaultACLuminanceTable() {
104 JPEGHuffmanTable result = new JPEGHuffmanTable(ACLuminanceTable);
105 result.initialize();
106 return result;
107 }
108
109 public static JPEGHuffmanTable getDefaultDCChrominanceTable() {
110 JPEGHuffmanTable result = new JPEGHuffmanTable(DCChrominanceTable);
111 result.initialize();
112 return result;
113 }
114
115 public static JPEGHuffmanTable getDefaultDCLuminanceTable() {
116 JPEGHuffmanTable result = new JPEGHuffmanTable(DCLuminanceTable);
117 result.initialize();
118 return result;
119 }
120
121 public int[] getDhMaxCodes() {
122 return dhMaxCodes;
123 }
124
125 public int[] getDhMinCodes() {
126 return dhMinCodes;
127 }
128
129 public int[] getDhValPtrs() {
130 return dhValPtrs;
131 }
132
133 public int[] getDhValues() {
134 return dhValues;
135 }
136
137 public int getTableClass() {
138 return tableClass;
139 }
140
141 public int getTableIdentifier() {
142 return tableIdentifier;
143 }
144
145 void initialize() {
146 int totalLength = getSegmentLength() - 2;
147 int ofs = 4;
148 int[] bits = new int[16];
149 JPEGHuffmanTable[] huffTables = new JPEGHuffmanTable[8]; // maximum is 4 AC + 4 DC
150 int huffTableCount = 0;
151 while (totalLength > 0) {
152 int tc = (reference[ofs] & 0xFF) >> 4; // table class: AC (1) or DC (0)
153 int tid = reference[ofs] & 0xF; // table id: 0-1 baseline, 0-3 prog/ext
154 ofs++;
155
156 /* Read the 16 count bytes and add them together to get the table size. */
157 int count = 0;
158 for (int i = 0; i < bits.length; i++) {
159 int bCount = reference[ofs + i] & 0xFF;
160 bits[i] = bCount;
161 count += bCount;
162 }
163 ofs += 16;
164 totalLength -= 17;
165
166 /* Read the table. */
167 int[] huffVals = new int[count];
168 for (int i = 0; i < count; i++) {
169 huffVals[i] = reference[ofs + i] & 0xFF;
170 }
171 ofs += count;
172 totalLength -= count;
173
174 /* Calculate the lengths. */
175 int[] huffCodeLengths = new int[50]; // start with 50 and increment as needed
176 int huffCodeLengthsIndex = 0;
177 for (int i = 0; i < 16; i++) {
178 for (int j = 0; j < bits[i]; j++) {
179 if (huffCodeLengthsIndex >= huffCodeLengths.length) {
180 int[] newHuffCodeLengths = new int[huffCodeLengths.length + 50];
181 System.arraycopy(huffCodeLengths, 0, newHuffCodeLengths, 0, huffCodeLengths.length);
182 huffCodeLengths = newHuffCodeLengths;
183 }
184 huffCodeLengths[huffCodeLengthsIndex] = i + 1;
185 huffCodeLengthsIndex++;
186 }
187 }
188
189 /* Truncate huffCodeLengths to the correct size. */
190 if (huffCodeLengthsIndex < huffCodeLengths.length) {
191 int[] newHuffCodeLengths = new int[huffCodeLengthsIndex];
192 System.arraycopy(huffCodeLengths, 0, newHuffCodeLengths, 0, huffCodeLengthsIndex);
193 huffCodeLengths = newHuffCodeLengths;
194 }
195
196 /* Calculate the Huffman codes. */
197 int[] huffCodes = new int[50]; // start with 50 and increment as needed
198 int huffCodesIndex = 0;
199 int k = 1;
200 int code = 0;
201 int si = huffCodeLengths[0];
202 int p = 0;
203 while (p < huffCodeLengthsIndex) {
204 while ((p < huffCodeLengthsIndex) && (huffCodeLengths[p] is si)) {
205 if (huffCodesIndex >= huffCodes.length) {
206 int[] newHuffCodes = new int[huffCodes.length + 50];
207 System.arraycopy(huffCodes, 0, newHuffCodes, 0, huffCodes.length);
208 huffCodes = newHuffCodes;
209 }
210 huffCodes[huffCodesIndex] = code;
211 huffCodesIndex++;
212 code++;
213 p++;
214 }
215 code *= 2;
216 si++;
217 }
218
219 /* Truncate huffCodes to the correct size. */
220 if (huffCodesIndex < huffCodes.length) {
221 int[] newHuffCodes = new int[huffCodesIndex];
222 System.arraycopy(huffCodes, 0, newHuffCodes, 0, huffCodesIndex);
223 huffCodes = newHuffCodes;
224 }
225
226 /* Calculate the maximum and minimum codes */
227 k = 0;
228 int[] maxCodes = new int[16];
229 int[] minCodes = new int[16];
230 int[] valPtrs = new int[16];
231 for (int i = 0; i < 16; i++) {
232 int bSize = bits[i];
233 if (bSize is 0) {
234 maxCodes[i] = -1;
235 } else {
236 valPtrs[i] = k;
237 minCodes[i] = huffCodes[k];
238 k += bSize;
239 maxCodes[i] = huffCodes[k - 1];
240 }
241 }
242
243 /* Calculate the eHuffman codes and lengths. */
244 int[] eHuffCodes = new int[256];
245 byte[] eHuffSize = new byte[256];
246 for (int i = 0; i < huffCodesIndex; i++) {
247 eHuffCodes[huffVals[i]] = huffCodes[i];
248 eHuffSize[huffVals[i]] = cast(byte)huffCodeLengths[i];
249 }
250
251 /* Create the new JPEGHuffmanTable and add it to the allTables array. */
252 JPEGHuffmanTable dhtTable = new JPEGHuffmanTable(reference);
253 dhtTable.tableClass = tc;
254 dhtTable.tableIdentifier = tid;
255 dhtTable.dhValues = huffVals;
256 dhtTable.dhMinCodes = minCodes;
257 dhtTable.dhMaxCodes = maxCodes;
258 dhtTable.dhValPtrs = valPtrs;
259 dhtTable.ehCodes = eHuffCodes;
260 dhtTable.ehCodeLengths = eHuffSize;
261 huffTables[huffTableCount] = dhtTable;
262 huffTableCount++;
263 }
264 allTables = new JPEGHuffmanTable[huffTableCount];
265 System.arraycopy(huffTables, 0, allTables, 0, huffTableCount);
266 }
267
268 public override int signature() {
269 return JPEGFileFormat.DHT;
270 }
271 }