1 /*
2 * $Id: PRStream.java 3633 2008-12-23 18:42:06Z xlv $
3 *
4 * Copyright 2001, 2002 by Paulo Soares.
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * (the "License"); you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the License.
13 *
14 * The Original Code is 'iText, a free JAVA-PDF library'.
15 *
16 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
18 * All Rights Reserved.
19 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
21 *
22 * Contributor(s): all the names of the contributors are added in the source code
23 * where applicable.
24 *
25 * Alternatively, the contents of this file may be used under the terms of the
26 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27 * provisions of LGPL are applicable instead of those above. If you wish to
28 * allow use of your version of this file only under the terms of the LGPL
29 * License and not to allow others to use your version of this file under
30 * the MPL, indicate your decision by deleting the provisions above and
31 * replace them with the notice and other provisions required by the LGPL.
32 * If you do not delete the provisions above, a recipient may use your version
33 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34 *
35 * This library is free software; you can redistribute it and/or modify it
36 * under the terms of the MPL as stated above or under the terms of the GNU
37 * Library General Public License as published by the Free Software Foundation;
38 * either version 2 of the License, or any later version.
39 *
40 * This library is distributed in the hope that it will be useful, but WITHOUT
41 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43 * details.
44 *
45 * If you didn't download this code from the following link, you should check if
46 * you aren't using an obsolete version:
47 * http://www.lowagie.com/iText/
48 */
49
50 package com.lowagie.text.pdf;
51
52 import java.io.ByteArrayOutputStream;
53 import java.io.IOException;
54 import java.io.OutputStream;
55 import java.util.zip.Deflater;
56 import java.util.zip.DeflaterOutputStream;
57
58 import com.lowagie.text.Document;
59 import com.lowagie.text.ExceptionConverter;
60
61 public class PRStream extends PdfStream {
62
63 protected PdfReader reader;
64 protected int offset;
65 protected int length;
66
67 //added by ujihara for decryption
68 protected int objNum = 0;
69 protected int objGen = 0;
70
71 public PRStream(PRStream stream, PdfDictionary newDic) {
72 reader = stream.reader;
73 offset = stream.offset;
74 length = stream.length;
75 compressed = stream.compressed;
76 compressionLevel = stream.compressionLevel;
77 streamBytes = stream.streamBytes;
78 bytes = stream.bytes;
79 objNum = stream.objNum;
80 objGen = stream.objGen;
81 if (newDic != null)
82 putAll(newDic);
83 else
84 hashMap.putAll(stream.hashMap);
85 }
86
87 public PRStream(PRStream stream, PdfDictionary newDic, PdfReader reader) {
88 this(stream, newDic);
89 this.reader = reader;
90 }
91
92 public PRStream(PdfReader reader, int offset) {
93 this.reader = reader;
94 this.offset = offset;
95 }
96
97 public PRStream(PdfReader reader, byte conts[]) {
98 this(reader, conts, DEFAULT_COMPRESSION);
99 }
100
101 /**
102 * Creates a new PDF stream object that will replace a stream
103 * in a existing PDF file.
104 * @param reader the reader that holds the existing PDF
105 * @param conts the new content
106 * @param compressionLevel the compression level for the content
107 * @since 2.1.3 (replacing the existing constructor without param compressionLevel)
108 */
109 public PRStream(PdfReader reader, byte[] conts, int compressionLevel) {
110 this.reader = reader;
111 this.offset = -1;
112 if (Document.compress) {
113 try {
114 ByteArrayOutputStream stream = new ByteArrayOutputStream();
115 Deflater deflater = new Deflater(compressionLevel);
116 DeflaterOutputStream zip = new DeflaterOutputStream(stream, deflater);
117 zip.write(conts);
118 zip.close();
119 deflater.end();
120 bytes = stream.toByteArray();
121 }
122 catch (IOException ioe) {
123 throw new ExceptionConverter(ioe);
124 }
125 put(PdfName.FILTER, PdfName.FLATEDECODE);
126 }
127 else
128 bytes = conts;
129 setLength(bytes.length);
130 }
131
132 /**
133 * Sets the data associated with the stream, either compressed or
134 * uncompressed. Note that the data will never be compressed if
135 * Document.compress is set to false.
136 *
137 * @param data raw data, decrypted and uncompressed.
138 * @param compress true if you want the stream to be compressed.
139 * @since iText 2.1.1
140 */
141 public void setData(byte[] data, boolean compress) {
142 setData(data, compress, DEFAULT_COMPRESSION);
143 }
144
145 /**
146 * Sets the data associated with the stream, either compressed or
147 * uncompressed. Note that the data will never be compressed if
148 * Document.compress is set to false.
149 *
150 * @param data raw data, decrypted and uncompressed.
151 * @param compress true if you want the stream to be compressed.
152 * @param compressionLevel a value between -1 and 9 (ignored if compress == false)
153 * @since iText 2.1.3
154 */
155 public void setData(byte[] data, boolean compress, int compressionLevel) {
156 remove(PdfName.FILTER);
157 this.offset = -1;
158 if (Document.compress && compress) {
159 try {
160 ByteArrayOutputStream stream = new ByteArrayOutputStream();
161 Deflater deflater = new Deflater(compressionLevel);
162 DeflaterOutputStream zip = new DeflaterOutputStream(stream, deflater);
163 zip.write(data);
164 zip.close();
165 deflater.end();
166 bytes = stream.toByteArray();
167 this.compressionLevel = compressionLevel;
168 }
169 catch (IOException ioe) {
170 throw new ExceptionConverter(ioe);
171 }
172 put(PdfName.FILTER, PdfName.FLATEDECODE);
173 }
174 else
175 bytes = data;
176 setLength(bytes.length);
177 }
178
179 /**Sets the data associated with the stream
180 * @param data raw data, decrypted and uncompressed.
181 */
182 public void setData(byte[] data) {
183 setData(data, true);
184 }
185
186 public void setLength(int length) {
187 this.length = length;
188 put(PdfName.LENGTH, new PdfNumber(length));
189 }
190
191 public int getOffset() {
192 return offset;
193 }
194
195 public int getLength() {
196 return length;
197 }
198
199 public PdfReader getReader() {
200 return reader;
201 }
202
203 public byte[] getBytes() {
204 return bytes;
205 }
206
207 public void setObjNum(int objNum, int objGen) {
208 this.objNum = objNum;
209 this.objGen = objGen;
210 }
211
212 int getObjNum() {
213 return objNum;
214 }
215
216 int getObjGen() {
217 return objGen;
218 }
219
220 public void toPdf(PdfWriter writer, OutputStream os) throws IOException {
221 byte[] b = PdfReader.getStreamBytesRaw(this);
222 PdfEncryption crypto = null;
223 if (writer != null)
224 crypto = writer.getEncryption();
225 PdfObject objLen = get(PdfName.LENGTH);
226 int nn = b.length;
227 if (crypto != null)
228 nn = crypto.calculateStreamSize(nn);
229 put(PdfName.LENGTH, new PdfNumber(nn));
230 superToPdf(writer, os);
231 put(PdfName.LENGTH, objLen);
232 os.write(STARTSTREAM);
233 if (length > 0) {
234 if (crypto != null && !crypto.isEmbeddedFilesOnly())
235 b = crypto.encryptByteArray(b);
236 os.write(b);
237 }
238 os.write(ENDSTREAM);
239 }
240 }