1 31 package org.pdfbox.cos; 32 33 import java.io.BufferedInputStream ; 34 import java.io.BufferedOutputStream ; 35 import java.io.ByteArrayInputStream ; 36 import java.io.InputStream ; 37 import java.io.IOException ; 38 import java.io.OutputStream ; 39 40 import java.util.List ; 41 42 import org.pdfbox.filter.Filter; 43 import org.pdfbox.filter.FilterManager; 44 45 import org.pdfbox.pdfparser.PDFStreamParser; 46 47 import org.pdfbox.exceptions.COSVisitorException; 48 49 import org.pdfbox.io.RandomAccess; 50 import org.pdfbox.io.RandomAccessFileInputStream; 51 import org.pdfbox.io.RandomAccessFileOutputStream; 52 53 59 public class COSStream extends COSDictionary 60 { 61 private static final int BUFFER_SIZE=16384; 62 63 private RandomAccess file; 64 67 private RandomAccessFileOutputStream filteredStream; 68 69 72 private RandomAccessFileOutputStream unFilteredStream; 73 74 79 public COSStream( RandomAccess storage ) 80 { 81 super(); 82 file = storage; 83 } 84 85 91 public COSStream( COSDictionary dictionary, RandomAccess storage ) 92 { 93 super( dictionary ); 94 file = storage; 95 } 96 97 104 public void replaceWithStream( COSStream stream ) 105 { 106 this.clear(); 107 this.addAll( stream ); 108 file = stream.file; 109 filteredStream = stream.filteredStream; 110 unFilteredStream = stream.unFilteredStream; 111 } 112 113 118 public RandomAccess getScratchFile() 119 { 120 return file; 121 } 122 123 130 public List getStreamTokens() throws IOException 131 { 132 PDFStreamParser parser = new PDFStreamParser( this ); 133 parser.parse(); 134 return parser.getTokens(); 135 } 136 137 144 public InputStream getFilteredStream() throws IOException 145 { 146 if( filteredStream == null ) 147 { 148 doEncode(); 149 } 150 long position = filteredStream.getPosition(); 151 long length = filteredStream.getLength(); 152 153 RandomAccessFileInputStream input = 154 new RandomAccessFileInputStream( file, position, length ); 155 return new BufferedInputStream ( input, BUFFER_SIZE ); 156 } 157 158 165 public InputStream getUnfilteredStream() throws IOException 166 { 167 InputStream retval = null; 168 if( unFilteredStream == null ) 169 { 170 doDecode(); 171 } 172 173 if( unFilteredStream != null ) 176 { 177 long position = unFilteredStream.getPosition(); 178 long length = unFilteredStream.getLength(); 179 RandomAccessFileInputStream input = 180 new RandomAccessFileInputStream( file, position, length ); 181 retval = new BufferedInputStream ( input, BUFFER_SIZE ); 182 } 183 else 184 { 185 retval = new ByteArrayInputStream ( new byte[0] ); 201 } 203 return retval; 204 } 205 206 213 public Object accept(ICOSVisitor visitor) throws COSVisitorException 214 { 215 return visitor.visitFromStream(this); 216 } 217 218 223 private void doDecode() throws IOException 224 { 225 unFilteredStream = filteredStream; 227 228 COSBase filters = getFilters(); 229 if( filters == null ) 230 { 231 } 233 else if( filters instanceof COSName ) 234 { 235 doDecode( (COSName)filters ); 236 } 237 else if( filters instanceof COSArray ) 238 { 239 COSArray filterArray = (COSArray)filters; 240 for( int i=0; i<filterArray.size(); i++ ) 241 { 242 COSName filterName = (COSName)filterArray.get( i ); 243 doDecode( filterName ); 244 } 245 } 246 else 247 { 248 throw new IOException ( "Error: Unknown filter type:" + filters ); 249 } 250 } 251 252 259 private void doDecode( COSName filterName ) throws IOException 260 { 261 FilterManager manager = getFilterManager(); 262 Filter filter = manager.getFilter( filterName ); 263 InputStream input; 264 265 boolean done = false; 266 IOException exception = null; 267 long position = unFilteredStream.getPosition(); 268 long length = unFilteredStream.getLength(); 269 270 if( length == 0 ) 271 { 272 unFilteredStream = new RandomAccessFileOutputStream( file ); 276 done = true; 277 } 278 else 279 { 280 for( int tryCount=0; !done && tryCount<5; tryCount++ ) 284 { 285 try 286 { 287 input = new BufferedInputStream ( 288 new RandomAccessFileInputStream( file, position, length ), BUFFER_SIZE ); 289 unFilteredStream = new RandomAccessFileOutputStream( file ); 290 filter.decode( input, unFilteredStream, this ); 291 done = true; 292 } 293 catch( IOException io ) 294 { 295 length--; 296 exception = io; 297 } 298 } 299 } 300 if( !done ) 301 { 302 throw exception; 303 } 304 } 305 306 311 private void doEncode() throws IOException 312 { 313 filteredStream = unFilteredStream; 314 315 COSBase filters = getFilters(); 316 if( filters == null ) 317 { 318 } 320 else if( filters instanceof COSName ) 321 { 322 doEncode( (COSName)filters ); 323 } 324 else if( filters instanceof COSArray ) 325 { 326 COSArray filterArray = (COSArray)filters; 328 for( int i=filterArray.size()-1; i>=0; i-- ) 329 { 330 COSName filterName = (COSName)filterArray.get( i ); 331 doEncode( filterName ); 332 } 333 } 334 } 335 336 343 private void doEncode( COSName filterName ) throws IOException 344 { 345 FilterManager manager = getFilterManager(); 346 Filter filter = manager.getFilter( filterName ); 347 InputStream input; 348 349 input = new BufferedInputStream ( 350 new RandomAccessFileInputStream( file, filteredStream.getPosition(), 351 filteredStream.getLength() ), BUFFER_SIZE ); 352 filteredStream = new RandomAccessFileOutputStream( file ); 353 filter.encode( input, filteredStream, this ); 354 } 355 356 365 public COSBase getFilters() 366 { 367 return getDictionaryObject(COSName.FILTER); 368 } 369 370 379 public OutputStream createFilteredStream() throws IOException 380 { 381 filteredStream = new RandomAccessFileOutputStream( file ); 382 unFilteredStream = null; 383 return new BufferedOutputStream ( filteredStream, BUFFER_SIZE ); 384 } 385 386 397 public OutputStream createFilteredStream( COSBase expectedLength ) throws IOException 398 { 399 filteredStream = new RandomAccessFileOutputStream( file ); 400 filteredStream.setExpectedLength( expectedLength ); 401 unFilteredStream = null; 402 return new BufferedOutputStream ( filteredStream, BUFFER_SIZE ); 403 } 404 405 412 public void setFilters(COSBase filters) throws IOException 413 { 414 setItem(COSName.FILTER, filters); 415 filteredStream = null; 417 } 418 419 426 public OutputStream createUnfilteredStream() throws IOException 427 { 428 unFilteredStream = new RandomAccessFileOutputStream( file ); 429 filteredStream = null; 430 return new BufferedOutputStream ( unFilteredStream, BUFFER_SIZE ); 431 } 432 } | Popular Tags |