View | Details | Raw Unified | Return to bug 57382
Collapse All | Expand All

(-)Eclipse SWT/common/org/eclipse/swt/internal/image/TIFFDirectory.java (-7 / +38 lines)
Lines 34-39 Link Here
34
	int[] stripByteCounts;
34
	int[] stripByteCounts;
35
	int t4Options;
35
	int t4Options;
36
	int colorMapOffset;
36
	int colorMapOffset;
37
    int predictor = 1;
38
    
39
    /* LZW fields */
40
    TIFFLZWDecoder lzwdecoder;
37
	
41
	
38
	/* Encoder fields */
42
	/* Encoder fields */
39
	ImageData image;
43
	ImageData image;
Lines 55-61 Link Here
55
	static final short TAG_T4Options = 292;
59
	static final short TAG_T4Options = 292;
56
	static final short TAG_ResolutionUnit = 296;
60
	static final short TAG_ResolutionUnit = 296;
57
	static final short TAG_ColorMap = 320;
61
	static final short TAG_ColorMap = 320;
58
	
62
    static final short TAG_Predictor = 317;
63
59
	static final int TYPE_BYTE = 1;
64
	static final int TYPE_BYTE = 1;
60
	static final int TYPE_ASCII = 2;
65
	static final int TYPE_ASCII = 2;
61
	static final int TYPE_SHORT = 3;
66
	static final int TYPE_SHORT = 3;
Lines 63-71 Link Here
63
	static final int TYPE_RATIONAL = 5;
68
	static final int TYPE_RATIONAL = 5;
64
	
69
	
65
	/* Different compression schemes */
70
	/* Different compression schemes */
66
	static final int COMPRESSION_NONE = 1;
71
    static final int COMPRESSION_NONE = 1;
67
	static final int COMPRESSION_CCITT_3_1 = 2;
72
    static final int COMPRESSION_CCITT_3_1 = 2;
68
	static final int COMPRESSION_PACKBITS = 32773;
73
    static final int COMPRESSION_CCITT_3_2 = 3;
74
    static final int COMPRESSION_CCITT_4_2 = 4;
75
    static final int COMPRESSION_LZW = 5;
76
    static final int COMPRESSION_JPEG_OLD = 6;
77
    static final int COMPRESSION_JPEG_TTN2 = 7;
78
    static final int COMPRESSION_PACKBITS = 32773;
79
    static final int COMPRESSION_DEFLATE = 32946;
69
	
80
	
70
	static final int IFD_ENTRY_SIZE = 12;
81
	static final int IFD_ENTRY_SIZE = 12;
71
	
82
	
Lines 149-155 Link Here
149
			destIndex += data.length;
160
			destIndex += data.length;
150
		} else if (compression == COMPRESSION_PACKBITS) {
161
		} else if (compression == COMPRESSION_PACKBITS) {
151
			destIndex += decodePackBits(data, imageData, destIndex);
162
			destIndex += decodePackBits(data, imageData, destIndex);
152
		} else if (compression == COMPRESSION_CCITT_3_1 || compression == 3) {
163
		} else if (compression == COMPRESSION_CCITT_3_1 || compression == COMPRESSION_CCITT_3_2) {
153
			TIFFModifiedHuffmanCodec codec = new TIFFModifiedHuffmanCodec();
164
			TIFFModifiedHuffmanCodec codec = new TIFFModifiedHuffmanCodec();
154
			int nRows = rowsPerStrip;
165
			int nRows = rowsPerStrip;
155
			if (i == length -1) {
166
			if (i == length -1) {
Lines 158-163 Link Here
158
			}
169
			}
159
			destIndex += codec.decode(data, imageData, destIndex, imageWidth, nRows);
170
			destIndex += codec.decode(data, imageData, destIndex, imageWidth, nRows);
160
		}
171
		}
172
        else if(compression == COMPRESSION_LZW){
173
            destIndex = lzwdecoder.decode(data, imageData, destIndex, rowsPerStrip);
174
        }
161
		if (loader.hasListeners()) {
175
		if (loader.hasListeners()) {
162
			loader.notifyListeners(new ImageLoaderEvent(loader, image, i, i == length - 1));
176
			loader.notifyListeners(new ImageLoaderEvent(loader, image, i, i == length - 1));
163
		}
177
		}
Lines 370-377 Link Here
370
				colorMapOffset = getEntryValue(TYPE_LONG, buffer, offset);
384
				colorMapOffset = getEntryValue(TYPE_LONG, buffer, offset);
371
				break;
385
				break;
372
			}
386
			}
373
		}
387
            case TAG_Predictor:{
374
	}
388
                // Option for lzw compression
389
                predictor = getEntryValue(type, buffer, offset); 
390
                if (predictor != 1 && predictor != 2) {
391
                    SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
392
                    //throw new RuntimeException("TIFFImage8");
393
                }
394
395
                if (predictor == 2 && bitsPerSample[0] != 8) {
396
                    SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
397
                    //throw new RuntimeException(sampleSize + "TIFFImage9");
398
                }
399
                break;
400
            }
401
		}
402
	}
403
    if(compression == COMPRESSION_LZW){
404
        lzwdecoder = new TIFFLZWDecoder(imageWidth, predictor, samplesPerPixel);
405
    }
375
}
406
}
376
407
377
public ImageData read() throws IOException {
408
public ImageData read() throws IOException {
(-)Eclipse (+243 lines)
Added Link Here
1
package org.eclipse.swt.internal.image;
2
3
/*
4
5
   Licensed to the Apache Software Foundation (ASF) under one or more
6
   contributor license agreements.  See the NOTICE file distributed with
7
   this work for additional information regarding copyright ownership.
8
   The ASF licenses this file to You under the Apache License, Version 2.0
9
   (the "License"); you may not use this file except in compliance with
10
   the License.  You may obtain a copy of the License at
11
12
       http://www.apache.org/licenses/LICENSE-2.0
13
14
   Unless required by applicable law or agreed to in writing, software
15
   distributed under the License is distributed on an "AS IS" BASIS,
16
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
   See the License for the specific language governing permissions and
18
   limitations under the License.
19
20
*/
21
22
/**
23
 * A class for performing LZW decoding.
24
 *
25
 * @version $Id$
26
 */
27
public class TIFFLZWDecoder {
28
29
    byte[][] stringTable;
30
    byte[] data = null;
31
    byte[] uncompData;
32
    int tableIndex, bitsToGet = 9;
33
    int bytePointer, bitPointer;
34
    int dstIndex;
35
    int w, h;
36
    int predictor, samplesPerPixel;
37
    int nextData = 0;
38
    int nextBits = 0;
39
40
    int[] andTable = {
41
        511,
42
        1023,
43
        2047,
44
        4095
45
    };
46
47
    public TIFFLZWDecoder(int w, int predictor, int samplesPerPixel) {
48
        this.w = w;
49
        this.predictor = predictor;
50
        this.samplesPerPixel = samplesPerPixel;
51
    }
52
53
    /**
54
     * Method to decode LZW compressed data.
55
     *
56
     * @param data            The compressed data.
57
     * @param uncompData      Array to return the uncompressed data in.
58
     * @param h               The number of rows the compressed data contains.
59
     */
60
    public int decode(byte[] data, byte[] uncompData, int destIndex, int h) {
61
62
        if(data[0] == (byte)0x00 && data[1] == (byte)0x01) {
63
            throw new UnsupportedOperationException("TIFFLZWDecoder0");
64
        }
65
66
        initializeStringTable();
67
68
        this.data = data;
69
        this.h = h;
70
        this.uncompData = uncompData;
71
72
        // Initialize pointers
73
        bytePointer = 0;
74
        bitPointer = 0;
75
        dstIndex = destIndex;
76
77
78
        nextData = 0;
79
        nextBits = 0;
80
81
        int code, oldCode = 0;
82
        byte[] string;
83
84
        while ( ((code = getNextCode()) != 257) &&
85
                dstIndex != uncompData.length) {
86
87
            if (code == 256) {
88
89
                initializeStringTable();
90
                code = getNextCode();
91
92
                if (code == 257) {
93
                    break;
94
                }
95
96
                writeString(stringTable[code]);
97
                oldCode = code;
98
99
            } else {
100
101
                if (code < tableIndex) {
102
103
                    string = stringTable[code];
104
105
                    writeString(string);
106
                    addStringToTable(stringTable[oldCode], string[0]);
107
                    oldCode = code;
108
109
                } else {
110
111
                    string = stringTable[oldCode];
112
                    string = composeString(string, string[0]);
113
                    writeString(string);
114
                    addStringToTable(string);
115
                    oldCode = code;
116
                }
117
118
            }
119
120
        }
121
122
        // Horizontal Differencing Predictor
123
        if (predictor == 2) {
124
125
            int count;
126
            for (int j = 0; j < h; j++) {
127
128
                count = samplesPerPixel * (j * w + 1)+ destIndex;
129
130
                for (int i = samplesPerPixel; i < w * samplesPerPixel; i++) {
131
132
                    uncompData[count] += uncompData[count - samplesPerPixel];
133
                    count++;
134
                }
135
            }
136
        }
137
138
        return dstIndex;
139
    }
140
141
142
    /**
143
     * Initialize the string table.
144
     */
145
    public void initializeStringTable() {
146
147
        stringTable = new byte[4096][];
148
149
        for (int i=0; i<256; i++) {
150
            stringTable[i] = new byte[1];
151
            stringTable[i][0] = (byte)i;
152
        }
153
154
        tableIndex = 258;
155
        bitsToGet = 9;
156
    }
157
158
    /**
159
     * Write out the string just uncompressed.
160
     */
161
    public void writeString(byte[] string) {
162
163
        for (int i=0; i<string.length; i++) {
164
            uncompData[dstIndex++] = string[i];
165
        }
166
    }
167
168
    /**
169
     * Add a new string to the string table.
170
     */
171
    public void addStringToTable(byte[] oldString, byte newString) {
172
        int length = oldString.length;
173
        byte[] string = new byte[length + 1];
174
        System.arraycopy(oldString, 0, string, 0, length);
175
        string[length] = newString;
176
177
        // Add this new String to the table
178
        stringTable[tableIndex++] = string;
179
180
        if (tableIndex == 511) {
181
            bitsToGet = 10;
182
        } else if (tableIndex == 1023) {
183
            bitsToGet = 11;
184
        } else if (tableIndex == 2047) {
185
            bitsToGet = 12;
186
        }
187
    }
188
189
    /**
190
     * Add a new string to the string table.
191
     */
192
    public void addStringToTable(byte[] string) {
193
194
        // Add this new String to the table
195
        stringTable[tableIndex++] = string;
196
197
        if (tableIndex == 511) {
198
            bitsToGet = 10;
199
        } else if (tableIndex == 1023) {
200
            bitsToGet = 11;
201
        } else if (tableIndex == 2047) {
202
            bitsToGet = 12;
203
        }
204
    }
205
206
    /**
207
     * Append <code>newString</code> to the end of <code>oldString</code>.
208
     */
209
    public byte[] composeString(byte[] oldString, byte newString) {
210
        int length = oldString.length;
211
        byte[] string = new byte[length + 1];
212
        System.arraycopy(oldString, 0, string, 0, length);
213
        string[length] = newString;
214
215
        return string;
216
    }
217
218
    // Returns the next 9, 10, 11 or 12 bits
219
    public int getNextCode() {
220
        // Attempt to get the next code. The exception is caught to make
221
        // this robust to cases wherein the EndOfInformation code has been
222
        // omitted from a strip. Examples of such cases have been observed
223
        // in practice.
224
        try {
225
            nextData = (nextData << 8) | (data[bytePointer++] & 0xff);
226
            nextBits += 8;
227
228
            if (nextBits < bitsToGet) {
229
                nextData = (nextData << 8) | (data[bytePointer++] & 0xff);
230
                nextBits += 8;
231
            }
232
233
            int code =
234
                (nextData >> (nextBits - bitsToGet)) & andTable[bitsToGet-9];
235
            nextBits -= bitsToGet;
236
237
            return code;
238
        } catch(ArrayIndexOutOfBoundsException e) {
239
            // Strip not terminated as expected: return EndOfInformation code.
240
            return 257;
241
        }
242
    }
243
}

Return to bug 57382