1 33 package com.lowagie.text.pdf.codec; 34 35 40 public class TIFFLZWDecoder { 41 42 byte stringTable[][]; 43 byte data[] = null, uncompData[]; 44 int tableIndex, bitsToGet = 9; 45 int bytePointer, bitPointer; 46 int dstIndex; 47 int w, h; 48 int predictor, samplesPerPixel; 49 int nextData = 0; 50 int nextBits = 0; 51 52 int andTable[] = { 53 511, 54 1023, 55 2047, 56 4095 57 }; 58 59 public TIFFLZWDecoder(int w, int predictor, int samplesPerPixel) { 60 this.w = w; 61 this.predictor = predictor; 62 this.samplesPerPixel = samplesPerPixel; 63 } 64 65 72 public byte[] decode(byte data[], byte uncompData[], int h) { 73 74 if(data[0] == (byte)0x00 && data[1] == (byte)0x01) { 75 throw new UnsupportedOperationException ("TIFF 5.0-style LZW codes are not supported."); 76 } 77 78 initializeStringTable(); 79 80 this.data = data; 81 this.h = h; 82 this.uncompData = uncompData; 83 84 bytePointer = 0; 86 bitPointer = 0; 87 dstIndex = 0; 88 89 90 nextData = 0; 91 nextBits = 0; 92 93 int code, oldCode = 0; 94 byte string[]; 95 96 while ( ((code = getNextCode()) != 257) && 97 dstIndex < uncompData.length) { 98 99 if (code == 256) { 100 101 initializeStringTable(); 102 code = getNextCode(); 103 104 if (code == 257) { 105 break; 106 } 107 108 writeString(stringTable[code]); 109 oldCode = code; 110 111 } else { 112 113 if (code < tableIndex) { 114 115 string = stringTable[code]; 116 117 writeString(string); 118 addStringToTable(stringTable[oldCode], string[0]); 119 oldCode = code; 120 121 } else { 122 123 string = stringTable[oldCode]; 124 string = composeString(string, string[0]); 125 writeString(string); 126 addStringToTable(string); 127 oldCode = code; 128 } 129 130 } 131 132 } 133 134 if (predictor == 2) { 136 137 int count; 138 for (int j = 0; j < h; j++) { 139 140 count = samplesPerPixel * (j * w + 1); 141 142 for (int i = samplesPerPixel; i < w * samplesPerPixel; i++) { 143 144 uncompData[count] += uncompData[count - samplesPerPixel]; 145 count++; 146 } 147 } 148 } 149 150 return uncompData; 151 } 152 153 154 157 public void initializeStringTable() { 158 159 stringTable = new byte[4096][]; 160 161 for (int i=0; i<256; i++) { 162 stringTable[i] = new byte[1]; 163 stringTable[i][0] = (byte)i; 164 } 165 166 tableIndex = 258; 167 bitsToGet = 9; 168 } 169 170 173 public void writeString(byte string[]) { 174 int max = uncompData.length - dstIndex; 176 if (string.length < max) 177 max = string.length; 178 System.arraycopy(string, 0, uncompData, dstIndex, max); 179 dstIndex += max; 180 } 181 182 185 public void addStringToTable(byte oldString[], byte newString) { 186 int length = oldString.length; 187 byte string[] = new byte[length + 1]; 188 System.arraycopy(oldString, 0, string, 0, length); 189 string[length] = newString; 190 191 stringTable[tableIndex++] = string; 193 194 if (tableIndex == 511) { 195 bitsToGet = 10; 196 } else if (tableIndex == 1023) { 197 bitsToGet = 11; 198 } else if (tableIndex == 2047) { 199 bitsToGet = 12; 200 } 201 } 202 203 206 public void addStringToTable(byte string[]) { 207 208 stringTable[tableIndex++] = string; 210 211 if (tableIndex == 511) { 212 bitsToGet = 10; 213 } else if (tableIndex == 1023) { 214 bitsToGet = 11; 215 } else if (tableIndex == 2047) { 216 bitsToGet = 12; 217 } 218 } 219 220 223 public byte[] composeString(byte oldString[], byte newString) { 224 int length = oldString.length; 225 byte string[] = new byte[length + 1]; 226 System.arraycopy(oldString, 0, string, 0, length); 227 string[length] = newString; 228 229 return string; 230 } 231 232 public int getNextCode() { 234 try { 239 nextData = (nextData << 8) | (data[bytePointer++] & 0xff); 240 nextBits += 8; 241 242 if (nextBits < bitsToGet) { 243 nextData = (nextData << 8) | (data[bytePointer++] & 0xff); 244 nextBits += 8; 245 } 246 247 int code = 248 (nextData >> (nextBits - bitsToGet)) & andTable[bitsToGet-9]; 249 nextBits -= bitsToGet; 250 251 return code; 252 } catch(ArrayIndexOutOfBoundsException e) { 253 return 257; 255 } 256 } 257 } 258 | Popular Tags |