KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * $Id: PDFXObject.java,v 1.14.2.6 2003/03/05 18:58:15 pietsch 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 // Java
54
import java.io.IOException JavaDoc;
55 import java.io.UnsupportedEncodingException JavaDoc;
56 import java.io.OutputStream JavaDoc;
57
58 // FOP
59
import org.apache.fop.datatypes.ColorSpace;
60 import org.apache.fop.messaging.MessageHandler;
61 import org.apache.fop.pdf.PDFDocument;
62 import org.apache.fop.pdf.PDFICCStream;
63 import org.apache.fop.image.FopImage;
64 import org.apache.fop.image.EPSImage;
65 import org.apache.fop.image.JpegImage;
66 import org.apache.fop.image.FopImageException;
67
68 /* modified by JKT to integrate with 0.12.0 */
69 /* modified by Eric SCHAEFFER to integrate with 0.13.0 */
70
71 /**
72  * PDF XObject
73  *
74  * A derivative of the PDF Object, is a PDF Stream that has not only a
75  * dictionary but a stream of image data.
76  * the dictionary just provides information like the stream length
77  */

78 public class PDFXObject extends PDFObject {
79     private boolean isPS;
80     private PDFDocument pdfDoc;
81     private PDFICCStream pdfICCStream;
82
83     FopImage fopimage;
84     int Xnum;
85
86     /**
87      * create an Xobject with the given number and name and load the
88      * image in the object
89      */

90     public PDFXObject(int number, int Xnumber, FopImage img) {
91         this(number, Xnumber, img, null);
92     }
93
94     public PDFXObject(int number, int Xnumber, FopImage img, PDFDocument pdfdoc) {
95         super(number);
96         isPS = false;
97         this.Xnum = Xnumber;
98         if (img == null)
99             MessageHandler.errorln("FISH");
100         fopimage = img;
101         this.pdfDoc = pdfdoc;
102         pdfICCStream = null;
103         try {
104             if (fopimage instanceof JpegImage) {
105                 fopimage.getBitmaps();
106                 JpegImage jpegimage = (JpegImage)fopimage;
107                 if (jpegimage.getColorSpace().hasICCProfile()) {
108                         pdfICCStream = pdfDoc.makePDFICCStream();
109                         pdfICCStream.setColorSpace(jpegimage.getColorSpace());
110                         pdfICCStream.addDefaultFilters();
111                         if (pdfDoc.encryption != null) {
112                             pdfICCStream.addFilter(pdfDoc.encryption.makeFilter(pdfICCStream.number, pdfICCStream.generation));
113                         }
114                     }
115             }
116         } catch (Exception JavaDoc e) {
117             MessageHandler.errorln("Error while reading image " + fopimage.getURL() +
118                             ": " + e.getMessage());
119         }
120     }
121
122     /**
123      * @return the PDF XObject number
124      */

125     public int getXNumber() {
126         return this.Xnum;
127     }
128
129     /**
130      * represent as PDF
131      */

132     protected int output(OutputStream JavaDoc stream) throws IOException JavaDoc {
133         int length = 0;
134         int i = 0;
135
136         try {
137             if (fopimage instanceof EPSImage) {
138                 isPS = true;
139                 EPSImage epsImage = (EPSImage)fopimage;
140                 int[] bbox = epsImage.getBBox();
141                 int bboxw = bbox[2] - bbox[0];
142                 int bboxh = bbox[3] - bbox[1];
143
144                 // delegate the stream work to PDFStream
145
PDFStream imgStream = new PDFStream(0);
146
147                 StringBuffer JavaDoc preamble = new StringBuffer JavaDoc();
148                 preamble.append("%%BeginDocument: " + epsImage.getDocName() + "\n");
149
150                 preamble.append("userdict begin % Push userdict on dict stack\n");
151                 preamble.append("/PreEPS_state save def\n");
152                 preamble.append("/dict_stack countdictstack def\n");
153                 preamble.append("/ops_count count 1 sub def\n");
154                 preamble.append("/showpage {} def\n");
155
156
157                 preamble.append((double)(1f/(double)bboxw) + " " + (double)(1f/(double)bboxh) + " scale\n");
158                 preamble.append(-bbox[0] + " " + (-bbox[1]) + " translate\n");
159                 preamble.append(bbox[0] + " " + bbox[1] + " " + bboxw + " " + bboxh + " rectclip\n");
160                 preamble.append("newpath\n");
161
162                 StringBuffer JavaDoc post = new StringBuffer JavaDoc();
163                 post.append("%%EndDocument\n");
164                 post.append("count ops_count sub {pop} repeat\n");
165                 post.append("countdictstack dict_stack sub {end} repeat\n");
166                 post.append("PreEPS_state restore\n");
167                 post.append("end % userdict\n");
168
169                 byte[] preBytes;
170                 try {
171                     preBytes = preamble.toString().getBytes(PDFDocument.ENCODING);
172                 } catch (UnsupportedEncodingException JavaDoc ue) {
173                     preBytes = preamble.toString().getBytes();
174                 }
175                 byte[] postBytes;
176                 try {
177                     postBytes = post.toString().getBytes(PDFDocument.ENCODING);
178                 } catch (UnsupportedEncodingException JavaDoc ue) {
179                     postBytes = post.toString().getBytes();
180                 }
181                 byte[] imgData = new byte[preBytes.length + postBytes.length + fopimage.getBitmaps().length];
182
183                 System.arraycopy (preBytes, 0, imgData, 0, preBytes.length);
184                 System.arraycopy (fopimage.getBitmaps(), 0, imgData, preBytes.length, fopimage.getBitmaps().length);
185                 System.arraycopy (postBytes, 0, imgData, preBytes.length + fopimage.getBitmaps().length, postBytes.length);
186
187
188                 imgStream.setData(imgData);
189                 //imgStream.addFilter(new FlateFilter());
190
imgStream.addDefaultFilters();
191                 if (pdfDoc.encryption != null) {
192                     imgStream.addFilter(pdfDoc.encryption.makeFilter(this.number,this.generation));
193                 }
194
195                 String JavaDoc dictEntries = imgStream.applyFilters();
196
197                 String JavaDoc p = this.number + " " + this.generation + " obj\n";
198                 p = p + "<</Type /XObject\n";
199                 p = p + "/Subtype /PS\n";
200                 p = p + "/Length " + imgStream.getDataLength();
201
202                 // don't know if it's the good place (other objects can have references to it)
203
//fopimage.close(); //Not really necessary, is it? Only leads to image reloading.
204

205                 p = p + dictEntries;
206                 p = p + ">>\n";
207
208                 // push the pdf dictionary on the writer
209
byte[] pdfBytes;
210                 try {
211                     pdfBytes = p.getBytes(PDFDocument.ENCODING);
212                 } catch (UnsupportedEncodingException JavaDoc ue) {
213                     pdfBytes = p.getBytes();
214                 }
215                 stream.write(pdfBytes);
216                 length += pdfBytes.length;
217                 // push all the image data on the writer and takes care of length for trailer
218
length += imgStream.outputStreamData(stream);
219
220                 try {
221                     pdfBytes = ("endobj\n").getBytes(PDFDocument.ENCODING);
222                 } catch (UnsupportedEncodingException JavaDoc ue) {
223                     pdfBytes = ("endobj\n").getBytes();
224                 }
225                 stream.write(pdfBytes);
226                 length += pdfBytes.length;
227
228             } else {
229
230                 // delegate the stream work to PDFStream
231
PDFStream imgStream = new PDFStream(0);
232
233                 imgStream.setData(fopimage.getBitmaps());
234
235                 /*
236                  * Added by Eric Dalquist
237                  * If the DCT filter hasn't been added to the object we add it here
238                  */

239                 /*
240                  * Added by Manuel Mall
241                  * Only add the default filters if we don't have an image filter to
242                  * avoid double encoding of images
243                  */

244                  
245                 if (fopimage.getPDFFilter() != null) {
246                     imgStream.addFilter(fopimage.getPDFFilter());
247                 } else {
248                     imgStream.addDefaultFilters();
249                 }
250                 if (pdfDoc.encryption != null) {
251                     imgStream.addFilter(pdfDoc.encryption.makeFilter(this.number,this.generation));
252                 }
253                 
254                 String JavaDoc dictEntries = imgStream.applyFilters();
255
256                 String JavaDoc p = this.number + " " + this.generation + " obj\n";
257                 p = p + "<</Type /XObject\n";
258                 p = p + "/Subtype /Image\n";
259                 p = p + "/Name /Im" + Xnum + "\n";
260                 p = p + "/Length " + imgStream.getDataLength() + "\n";
261                 p = p + "/Width " + fopimage.getWidth() + "\n";
262                 p = p + "/Height " + fopimage.getHeight() + "\n";
263                 p = p + "/BitsPerComponent " + fopimage.getBitsPerPixel() + "\n";
264
265                 if (pdfICCStream != null ) {
266                     p = p + "/ColorSpace [/ICCBased " + pdfICCStream.referencePDF() + "]\n";
267                 } else {
268                     ColorSpace cs = fopimage.getColorSpace();
269                     p = p + "/ColorSpace /" + cs.getColorSpacePDFString() + "\n";
270                 }
271
272                     /* PhotoShop generates CMYK values that's inverse,
273                      */

274                 if (fopimage.getColorSpace().getColorSpace() == ColorSpace.DEVICE_CMYK &&
275                     fopimage.invertImage()) {
276                     p = p + "/Decode [ 1.0 0.0 1.0 0.0 1.0 0.0 1.1 0.0 ]\n";
277                 }
278
279                 if (fopimage.isTransparent()) {
280                     PDFColor transp = fopimage.getTransparentColor();
281                     p = p + "/Mask [" + transp.red255() + " " + transp.red255()
282                         + " " + transp.green255() + " " + transp.green255() + " "
283                         + transp.blue255() + " " + transp.blue255() + "]\n";
284                 }
285                 p = p + dictEntries;
286                 p = p + ">>\n";
287
288                 // don't know if it's the good place (other objects can have references to it)
289
//fopimage.close(); //Not really necessary, is it? Only leads to image reloading.
290

291                 // push the pdf dictionary on the writer
292
byte[] pdfBytes;
293                 try {
294                     pdfBytes = p.getBytes(PDFDocument.ENCODING);
295                 } catch (UnsupportedEncodingException JavaDoc ue) {
296                     pdfBytes = p.getBytes();
297                 }
298                 stream.write(pdfBytes);
299                 length += pdfBytes.length;
300                 // push all the image data on the writer and takes care of length for trailer
301
length += imgStream.outputStreamData(stream);
302
303                 try {
304                     pdfBytes = ("endobj\n").getBytes(PDFDocument.ENCODING);
305                 } catch (UnsupportedEncodingException JavaDoc ue) {
306                     pdfBytes = ("endobj\n").getBytes();
307                 }
308                 stream.write(pdfBytes);
309                 length += pdfBytes.length;
310             }
311         } catch (FopImageException imgex) {
312             MessageHandler.errorln("Error in XObject : "
313                                    + imgex.getMessage());
314         }
315
316         return length;
317     }
318
319     byte[] toPDF() {
320         /*
321          * Not used any more
322          * String p = this.number + " " + this.generation + " obj\n";
323          * p = p + "<</Type /XObject\n";
324          * p = p + "/Subtype /Image\n";
325          * p = p + "/Name /Im"+Xnum+"\n";
326          * p = p + "/Width "+fopimage.getpixelwidth()+"\n";
327          * p = p + "/Height "+fopimage.getpixelheight()+"\n";
328          * p = p + "/BitsPerComponent 8\n";
329          * if (fopimage.getcolor())
330          * p = p + "/ColorSpace /DeviceRGB\n";
331          * else
332          * p = p + "/ColorSpace /DeviceGray\n";
333          * p = p + "/Filter /ASCIIHexDecode\n";
334          * p = p + "/Length ";
335          * return p;
336          */

337         return null;
338     }
339
340 }
341
Popular Tags