KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > ext > awt > image > codec > tiff > TIFFLZWDecoder


1 /*
2
3    Copyright 1999-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17 */

18
19 package org.apache.batik.ext.awt.image.codec.tiff;
20
21 /**
22  * A class for performing LZW decoding.
23  *
24  *
25  */

26 public class TIFFLZWDecoder {
27
28     byte stringTable[][];
29     byte data[] = null, uncompData[];
30     int tableIndex, bitsToGet = 9;
31     int bytePointer, bitPointer;
32     int dstIndex;
33     int w, h;
34     int predictor, samplesPerPixel;
35     int nextData = 0;
36     int nextBits = 0;
37
38     int andTable[] = {
39     511,
40     1023,
41     2047,
42     4095
43     };
44     
45     public TIFFLZWDecoder(int w, int predictor, int samplesPerPixel) {
46     this.w = w;
47     this.predictor = predictor;
48     this.samplesPerPixel = samplesPerPixel;
49     }
50
51     /**
52      * Method to decode LZW compressed data.
53      *
54      * @param data The compressed data.
55      * @param uncompData Array to return the uncompressed data in.
56      * @param h The number of rows the compressed data contains.
57      */

58     public byte[] decode(byte data[], byte uncompData[], int h) {
59
60         if(data[0] == (byte)0x00 && data[1] == (byte)0x01) {
61             throw new UnsupportedOperationException JavaDoc("TIFFLZWDecoder0");
62         }
63
64     initializeStringTable();
65
66     this.data = data;
67     this.h = h;
68     this.uncompData = uncompData;
69     
70     // Initialize pointers
71
bytePointer = 0;
72     bitPointer = 0;
73     dstIndex = 0;
74
75
76     nextData = 0;
77     nextBits = 0;
78
79     int code, oldCode = 0;
80     byte string[];
81  
82     while ( ((code = getNextCode()) != 257) &&
83         dstIndex != uncompData.length) {
84
85         if (code == 256) {
86
87         initializeStringTable();
88         code = getNextCode();
89
90         if (code == 257) {
91             break;
92         }
93
94         writeString(stringTable[code]);
95         oldCode = code;
96
97         } else {
98
99         if (code < tableIndex) {
100
101             string = stringTable[code];
102
103             writeString(string);
104             addStringToTable(stringTable[oldCode], string[0]);
105             oldCode = code;
106
107         } else {
108
109             string = stringTable[oldCode];
110             string = composeString(string, string[0]);
111             writeString(string);
112             addStringToTable(string);
113             oldCode = code;
114         }
115
116         }
117
118     }
119
120     // Horizontal Differencing Predictor
121
if (predictor == 2) {
122
123         int count;
124         for (int j = 0; j < h; j++) {
125         
126         count = samplesPerPixel * (j * w + 1);
127         
128         for (int i = samplesPerPixel; i < w * samplesPerPixel; i++) {
129             
130             uncompData[count] += uncompData[count - samplesPerPixel];
131             count++;
132         }
133         }
134     }
135
136     return uncompData;
137     }
138
139
140     /**
141      * Initialize the string table.
142      */

143     public void initializeStringTable() {
144
145     stringTable = new byte[4096][];
146     
147     for (int i=0; i<256; i++) {
148         stringTable[i] = new byte[1];
149         stringTable[i][0] = (byte)i;
150     }
151     
152     tableIndex = 258;
153     bitsToGet = 9;
154     }
155
156     /**
157      * Write out the string just uncompressed.
158      */

159     public void writeString(byte string[]) {
160     
161     for (int i=0; i<string.length; i++) {
162         uncompData[dstIndex++] = string[i];
163     }
164     }
165     
166     /**
167      * Add a new string to the string table.
168      */

169     public void addStringToTable(byte oldString[], byte newString) {
170     int length = oldString.length;
171     byte string[] = new byte[length + 1];
172     System.arraycopy(oldString, 0, string, 0, length);
173     string[length] = newString;
174     
175     // Add this new String to the table
176
stringTable[tableIndex++] = string;
177     
178     if (tableIndex == 511) {
179         bitsToGet = 10;
180     } else if (tableIndex == 1023) {
181         bitsToGet = 11;
182     } else if (tableIndex == 2047) {
183         bitsToGet = 12;
184     }
185     }
186
187     /**
188      * Add a new string to the string table.
189      */

190     public void addStringToTable(byte string[]) {
191     
192     // Add this new String to the table
193
stringTable[tableIndex++] = string;
194     
195     if (tableIndex == 511) {
196         bitsToGet = 10;
197     } else if (tableIndex == 1023) {
198         bitsToGet = 11;
199     } else if (tableIndex == 2047) {
200         bitsToGet = 12;
201     }
202     }
203
204     /**
205      * Append <code>newString</code> to the end of <code>oldString</code>.
206      */

207     public byte[] composeString(byte oldString[], byte newString) {
208     int length = oldString.length;
209     byte string[] = new byte[length + 1];
210     System.arraycopy(oldString, 0, string, 0, length);
211     string[length] = newString;
212
213     return string;
214     }
215
216     // Returns the next 9, 10, 11 or 12 bits
217
public int getNextCode() {
218         // Attempt to get the next code. The exception is caught to make
219
// this robust to cases wherein the EndOfInformation code has been
220
// omitted from a strip. Examples of such cases have been observed
221
// in practice.
222
try {
223             nextData = (nextData << 8) | (data[bytePointer++] & 0xff);
224             nextBits += 8;
225
226             if (nextBits < bitsToGet) {
227                 nextData = (nextData << 8) | (data[bytePointer++] & 0xff);
228                 nextBits += 8;
229             }
230
231             int code =
232                 (nextData >> (nextBits - bitsToGet)) & andTable[bitsToGet-9];
233             nextBits -= bitsToGet;
234
235             return code;
236         } catch(ArrayIndexOutOfBoundsException JavaDoc e) {
237             // Strip not terminated as expected: return EndOfInformation code.
238
return 257;
239         }
240     }
241 }
242
Popular Tags