001/* 002 * $Id: PRStream.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.ByteArrayOutputStream; 047import java.io.IOException; 048import java.io.OutputStream; 049import java.util.zip.Deflater; 050import java.util.zip.DeflaterOutputStream; 051 052import com.itextpdf.text.Document; 053import com.itextpdf.text.ExceptionConverter; 054 055public class PRStream extends PdfStream { 056 057 protected PdfReader reader; 058 protected int offset; 059 protected int length; 060 061 //added by ujihara for decryption 062 protected int objNum = 0; 063 protected int objGen = 0; 064 065 public PRStream(PRStream stream, PdfDictionary newDic) { 066 reader = stream.reader; 067 offset = stream.offset; 068 length = stream.length; 069 compressed = stream.compressed; 070 compressionLevel = stream.compressionLevel; 071 streamBytes = stream.streamBytes; 072 bytes = stream.bytes; 073 objNum = stream.objNum; 074 objGen = stream.objGen; 075 if (newDic != null) 076 putAll(newDic); 077 else 078 hashMap.putAll(stream.hashMap); 079 } 080 081 public PRStream(PRStream stream, PdfDictionary newDic, PdfReader reader) { 082 this(stream, newDic); 083 this.reader = reader; 084 } 085 086 public PRStream(PdfReader reader, int offset) { 087 this.reader = reader; 088 this.offset = offset; 089 } 090 091 public PRStream(PdfReader reader, byte conts[]) { 092 this(reader, conts, DEFAULT_COMPRESSION); 093 } 094 095 /** 096 * Creates a new PDF stream object that will replace a stream 097 * in a existing PDF file. 098 * @param reader the reader that holds the existing PDF 099 * @param conts the new content 100 * @param compressionLevel the compression level for the content 101 * @since 2.1.3 (replacing the existing constructor without param compressionLevel) 102 */ 103 public PRStream(PdfReader reader, byte[] conts, int compressionLevel) { 104 this.reader = reader; 105 this.offset = -1; 106 if (Document.compress) { 107 try { 108 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 109 Deflater deflater = new Deflater(compressionLevel); 110 DeflaterOutputStream zip = new DeflaterOutputStream(stream, deflater); 111 zip.write(conts); 112 zip.close(); 113 deflater.end(); 114 bytes = stream.toByteArray(); 115 } 116 catch (IOException ioe) { 117 throw new ExceptionConverter(ioe); 118 } 119 put(PdfName.FILTER, PdfName.FLATEDECODE); 120 } 121 else 122 bytes = conts; 123 setLength(bytes.length); 124 } 125 126 /** 127 * Sets the data associated with the stream, either compressed or 128 * uncompressed. Note that the data will never be compressed if 129 * Document.compress is set to false. 130 * 131 * @param data raw data, decrypted and uncompressed. 132 * @param compress true if you want the stream to be compressed. 133 * @since iText 2.1.1 134 */ 135 public void setData(byte[] data, boolean compress) { 136 setData(data, compress, DEFAULT_COMPRESSION); 137 } 138 139 /** 140 * Sets the data associated with the stream, either compressed or 141 * uncompressed. Note that the data will never be compressed if 142 * Document.compress is set to false. 143 * 144 * @param data raw data, decrypted and uncompressed. 145 * @param compress true if you want the stream to be compressed. 146 * @param compressionLevel a value between -1 and 9 (ignored if compress == false) 147 * @since iText 2.1.3 148 */ 149 public void setData(byte[] data, boolean compress, int compressionLevel) { 150 remove(PdfName.FILTER); 151 this.offset = -1; 152 if (Document.compress && compress) { 153 try { 154 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 155 Deflater deflater = new Deflater(compressionLevel); 156 DeflaterOutputStream zip = new DeflaterOutputStream(stream, deflater); 157 zip.write(data); 158 zip.close(); 159 deflater.end(); 160 bytes = stream.toByteArray(); 161 this.compressionLevel = compressionLevel; 162 } 163 catch (IOException ioe) { 164 throw new ExceptionConverter(ioe); 165 } 166 put(PdfName.FILTER, PdfName.FLATEDECODE); 167 } 168 else 169 bytes = data; 170 setLength(bytes.length); 171 } 172 173 /**Sets the data associated with the stream 174 * @param data raw data, decrypted and uncompressed. 175 */ 176 public void setData(byte[] data) { 177 setData(data, true); 178 } 179 180 public void setLength(int length) { 181 this.length = length; 182 put(PdfName.LENGTH, new PdfNumber(length)); 183 } 184 185 public int getOffset() { 186 return offset; 187 } 188 189 public int getLength() { 190 return length; 191 } 192 193 public PdfReader getReader() { 194 return reader; 195 } 196 197 public byte[] getBytes() { 198 return bytes; 199 } 200 201 public void setObjNum(int objNum, int objGen) { 202 this.objNum = objNum; 203 this.objGen = objGen; 204 } 205 206 int getObjNum() { 207 return objNum; 208 } 209 210 int getObjGen() { 211 return objGen; 212 } 213 214 public void toPdf(PdfWriter writer, OutputStream os) throws IOException { 215 byte[] b = PdfReader.getStreamBytesRaw(this); 216 PdfEncryption crypto = null; 217 if (writer != null) 218 crypto = writer.getEncryption(); 219 PdfObject objLen = get(PdfName.LENGTH); 220 int nn = b.length; 221 if (crypto != null) 222 nn = crypto.calculateStreamSize(nn); 223 put(PdfName.LENGTH, new PdfNumber(nn)); 224 superToPdf(writer, os); 225 put(PdfName.LENGTH, objLen); 226 os.write(STARTSTREAM); 227 if (length > 0) { 228 if (crypto != null && !crypto.isEmbeddedFilesOnly()) 229 b = crypto.encryptByteArray(b); 230 os.write(b); 231 } 232 os.write(ENDSTREAM); 233 } 234}