Mercurial > projects > dwt2
annotate org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/internal/image/TIFFModifiedHuffmanCodec.d @ 49:7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 27 Mar 2009 12:59:54 +0100 |
parents | f713da8bc051 |
children | 536e43f63c81 |
rev | line source |
---|---|
25 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2003 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.TIFFModifiedHuffmanCodec; | |
14 | |
15 import java.lang.all; | |
16 | |
17 import org.eclipse.swt.SWT; | |
18 | |
19 /* | |
20 * Decoder for | |
21 * - CCITT Group 3 1-Dimensional Modified Huffman run length encoding | |
22 * (TIFF compression type 2) | |
23 * - CCITT T.4 bi-level encoding 1D | |
24 * (TIFF compression type 3 option 1D) | |
25 */ | |
26 final class TIFFModifiedHuffmanCodec { | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
27 static const short[][][] BLACK_CODE = [ |
25 | 28 /* 2 bits */ |
29 [[ cast(short)2, 3], [ cast(short)3, 2]], | |
30 /* 3 bits */ | |
31 [[ cast(short)2, 1], [ cast(short)3, 4]], | |
32 /* 4 bits */ | |
33 [[ cast(short)2, 6], [ cast(short)3, 5]], | |
34 /* 5 bits */ | |
35 [[ cast(short)3, 7]], | |
36 /* 6 bits */ | |
37 [[ cast(short)4, 9], [ cast(short)5, 8]], | |
38 /* 7 bits */ | |
39 [[ cast(short)4, 10], [ cast(short)5, 11], [ cast(short)7, 12]], | |
40 /* 8 bits */ | |
41 [[ cast(short)4, 13], [ cast(short)7, 14]], | |
42 /* 9 bits */ | |
43 [[ cast(short)24, 15]], | |
44 /* 10 bits */ | |
45 [[ cast(short)8, 18], [ cast(short)15, 64], [ cast(short)23, 16], [ cast(short)24, 17], [ cast(short)55, 0]], | |
46 /* 11 bits */ | |
47 [/* EOL */[ cast(short)0, -1], [ cast(short)8, 1792], [ cast(short)23, 24], [ cast(short)24, 25], [ cast(short)40, 23], [ cast(short)55, 22], [ cast(short)103, 19], | |
48 [ cast(short)104, 20], [ cast(short)108, 21], [ cast(short)12, 1856], [ cast(short)13, 1920]], | |
49 /* 12 bits */ | |
50 [[ cast(short)18, 1984], [ cast(short)19, 2048], [ cast(short)20, 2112], [ cast(short)21, 2176], [ cast(short)22, 2240], [ cast(short)23, 2304], | |
51 [ cast(short)28, 2368], [ cast(short)29, 2432], [ cast(short)30, 2496], [ cast(short)31, 2560], [ cast(short)36, 52], [ cast(short)39, 55], [ cast(short)40, 56], | |
52 [ cast(short)43, 59], [ cast(short)44, 60], [ cast(short)51, 320], [ cast(short)52, 384], [ cast(short)53, 448], [ cast(short)55, 53], [ cast(short)56, 54], [ cast(short)82, 50], | |
53 [ cast(short)83, 51], [ cast(short)84, 44], [ cast(short)85, 45], [ cast(short)86, 46], [ cast(short)87, 47], [ cast(short)88, 57], [ cast(short)89, 58], [ cast(short)90, 61], | |
54 [ cast(short)91, 256], [ cast(short)100, 48], [ cast(short)101, 49], [ cast(short)102, 62], [ cast(short)103, 63], [ cast(short)104, 30], [ cast(short)105, 31], | |
55 [ cast(short)106, 32], [ cast(short)107, 33], [ cast(short)108, 40], [ cast(short)109, 41], [ cast(short)200, 128], [ cast(short)201, 192], [ cast(short)202, 26], | |
56 [ cast(short)203, 27], [ cast(short)204, 28], [ cast(short)205, 29], [ cast(short)210, 34], [ cast(short)211, 35], [ cast(short)212, 36], [ cast(short)213, 37], | |
57 [ cast(short)214, 38], [ cast(short)215, 39], [ cast(short)218, 42], [ cast(short)219, 43]], | |
58 /* 13 bits */ | |
59 [[ cast(short)74, 640], [ cast(short)75, 704], [ cast(short)76, 768], [ cast(short)77, 832], [ cast(short)82, 1280], [ cast(short)83, 1344], [ cast(short)84, 1408], | |
60 [ cast(short)85, 1472], [ cast(short)90, 1536], [ cast(short)91, 1600], [ cast(short)100, 1664], [ cast(short)101, 1728], [ cast(short)108, 512], | |
61 [ cast(short)109, 576], [ cast(short)114, 896], [ cast(short)115, 960], [ cast(short)116, 1024], [ cast(short)117, 1088], [ cast(short)118, 1152], | |
62 [ cast(short)119, 1216]] | |
63 ]; | |
64 | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
65 static const short[][][] WHITE_CODE = [ |
25 | 66 /* 4 bits */ |
67 [[ cast(short)7, 2], [ cast(short)8, 3], [ cast(short)11, 4], [ cast(short)12, 5], [ cast(short)14, 6], [ cast(short)15, 7]], | |
68 /* 5 bits */ | |
69 [[ cast(short)7, 10], [ cast(short)8, 11], [ cast(short)18, 128], [ cast(short)19, 8], [ cast(short)20, 9], [ cast(short)27, 64]], | |
70 /* 6 bits */ | |
71 [[ cast(short)3, 13], [ cast(short)7, 1], [ cast(short)8, 12], [ cast(short)23, 192], [ cast(short)24, 1664], [ cast(short)42, 16], [ cast(short)43, 17], [ cast(short)52, 14], | |
72 [ cast(short)53, 15]], | |
73 /* 7 bits */ | |
74 [[ cast(short)3, 22], [ cast(short)4, 23], [ cast(short)8, 20], [ cast(short)12, 19], [ cast(short)19, 26], [ cast(short)23, 21], [ cast(short)24, 28], [ cast(short)36, 27], | |
75 [ cast(short)39, 18], [ cast(short)40, 24], [ cast(short)43, 25], [ cast(short)55, 256]], | |
76 /* 8 bits */ | |
77 [[ cast(short)2, 29], [ cast(short)3, 30], [ cast(short)4, 45], [ cast(short)5, 46], [ cast(short)10, 47], [ cast(short)11, 48], [ cast(short)18, 33], [ cast(short)19, 34], | |
78 [ cast(short)20, 35], [ cast(short)21, 36], [ cast(short)22, 37], [ cast(short)23, 38], [ cast(short)26, 31], [ cast(short)27, 32], [ cast(short)36, 53], [ cast(short)37, 54], | |
79 [ cast(short)40, 39], [ cast(short)41, 40], [ cast(short)42, 41], [ cast(short)43, 42], [ cast(short)44, 43], [ cast(short)45, 44], [ cast(short)50, 61], [ cast(short)51, 62], | |
80 [ cast(short)52, 63], [ cast(short)53, 0], [ cast(short)54, 320], [ cast(short)55, 384], [ cast(short)74, 59], [ cast(short)75, 60], [ cast(short)82, 49], [ cast(short)83, 50], | |
81 [ cast(short)84, 51], [ cast(short)85, 52], [ cast(short)88, 55], [ cast(short)89, 56], [ cast(short)90, 57], [ cast(short)91, 58], [ cast(short)100, 448], | |
82 [ cast(short)101, 512], [ cast(short)103, 640], [ cast(short)104, 576]], | |
83 /* 9 bits */ | |
84 [[ cast(short)152, 1472], [ cast(short)153, 1536], [ cast(short)154, 1600], [ cast(short)155, 1728], [ cast(short)204, 704], [ cast(short)205, 768], | |
85 [ cast(short)210, 832], [ cast(short)211, 896], [ cast(short)212, 960], [ cast(short)213, 1024], [ cast(short)214, 1088], [ cast(short)215, 1152], | |
86 [ cast(short)216, 1216], [ cast(short)217, 1280], [ cast(short)218, 1344], [ cast(short)219, 1408]], | |
87 /* 10 bits */ | |
88 [], | |
89 /* 11 bits */ | |
90 [[ cast(short)8, 1792], [ cast(short)12, 1856], [ cast(short)13, 1920]], | |
91 /* 12 bits */ | |
92 [/* EOL */[ cast(short)1, -1], [ cast(short)18, 1984], [ cast(short)19, 2048], [ cast(short)20, 2112], [ cast(short)21, 2176], [ cast(short)22, 2240], [ cast(short)23, 2304], | |
93 [ cast(short)28, 2368], [ cast(short)29, 2432], [ cast(short)30, 2496], [ cast(short)31, 2560]] | |
94 ]; | |
95 | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
96 static const int BLACK_MIN_BITS = 2; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
97 static const int WHITE_MIN_BITS = 4; |
25 | 98 |
99 bool isWhite; | |
100 int whiteValue = 0; | |
101 int blackValue = 1; | |
102 byte[] src; | |
103 byte[] dest; | |
104 int byteOffsetSrc = 0; | |
105 int bitOffsetSrc = 0; | |
106 int byteOffsetDest = 0; | |
107 int bitOffsetDest = 0; | |
108 int code = 0; | |
109 int nbrBits = 0; | |
110 /* nbr of bytes per row */ | |
111 int rowSize; | |
112 | |
113 public int decode(byte[] src, byte[] dest, int offsetDest, int rowSize, int nRows) { | |
114 this.src = src; | |
115 this.dest = dest; | |
116 this.rowSize = rowSize; | |
117 byteOffsetSrc = 0; | |
118 bitOffsetSrc = 0; | |
119 byteOffsetDest = offsetDest; | |
120 bitOffsetDest = 0; | |
121 int cnt = 0; | |
122 while (cnt < nRows && decodeRow()) { | |
123 cnt++; | |
124 /* byte aligned */ | |
125 if (bitOffsetDest > 0) { | |
126 byteOffsetDest++; | |
127 bitOffsetDest = 0; | |
128 } | |
129 } | |
130 return byteOffsetDest - offsetDest; | |
131 } | |
132 | |
133 bool decodeRow() { | |
134 isWhite = true; | |
135 int n = 0; | |
136 while (n < rowSize) { | |
137 int runLength = decodeRunLength(); | |
138 if (runLength < 0) return false; | |
139 n += runLength; | |
140 setNextBits(isWhite ? whiteValue : blackValue, runLength); | |
141 isWhite = !isWhite; | |
142 } | |
143 return true; | |
144 } | |
145 | |
146 int decodeRunLength() { | |
147 int runLength = 0; | |
148 int partialRun = 0; | |
149 short[][][] huffmanCode = isWhite ? WHITE_CODE : BLACK_CODE; | |
150 while (true) { | |
151 bool found = false; | |
152 nbrBits = isWhite ? WHITE_MIN_BITS : BLACK_MIN_BITS; | |
153 code = getNextBits(nbrBits); | |
154 for (int i = 0; i < huffmanCode.length; i++) { | |
155 for (int j = 0; j < huffmanCode[i].length; j++) { | |
156 if (huffmanCode[i][j][0] is code) { | |
157 found = true; | |
158 partialRun = huffmanCode[i][j][1]; | |
159 if (partialRun is -1) { | |
160 /* Stop when reaching final EOL on last byte */ | |
161 if (byteOffsetSrc is src.length - 1) return -1; | |
162 /* Group 3 starts each row with an EOL - ignore it */ | |
163 } else { | |
164 runLength += partialRun; | |
165 if (partialRun < 64) return runLength; | |
166 } | |
167 break; | |
168 } | |
169 } | |
170 if (found) break; | |
171 code = code << 1 | getNextBit(); | |
172 } | |
173 if (!found) SWT.error(SWT.ERROR_INVALID_IMAGE); | |
174 } | |
175 } | |
176 | |
177 int getNextBit() { | |
178 int value = (src[byteOffsetSrc] >>> (7 - bitOffsetSrc)) & 0x1; | |
179 bitOffsetSrc++; | |
180 if (bitOffsetSrc > 7) { | |
181 byteOffsetSrc++; | |
182 bitOffsetSrc = 0; | |
183 } | |
184 return value; | |
185 } | |
186 | |
187 int getNextBits(int cnt) { | |
188 int value = 0; | |
189 for (int i = 0; i < cnt; i++) { | |
190 value = value << 1 | getNextBit(); | |
191 } | |
192 return value; | |
193 } | |
194 | |
195 void setNextBits(int value, int cnt) { | |
196 int n = cnt; | |
197 while (bitOffsetDest > 0 && bitOffsetDest <= 7 && n > 0) { | |
198 dest[byteOffsetDest] = value is 1 ? | |
199 cast(byte)(dest[byteOffsetDest] | (1 << (7 - bitOffsetDest))) : | |
200 cast(byte)(dest[byteOffsetDest] & ~(1 << (7 - bitOffsetDest))); | |
201 n--; | |
202 bitOffsetDest++; | |
203 } | |
204 if (bitOffsetDest is 8) { | |
205 byteOffsetDest++; | |
206 bitOffsetDest = 0; | |
207 } | |
208 while (n >= 8) { | |
209 dest[byteOffsetDest++] = cast(byte) (value is 1 ? 0xFF : 0); | |
210 n -= 8; | |
211 } | |
212 while (n > 0) { | |
213 dest[byteOffsetDest] = value is 1 ? | |
214 cast(byte)(dest[byteOffsetDest] | (1 << (7 - bitOffsetDest))) : | |
215 cast(byte)(dest[byteOffsetDest] & ~(1 << (7 - bitOffsetDest))); | |
216 n--; | |
217 bitOffsetDest++; | |
218 } | |
219 } | |
220 | |
221 } |