1 18 19 package org.apache.batik.ext.awt.image.codec.tiff; 20 21 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 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 ("TIFFLZWDecoder0"); 62 } 63 64 initializeStringTable(); 65 66 this.data = data; 67 this.h = h; 68 this.uncompData = uncompData; 69 70 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 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 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 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 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 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 190 public void addStringToTable(byte string[]) { 191 192 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 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 public int getNextCode() { 218 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 e) { 237 return 257; 239 } 240 } 241 } 242 | Popular Tags |