001/* 002 * $Id: PdfEFStream.java 4784 2011-03-15 08:33:00Z blowagie $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text.pdf; 045 046import java.io.IOException; 047import java.io.InputStream; 048import java.io.OutputStream; 049import java.util.zip.Deflater; 050import java.util.zip.DeflaterOutputStream; 051 052/** 053 * Extends PdfStream and should be used to create Streams for Embedded Files 054 * (file attachments). 055 * @since 2.1.3 056 */ 057 058public class PdfEFStream extends PdfStream { 059 060 /** 061 * Creates a Stream object using an InputStream and a PdfWriter object 062 * @param in the InputStream that will be read to get the Stream object 063 * @param writer the writer to which the stream will be added 064 */ 065 public PdfEFStream(InputStream in, PdfWriter writer) { 066 super(in, writer); 067 } 068 069 /** 070 * Creates a Stream object using a byte array 071 * @param fileStore the bytes for the stream 072 */ 073 public PdfEFStream(byte[] fileStore) { 074 super(fileStore); 075 } 076 077 /** 078 * @see com.itextpdf.text.pdf.PdfDictionary#toPdf(com.itextpdf.text.pdf.PdfWriter, java.io.OutputStream) 079 */ 080 public void toPdf(PdfWriter writer, OutputStream os) throws IOException { 081 if (inputStream != null && compressed) 082 put(PdfName.FILTER, PdfName.FLATEDECODE); 083 PdfEncryption crypto = null; 084 if (writer != null) 085 crypto = writer.getEncryption(); 086 if (crypto != null) { 087 PdfObject filter = get(PdfName.FILTER); 088 if (filter != null) { 089 if (PdfName.CRYPT.equals(filter)) 090 crypto = null; 091 else if (filter.isArray()) { 092 PdfArray a = (PdfArray)filter; 093 if (!a.isEmpty() && PdfName.CRYPT.equals(a.getPdfObject(0))) 094 crypto = null; 095 } 096 } 097 } 098 if (crypto != null && crypto.isEmbeddedFilesOnly()) { 099 PdfArray filter = new PdfArray(); 100 PdfArray decodeparms = new PdfArray(); 101 PdfDictionary crypt = new PdfDictionary(); 102 crypt.put(PdfName.NAME, PdfName.STDCF); 103 filter.add(PdfName.CRYPT); 104 decodeparms.add(crypt); 105 if (compressed) { 106 filter.add(PdfName.FLATEDECODE); 107 decodeparms.add(new PdfNull()); 108 } 109 put(PdfName.FILTER, filter); 110 put(PdfName.DECODEPARMS, decodeparms); 111 } 112 PdfObject nn = get(PdfName.LENGTH); 113 if (crypto != null && nn != null && nn.isNumber()) { 114 int sz = ((PdfNumber)nn).intValue(); 115 put(PdfName.LENGTH, new PdfNumber(crypto.calculateStreamSize(sz))); 116 superToPdf(writer, os); 117 put(PdfName.LENGTH, nn); 118 } 119 else 120 superToPdf(writer, os); 121 122 os.write(STARTSTREAM); 123 if (inputStream != null) { 124 rawLength = 0; 125 DeflaterOutputStream def = null; 126 OutputStreamCounter osc = new OutputStreamCounter(os); 127 OutputStreamEncryption ose = null; 128 OutputStream fout = osc; 129 if (crypto != null) 130 fout = ose = crypto.getEncryptionStream(fout); 131 Deflater deflater = null; 132 if (compressed) { 133 deflater = new Deflater(compressionLevel); 134 fout = def = new DeflaterOutputStream(fout, deflater, 0x8000); 135 } 136 137 byte buf[] = new byte[4192]; 138 while (true) { 139 int n = inputStream.read(buf); 140 if (n <= 0) 141 break; 142 fout.write(buf, 0, n); 143 rawLength += n; 144 } 145 if (def != null) { 146 def.finish(); 147 deflater.end(); 148 } 149 if (ose != null) 150 ose.finish(); 151 inputStreamLength = osc.getCounter(); 152 } 153 else { 154 if (crypto == null) { 155 if (streamBytes != null) 156 streamBytes.writeTo(os); 157 else 158 os.write(bytes); 159 } 160 else { 161 byte b[]; 162 if (streamBytes != null) { 163 b = crypto.encryptByteArray(streamBytes.toByteArray()); 164 } 165 else { 166 b = crypto.encryptByteArray(bytes); 167 } 168 os.write(b); 169 } 170 } 171 os.write(ENDSTREAM); 172 } 173}