KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > internal > image > TIFFModifiedHuffmanCodec


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 package org.eclipse.swt.internal.image;
12
13 import org.eclipse.swt.*;
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     boolean 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 boolean 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         boolean 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] == code) {
153                     found = true;
154                     partialRun = huffmanCode[i][j][1];
155                     if (partialRun == -1) {
156                         /* Stop when reaching final EOL on last byte */
157                         if (byteOffsetSrc == 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) SWT.error(SWT.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 == 1 ?
195             (byte)(dest[byteOffsetDest] | (1 << (7 - bitOffsetDest))) :
196             (byte)(dest[byteOffsetDest] & ~(1 << (7 - bitOffsetDest)));
197         n--;
198         bitOffsetDest++;
199     }
200     if (bitOffsetDest == 8) {
201         byteOffsetDest++;
202         bitOffsetDest = 0;
203     }
204     while (n >= 8) {
205         dest[byteOffsetDest++] = (byte) (value == 1 ? 0xFF : 0);
206         n -= 8;
207     }
208     while (n > 0) {
209         dest[byteOffsetDest] = value == 1 ?
210             (byte)(dest[byteOffsetDest] | (1 << (7 - bitOffsetDest))) :
211             (byte)(dest[byteOffsetDest] & ~(1 << (7 - bitOffsetDest)));
212         n--;
213         bitOffsetDest++;
214     }
215 }
216
217 }
218
Popular Tags