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