1 50 51 package com.lowagie.text.pdf; 52 53 import java.io.ByteArrayOutputStream ; 54 import java.io.IOException ; 55 import java.io.InputStream ; 56 import java.io.OutputStream ; 57 import java.util.zip.Deflater ; 58 import java.util.zip.DeflaterOutputStream ; 59 60 import com.lowagie.text.DocWriter; 61 import com.lowagie.text.Document; 62 import com.lowagie.text.ExceptionConverter; 63 import java.util.ArrayList ; 64 65 85 86 public class PdfStream extends PdfDictionary { 87 88 90 91 protected boolean compressed = false; 92 93 protected ByteArrayOutputStream streamBytes = null; 94 protected InputStream inputStream; 95 protected PdfIndirectReference ref; 96 protected int inputStreamLength = -1; 97 protected PdfWriter writer; 98 protected int rawLength; 99 100 static final byte STARTSTREAM[] = DocWriter.getISOBytes("stream\n"); 101 static final byte ENDSTREAM[] = DocWriter.getISOBytes("\nendstream"); 102 static final int SIZESTREAM = STARTSTREAM.length + ENDSTREAM.length; 103 104 106 111 112 public PdfStream(byte[] bytes) { 113 super(); 114 type = STREAM; 115 this.bytes = bytes; 116 rawLength = bytes.length; 117 put(PdfName.LENGTH, new PdfNumber(bytes.length)); 118 } 119 120 135 public PdfStream(InputStream inputStream, PdfWriter writer) { 136 super(); 137 type = STREAM; 138 this.inputStream = inputStream; 139 this.writer = writer; 140 ref = writer.getPdfIndirectReference(); 141 put(PdfName.LENGTH, ref); 142 } 143 144 147 148 protected PdfStream() { 149 super(); 150 type = STREAM; 151 } 152 153 161 public void writeLength() throws IOException { 162 if (inputStream == null) 163 throw new UnsupportedOperationException ("writeLength() can only be called in a contructed PdfStream(InputStream,PdfWriter)."); 164 if (inputStreamLength == -1) 165 throw new IOException ("writeLength() can only be called after output of the stream body."); 166 writer.addToBody(new PdfNumber(inputStreamLength), ref, false); 167 } 168 169 173 public int getRawLength() { 174 return rawLength; 175 } 176 177 180 181 public void flateCompress() { 182 if (!Document.compress) 183 return; 184 if (compressed) { 186 return; 187 } 188 if (inputStream != null) { 189 compressed = true; 190 return; 191 } 192 PdfObject filter = PdfReader.getPdfObject(get(PdfName.FILTER)); 194 if (filter != null) { 195 if (filter.isName()) { 196 if (PdfName.FLATEDECODE.equals(filter)) 197 return; 198 } 199 else if (filter.isArray()) { 200 if (((PdfArray) filter).contains(PdfName.FLATEDECODE)) 201 return; 202 } 203 else { 204 throw new RuntimeException ("Stream could not be compressed: filter is not a name or array."); 205 } 206 } 207 try { 208 ByteArrayOutputStream stream = new ByteArrayOutputStream (); 210 DeflaterOutputStream zip = new DeflaterOutputStream (stream); 211 if (streamBytes != null) 212 streamBytes.writeTo(zip); 213 else 214 zip.write(bytes); 215 zip.close(); 216 streamBytes = stream; 218 bytes = null; 219 put(PdfName.LENGTH, new PdfNumber(streamBytes.size())); 220 if (filter == null) { 221 put(PdfName.FILTER, PdfName.FLATEDECODE); 222 } 223 else { 224 PdfArray filters = new PdfArray(filter); 225 filters.add(PdfName.FLATEDECODE); 226 put(PdfName.FILTER, filters); 227 } 228 compressed = true; 229 } 230 catch(IOException ioe) { 231 throw new ExceptionConverter(ioe); 232 } 233 } 234 235 244 protected void superToPdf(PdfWriter writer, OutputStream os) throws IOException { 245 super.toPdf(writer, os); 246 } 247 248 251 public void toPdf(PdfWriter writer, OutputStream os) throws IOException { 252 if (inputStream != null && compressed) 253 put(PdfName.FILTER, PdfName.FLATEDECODE); 254 PdfEncryption crypto = null; 255 if (writer != null) 256 crypto = writer.getEncryption(); 257 if (crypto != null) { 258 PdfObject filter = get(PdfName.FILTER); 259 if (filter != null) { 260 if (PdfName.CRYPT.equals(filter)) 261 crypto = null; 262 else if (filter.isArray()) { 263 ArrayList af = ((PdfArray)filter).getArrayList(); 264 if (!af.isEmpty() && PdfName.CRYPT.equals(af.get(0))) 265 crypto = null; 266 } 267 } 268 } 269 PdfObject nn = get(PdfName.LENGTH); 270 if (crypto != null && nn != null && nn.isNumber()) { 271 int sz = ((PdfNumber)nn).intValue(); 272 put(PdfName.LENGTH, new PdfNumber(crypto.calculateStreamSize(sz))); 273 superToPdf(writer, os); 274 put(PdfName.LENGTH, nn); 275 } 276 else 277 superToPdf(writer, os); 278 os.write(STARTSTREAM); 279 if (inputStream != null) { 280 rawLength = 0; 281 DeflaterOutputStream def = null; 282 OutputStreamCounter osc = new OutputStreamCounter(os); 283 OutputStreamEncryption ose = null; 284 OutputStream fout = osc; 285 if (crypto != null) 286 fout = ose = crypto.getEncryptionStream(fout); 287 if (compressed) 288 fout = def = new DeflaterOutputStream (fout, new Deflater (Deflater.BEST_COMPRESSION), 0x8000); 289 290 byte buf[] = new byte[4192]; 291 while (true) { 292 int n = inputStream.read(buf); 293 if (n <= 0) 294 break; 295 fout.write(buf, 0, n); 296 rawLength += n; 297 } 298 if (def != null) 299 def.finish(); 300 if (ose != null) 301 ose.finish(); 302 inputStreamLength = osc.getCounter(); 303 } 304 else { 305 if (crypto == null) { 306 if (streamBytes != null) 307 streamBytes.writeTo(os); 308 else 309 os.write(bytes); 310 } 311 else { 312 byte b[]; 313 if (streamBytes != null) { 314 b = crypto.encryptByteArray(streamBytes.toByteArray()); 315 } 316 else { 317 b = crypto.encryptByteArray(bytes); 318 } 319 os.write(b); 320 } 321 } 322 os.write(ENDSTREAM); 323 } 324 325 330 public void writeContent(OutputStream os) throws IOException { 331 if (streamBytes != null) 332 streamBytes.writeTo(os); 333 else if (bytes != null) 334 os.write(bytes); 335 } 336 } 337 | Popular Tags |