1 31 package org.pdfbox.filter; 32 33 import java.io.ByteArrayOutputStream ; 34 import java.io.IOException ; 35 import java.io.InputStream ; 36 import java.io.OutputStream ; 37 import java.io.PushbackInputStream ; 38 import java.io.StreamCorruptedException ; 39 40 import org.pdfbox.cos.COSDictionary; 41 42 import org.pdfbox.io.NBitInputStream; 43 import org.pdfbox.io.NBitOutputStream; 44 45 51 public class LZWFilter implements Filter 52 { 53 54 57 public static final long CLEAR_TABLE = 256; 58 61 public static final long EOD = 257; 62 63 72 public void decode( InputStream compressedData, OutputStream result, COSDictionary options ) throws IOException 73 { 74 NBitInputStream in = null; 76 in = new NBitInputStream( compressedData ); 77 in.setBitsInChunk( 9 ); 78 LZWDictionary dic = new LZWDictionary(); 79 byte firstByte = 0; 80 long nextCommand = 0; 81 while( (nextCommand = in.read() ) != EOD ) 82 { 83 85 if( nextCommand == CLEAR_TABLE ) 86 { 87 in.setBitsInChunk( 9 ); 88 dic = new LZWDictionary(); 89 } 90 else 91 { 92 byte[] data = dic.getData( nextCommand ); 93 if( data == null ) 94 { 95 dic.visit( firstByte ); 96 data = dic.getData( nextCommand ); 97 dic.clear(); 98 } 99 if( data == null ) 100 { 101 throw new StreamCorruptedException ( "Error: data is null" ); 102 } 103 dic.visit(data); 104 105 107 if( dic.getNextCode() >= 2047 ) 108 { 109 in.setBitsInChunk( 12 ); 110 } 111 else if( dic.getNextCode() >= 1023 ) 112 { 113 in.setBitsInChunk( 11 ); 114 } 115 else if( dic.getNextCode() >= 511 ) 116 { 117 in.setBitsInChunk( 10 ); 118 } 119 else 120 { 121 in.setBitsInChunk( 9 ); 122 } 123 133 firstByte = data[0]; 134 result.write( data ); 135 } 136 } 137 result.flush(); 138 } 139 140 141 150 public void encode( InputStream rawData, OutputStream result, COSDictionary options ) throws IOException 151 { 152 PushbackInputStream input = new PushbackInputStream ( rawData, 4096 ); 154 LZWDictionary dic = new LZWDictionary(); 155 NBitOutputStream out = new NBitOutputStream( result ); 156 out.setBitsInChunk( 9 ); out.write( CLEAR_TABLE ); 158 ByteArrayOutputStream buffer = new ByteArrayOutputStream (); 159 int byteRead = 0; 160 for( int i=0; (byteRead = input.read()) != -1; i++ ) 161 { 162 buffer.write( byteRead ); 164 dic.visit( (byte)byteRead ); 165 out.setBitsInChunk( dic.getCodeSize() ); 166 167 LZWNode node = dic.getNode( buffer.toByteArray() ); 169 int nextByte = input.read(); 170 if( nextByte != -1 ) 171 { 172 LZWNode next = node.getNode( (byte)nextByte ); 174 if( next == null ) 175 { 176 out.write( node.getCode() ); 181 buffer.reset(); 182 } 183 184 input.unread( nextByte ); 185 } 186 else 187 { 188 out.write( node.getCode() ); 193 buffer.reset(); 194 break; 195 } 196 197 if( dic.getNextCode() == 4096 ) 198 { 199 out.write( CLEAR_TABLE ); 203 dic = new LZWDictionary(); 204 input.unread( buffer.toByteArray() ); 205 buffer.reset(); 206 } 207 } 208 209 if( dic.getNextCode() >= 2047 ) 212 { 213 out.setBitsInChunk( 12 ); 214 } 215 else if( dic.getNextCode() >= 1023 ) 216 { 217 out.setBitsInChunk( 11 ); 218 } 219 else if( dic.getNextCode() >= 511 ) 220 { 221 out.setBitsInChunk( 10 ); 222 } 223 else 224 { 225 out.setBitsInChunk( 9 ); 226 } 227 228 out.write( EOD ); 232 out.close(); 233 result.flush(); 234 } 235 } | Popular Tags |