KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > pdf > PDFStream


1 /*
2  * $Id: PDFStream.java,v 1.10.2.4 2003/02/25 14:29:38 jeremias Exp $
3  * ============================================================================
4  * The Apache Software License, Version 1.1
5  * ============================================================================
6  *
7  * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without modifica-
10  * tion, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if any, must
20  * include the following acknowledgment: "This product includes software
21  * developed by the Apache Software Foundation (http://www.apache.org/)."
22  * Alternately, this acknowledgment may appear in the software itself, if
23  * and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. The names "FOP" and "Apache Software Foundation" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * apache@apache.org.
29  *
30  * 5. Products derived from this software may not be called "Apache", nor may
31  * "Apache" appear in their name, without prior written permission of the
32  * Apache Software Foundation.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37  * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39  * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44  * ============================================================================
45  *
46  * This software consists of voluntary contributions made by many individuals
47  * on behalf of the Apache Software Foundation and was originally created by
48  * James Tauber <jtauber@jtauber.com>. For more information on the Apache
49  * Software Foundation, please see <http://www.apache.org/>.
50  */

51 package org.apache.fop.pdf;
52
53 // Fop
54
import org.apache.fop.configuration.Configuration;
55 import org.apache.fop.messaging.MessageHandler;
56
57 // Java
58
import java.io.ByteArrayOutputStream JavaDoc;
59 import java.io.OutputStream JavaDoc;
60 import java.io.IOException JavaDoc;
61 import java.io.UnsupportedEncodingException JavaDoc;
62 import java.util.List JavaDoc;
63
64 /**
65  * class representing a PDF stream.
66  *
67  * A derivative of the PDF Object, a PDF Stream has not only a dictionary
68  * but a stream of PDF commands. The stream of commands is where the real
69  * work is done, the dictionary just provides information like the stream
70  * length.
71  */

72 public class PDFStream extends PDFObject {
73
74     /**
75      * the stream of PDF commands
76      */

77     protected ByteArrayOutputStream JavaDoc _data;
78
79     /**
80      * the filters that should be applied
81      */

82     private List JavaDoc _filters;
83
84     /**
85      * create an empty stream object
86      *
87      * @param number the object's number
88      */

89     public PDFStream(int number) {
90         super(number);
91         _data = new ByteArrayOutputStream JavaDoc();
92         _filters = new java.util.ArrayList JavaDoc();
93     }
94
95     /**
96      * append data to the stream
97      *
98      * @param s the string of PDF to add
99      */

100     public void add(String JavaDoc s) {
101         try {
102             try {
103                 _data.write(s.getBytes(PDFDocument.ENCODING));
104             } catch (UnsupportedEncodingException JavaDoc ue) {
105                 _data.write(s.getBytes());
106             }
107         } catch (IOException JavaDoc ex) {
108             ex.printStackTrace();
109         }
110
111     }
112
113     /**
114      * Add a filter for compression of the stream. Filters are
115      * applied in the order they are added. This should always be a
116      * new instance of the particular filter of choice. The applied
117      * flag in the filter is marked true after it has been applied to the
118      * data.
119      */

120     public void addFilter(PDFFilter filter) {
121         if (filter != null) {
122             _filters.add(filter);
123         }
124
125     }
126
127     public void addFilter(String JavaDoc filterType) {
128         if (filterType == null) {
129             return;
130         }
131         if (filterType.equals("flate")) {
132             addFilter(new FlateFilter());
133         } else if (filterType.equals("ascii-85")) {
134             addFilter(new ASCII85Filter());
135         } else if (filterType.equals("ascii-hex")) {
136             addFilter(new ASCIIHexFilter());
137         } else if (filterType.equals("")) {
138             return;
139         } else {
140             MessageHandler.errorln("Unsupported filter type in stream-filter-list: "
141                                    + filterType);
142         }
143     }
144
145
146     protected void addDefaultFilters() {
147         List JavaDoc filters = Configuration.getListValue("stream-filter-list",
148                                                     Configuration.PDF);
149         if (filters == null) {
150             // try getting it as a String
151
String JavaDoc filter = Configuration.getStringValue("stream-filter-list",
152                     Configuration.PDF);
153             if (filter == null) {
154                 // built-in default to flate
155
addFilter(new FlateFilter());
156             } else {
157                 addFilter(filter);
158             }
159         } else {
160             for (int i = 0; i < filters.size(); i++) {
161                 String JavaDoc v = (String JavaDoc)filters.get(i);
162                 addFilter(v);
163             }
164         }
165     }
166
167
168     /**
169      * append an array of xRGB pixels, ASCII Hex Encoding it first
170      *
171      * @param pixels the area of pixels
172      * @param width the width of the image in pixels
173      * @param height the height of the image in pixels
174      */

175     public void addImageArray(int[] pixels, int width, int height) {
176         try {
177             for (int i = 0; i < height; i++) {
178                 for (int j = 0; j < width; j++) {
179                     int p = pixels[i * width + j];
180                     int r = (p >> 16) & 0xFF;
181                     int g = (p >> 8) & 0xFF;
182                     int b = (p) & 0xFF;
183                     if (r < 16) {
184                         _data.write('0');
185                     }
186                     try {
187                         _data.write(Integer.toHexString(r).getBytes(PDFDocument.ENCODING));
188                     } catch (UnsupportedEncodingException JavaDoc ue) {
189                         _data.write(Integer.toHexString(r).getBytes());
190                     }
191                     if (g < 16) {
192                         _data.write('0');
193                     }
194                     try {
195                         _data.write(Integer.toHexString(g).getBytes(PDFDocument.ENCODING));
196                     } catch (UnsupportedEncodingException JavaDoc ue) {
197                         _data.write(Integer.toHexString(g).getBytes());
198                     }
199                     if (b < 16) {
200                         _data.write('0');
201                     }
202                     try {
203                         _data.write(Integer.toHexString(b).getBytes(PDFDocument.ENCODING));
204                     } catch (UnsupportedEncodingException JavaDoc ue) {
205                         _data.write(Integer.toHexString(b).getBytes());
206                     }
207                     _data.write(' ');
208                 }
209             }
210             try {
211                 _data.write(">\n".getBytes(PDFDocument.ENCODING));
212             } catch (UnsupportedEncodingException JavaDoc ue) {
213                 _data.write(">\n".getBytes());
214             }
215         } catch (IOException JavaDoc ex) {
216             ex.printStackTrace();
217         }
218
219     }
220
221     public void setData(byte[] data) throws IOException JavaDoc {
222         _data.reset();
223         _data.write(data);
224     }
225
226     public byte[] getData() {
227         return _data.toByteArray();
228     }
229
230     public int getDataLength() {
231         return _data.size();
232     }
233
234
235
236     /**
237      * represent as PDF.
238      *
239      * @return the PDF string.
240      */

241     /*
242      * public byte[] toPDF() {
243      * byte[] d = _data.toByteArray();
244      * ByteArrayOutputStream s = new ByteArrayOutputStream();
245      * String p = this.number + " " + this.generation
246      * + " obj\n<< /Length " + (d.length+1)
247      * + " >>\nstream\n";
248      * s.write(p.getBytes());
249      * s.write(d);
250      * s.write("\nendstream\nendobj\n".getBytes());
251      * return s.toByteArray();
252      * }
253      */

254     public byte[] toPDF() {
255         throw new RuntimeException JavaDoc();
256     }
257
258
259     // overload the base object method so we don't have to copy
260
// byte arrays around so much
261
protected int output(OutputStream JavaDoc stream) throws IOException JavaDoc {
262         int length = 0;
263         String JavaDoc filterEntry = applyFilters();
264         String JavaDoc s = this.number + " " + this.generation + " obj\n<< /Length "
265                     + (_data.size() + 1) + " " + filterEntry
266                     + " >>\n";
267         byte[] p;
268         try {
269             p = s.getBytes(PDFDocument.ENCODING);
270         } catch (UnsupportedEncodingException JavaDoc ue) {
271             p = s.getBytes();
272         }
273         stream.write(p);
274         length += p.length;
275         length += outputStreamData(stream);
276         try {
277             p = "endobj\n".getBytes(PDFDocument.ENCODING);
278         } catch (UnsupportedEncodingException JavaDoc ue) {
279             p = "endobj\n".getBytes();
280         }
281         stream.write(p);
282         length += p.length;
283         return length;
284
285     }
286
287     /**
288      * Output just the stream data enclosed by stream/endstream markers
289      */

290     protected int outputStreamData(OutputStream JavaDoc stream) throws IOException JavaDoc {
291         int length = 0;
292         byte[] p;
293         try {
294             p = "stream\n".getBytes(PDFDocument.ENCODING);
295         } catch (UnsupportedEncodingException JavaDoc ue) {
296             p = "stream\n".getBytes();
297         }
298         stream.write(p);
299         length += p.length;
300         _data.writeTo(stream);
301         length += _data.size();
302         try {
303             p = "\nendstream\n".getBytes(PDFDocument.ENCODING);
304         } catch (UnsupportedEncodingException JavaDoc ue) {
305             p = "\nendstream\n".getBytes();
306         }
307         stream.write(p);
308         length += p.length;
309         return length;
310
311     }
312
313
314     /**
315      * Apply the filters to the data
316      * in the order given and return the /Filter and /DecodeParms
317      * entries for the stream dictionary. If the filters have already
318      * been applied to the data (either externally, or internally)
319      * then the dictionary entries are built and returned.
320      */

321     protected String JavaDoc applyFilters() throws IOException JavaDoc {
322         if (_filters.size() > 0) {
323             List JavaDoc names = new java.util.ArrayList JavaDoc();
324             List JavaDoc parms = new java.util.ArrayList JavaDoc();
325
326             // run the filters
327
for (int i = 0; i < _filters.size(); i++) {
328                 PDFFilter filter = (PDFFilter)_filters.get(i);
329                 // apply the filter encoding if neccessary
330
if (!filter.isApplied()) {
331                     byte[] tmp = filter.encode(_data.toByteArray());
332                     _data.reset();
333                     _data.write(tmp);
334                     filter.setApplied(true);
335                 }
336                 // place the names in our local List in reverse order
337
names.add(0, filter.getName());
338                 parms.add(0, filter.getDecodeParms());
339             }
340
341             // now build up the filter entries for the dictionary
342
return buildFilterEntries(names) + buildDecodeParms(parms);
343         }
344         return "";
345
346     }
347
348     private String JavaDoc buildFilterEntries(List JavaDoc names) {
349         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
350         sb.append("/Filter ");
351         if (names.size() > 1) {
352             sb.append("[ ");
353         }
354         for (int i = 0; i < names.size(); i++) {
355             sb.append((String JavaDoc)names.get(i));
356             sb.append(" ");
357         }
358         if (names.size() > 1) {
359             sb.append("]");
360         }
361         sb.append("\n");
362         return sb.toString();
363     }
364
365     private String JavaDoc buildDecodeParms(List JavaDoc parms) {
366         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
367         boolean needParmsEntry = false;
368         sb.append("/DecodeParms ");
369
370         if (parms.size() > 1) {
371             sb.append("[ ");
372         }
373         for (int i = 0; i < parms.size(); i++) {
374             String JavaDoc s = (String JavaDoc)parms.get(i);
375             if (s != null) {
376                 sb.append(s);
377                 needParmsEntry = true;
378             } else {
379                 sb.append("null");
380             }
381             sb.append(" ");
382         }
383         if (parms.size() > 1) {
384             sb.append("]");
385         }
386         sb.append("\n");
387         if (needParmsEntry) {
388             return sb.toString();
389         } else {
390             return "";
391         }
392     }
393
394
395 }
396
Popular Tags