KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > render > pdf > FopPDFImage


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id: FopPDFImage.java 426576 2006-07-28 15:44:37Z jeremias $ */
19
20 package org.apache.fop.render.pdf;
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.fop.pdf.PDFConformanceException;
24 import org.apache.fop.pdf.PDFFilterList;
25 import org.apache.fop.pdf.PDFICCBasedColorSpace;
26 import org.apache.fop.pdf.PDFImage;
27 import org.apache.fop.pdf.PDFFilter;
28 import org.apache.fop.pdf.PDFICCStream;
29 import org.apache.fop.pdf.PDFColor;
30 import org.apache.fop.pdf.PDFDocument;
31 import org.apache.fop.pdf.DCTFilter;
32 import org.apache.fop.pdf.CCFFilter;
33 import org.apache.fop.pdf.PDFDeviceColorSpace;
34 import org.apache.fop.pdf.PDFXObject;
35 import org.apache.fop.pdf.BitmapImage;
36 import org.apache.fop.util.ColorProfileUtil;
37
38 import org.apache.fop.image.FopImage;
39 import org.apache.fop.image.EPSImage;
40 import org.apache.fop.image.TIFFImage;
41
42 import java.io.IOException JavaDoc;
43 import java.io.OutputStream JavaDoc;
44 import java.awt.color.ColorSpace JavaDoc;
45 import java.awt.color.ICC_Profile JavaDoc;
46
47 /**
48  * PDFImage implementation for the PDF renderer.
49  */

50 public class FopPDFImage implements PDFImage {
51
52     /** logging instance */
53     private static Log log = LogFactory.getLog(FopPDFImage.class);
54
55     private FopImage fopImage;
56     private PDFICCStream pdfICCStream = null;
57     private PDFFilter pdfFilter = null;
58     private String JavaDoc maskRef;
59     private String JavaDoc softMaskRef;
60     private boolean isPS = false;
61     private boolean isCCF = false;
62     private boolean isDCT = false;
63     private String JavaDoc key;
64
65     /**
66      * Creates a new PDFImage from a FopImage
67      * @param image Image
68      * @param key XObject key
69      */

70     public FopPDFImage(FopImage image, String JavaDoc key) {
71         fopImage = image;
72         this.key = key;
73         isPS = (fopImage instanceof EPSImage);
74     }
75
76     /**
77      * @see org.apache.fop.pdf.PDFImage#getKey()
78      */

79     public String JavaDoc getKey() {
80         // key to look up XObject
81
return this.key;
82     }
83
84     /**
85      * @see org.apache.fop.pdf.PDFImage#setup(PDFDocument)
86      */

87     public void setup(PDFDocument doc) {
88         if ("image/jpeg".equals(fopImage.getMimeType())) {
89             pdfFilter = new DCTFilter();
90             pdfFilter.setApplied(true);
91             isDCT = true;
92
93         } else if ("image/tiff".equals(fopImage.getMimeType())
94                     && fopImage instanceof TIFFImage) {
95             TIFFImage tiffImage = (TIFFImage) fopImage;
96             if (tiffImage.getStripCount() == 1) {
97                 int comp = tiffImage.getCompression();
98                 if (comp == 1) {
99                     // Nothing to do
100
} else if (comp == 3) {
101                     pdfFilter = new CCFFilter();
102                     pdfFilter.setApplied(true);
103                     isCCF = true;
104                 } else if (comp == 4) {
105                     pdfFilter = new CCFFilter();
106                     pdfFilter.setApplied(true);
107                     ((CCFFilter)pdfFilter).setDecodeParms("<< /K -1 /Columns "
108                         + tiffImage.getWidth() + " >>");
109                     isCCF = true;
110                 } else if (comp == 6) {
111                     pdfFilter = new DCTFilter();
112                     pdfFilter.setApplied(true);
113                     isDCT = true;
114                 }
115             }
116         }
117         if (isPS || isDCT || isCCF) {
118             fopImage.load(FopImage.ORIGINAL_DATA);
119         } else {
120             fopImage.load(FopImage.BITMAP);
121         }
122         ICC_Profile JavaDoc prof = fopImage.getICCProfile();
123         PDFDeviceColorSpace pdfCS = toPDFColorSpace(fopImage.getColorSpace());
124         if (prof != null) {
125             boolean defaultsRGB = ColorProfileUtil.isDefaultsRGB(prof);
126             String JavaDoc desc = ColorProfileUtil.getICCProfileDescription(prof);
127             if (log.isDebugEnabled()) {
128                 log.debug("Image returns ICC profile: " + desc + ", default sRGB=" + defaultsRGB);
129             }
130             PDFICCBasedColorSpace cs = doc.getResources().getICCColorSpaceByProfileName(desc);
131             if (!defaultsRGB) {
132                 if (cs == null) {
133                     pdfICCStream = doc.getFactory().makePDFICCStream();
134                     pdfICCStream.setColorSpace(prof, pdfCS);
135                     cs = doc.getFactory().makeICCBasedColorSpace(null, null, pdfICCStream);
136                 } else {
137                     pdfICCStream = cs.getICCStream();
138                 }
139             } else {
140                 if (cs == null && "sRGB".equals(desc)) {
141                     //It's the default sRGB profile which we mapped to DefaultRGB in PDFRenderer
142
cs = doc.getResources().getColorSpace("DefaultRGB");
143                 }
144                 pdfICCStream = cs.getICCStream();
145             }
146         }
147         //Handle transparency mask if applicable
148
if (fopImage.hasSoftMask()) {
149             doc.getProfile().verifyTransparencyAllowed(fopImage.getOriginalURI());
150             //TODO Implement code to combine image with background color if transparency is not
151
//allowed (need BufferedImage support for that)
152
byte [] softMask = fopImage.getSoftMask();
153             if (softMask == null) {
154                 return;
155             }
156             BitmapImage fopimg = new BitmapImage
157                 ("Mask:" + key, fopImage.getWidth(), fopImage.getHeight(),
158                  softMask, null);
159             fopimg.setColorSpace(new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY));
160             PDFXObject xobj = doc.addImage(null, fopimg);
161             softMaskRef = xobj.referencePDF();
162         }
163         if (doc.getProfile().getPDFAMode().isPDFA1LevelB()) {
164             if (pdfCS != null
165                     && pdfCS.getColorSpace() != PDFDeviceColorSpace.DEVICE_RGB
166                     && pdfCS.getColorSpace() != PDFDeviceColorSpace.DEVICE_GRAY
167                     && prof == null) {
168                 //See PDF/A-1, ISO 19005:1:2005(E), 6.2.3.3
169
//FOP is currently restricted to DeviceRGB if PDF/A-1 is active.
170
throw new PDFConformanceException(
171                         "PDF/A-1 does not allow mixing DeviceRGB and DeviceCMYK: "
172                                 + fopImage.getOriginalURI());
173             }
174         }
175     }
176
177     /**
178      * @see org.apache.fop.pdf.PDFImage#getWidth()
179      */

180     public int getWidth() {
181         return fopImage.getWidth();
182     }
183
184     /**
185      * @see org.apache.fop.pdf.PDFImage#getHeight()
186      */

187     public int getHeight() {
188         return fopImage.getHeight();
189     }
190
191     /**
192      * @see org.apache.fop.pdf.PDFImage#getColorSpace()
193      */

194     public PDFDeviceColorSpace getColorSpace() {
195         // DeviceGray, DeviceRGB, or DeviceCMYK
196
if (isCCF || isDCT || isPS) {
197             return toPDFColorSpace(fopImage.getColorSpace());
198         } else {
199             return toPDFColorSpace(ColorSpace.getInstance(ColorSpace.CS_sRGB));
200         }
201     }
202
203     /**
204      * @see org.apache.fop.pdf.PDFImage#getBitsPerPixel()
205      */

206     public int getBitsPerPixel() {
207         if (isCCF) {
208             return fopImage.getBitsPerPixel();
209         } else {
210             return 8; //TODO This is suboptimal, handling everything as RGB
211
//The image wrappers can mostly only return RGB bitmaps right now. This should
212
//be improved so the renderers can deal directly with RenderedImage instances.
213
}
214     }
215
216     /**
217      * @see org.apache.fop.pdf.PDFImage#isTransparent()
218      */

219     public boolean isTransparent() {
220         return fopImage.isTransparent();
221     }
222
223     /**
224      * @see org.apache.fop.pdf.PDFImage#getTransparentColor()
225      */

226     public PDFColor getTransparentColor() {
227         return new PDFColor(fopImage.getTransparentColor().getRed(),
228                             fopImage.getTransparentColor().getGreen(),
229                             fopImage.getTransparentColor().getBlue());
230     }
231
232     /**
233      * @see org.apache.fop.pdf.PDFImage#getMask()
234      */

235     public String JavaDoc getMask() {
236         return maskRef;
237     }
238
239     /**
240      * @see org.apache.fop.pdf.PDFImage#getSoftMask()
241      */

242     public String JavaDoc getSoftMask() {
243         return softMaskRef;
244     }
245
246     /** @return true for CMYK images generated by Adobe Photoshop */
247     public boolean isInverted() {
248         return fopImage.isInverted();
249     }
250     
251     /**
252      * @see org.apache.fop.pdf.PDFImage#isPS()
253      */

254     public boolean isPS() {
255         return isPS;
256     }
257
258     /**
259      * @see org.apache.fop.pdf.PDFImage#getPDFFilter()
260      */

261     public PDFFilter getPDFFilter() {
262         return pdfFilter;
263     }
264     
265     /**
266      * @see org.apache.fop.pdf.PDFImage#outputContents(OutputStream)
267      */

268     public void outputContents(OutputStream JavaDoc out) throws IOException JavaDoc {
269         if (isPS) {
270             outputPostScriptContents(out);
271         } else {
272             if (fopImage.getBitmapsSize() > 0) {
273                 out.write(fopImage.getBitmaps());
274             } else {
275                 out.write(fopImage.getRessourceBytes());
276             }
277         }
278     }
279
280     /**
281      * Serializes an EPS image to an OutputStream.
282      * @param out OutputStream to write to
283      * @throws IOException in case of an I/O problem
284      */

285     protected void outputPostScriptContents(OutputStream JavaDoc out) throws IOException JavaDoc {
286         EPSImage epsImage = (EPSImage) fopImage;
287         int[] bbox = epsImage.getBBox();
288         int bboxw = bbox[2] - bbox[0];
289         int bboxh = bbox[3] - bbox[1];
290
291         // delegate the stream work to PDFStream
292
//PDFStream imgStream = new PDFStream(0);
293

294         StringBuffer JavaDoc preamble = new StringBuffer JavaDoc();
295         preamble.append("%%BeginDocument: " + epsImage.getDocName() + "\n");
296
297         preamble.append("userdict begin % Push userdict on dict stack\n");
298         preamble.append("/PreEPS_state save def\n");
299         preamble.append("/dict_stack countdictstack def\n");
300         preamble.append("/ops_count count 1 sub def\n");
301         preamble.append("/showpage {} def\n");
302
303
304         preamble.append((double)(1f / (double) bboxw) + " "
305                       + (double)(1f / (double) bboxh) + " scale\n");
306         preamble.append(-bbox[0] + " " + (-bbox[1]) + " translate\n");
307         preamble.append(bbox[0] + " " + bbox[1] + " "
308                         + bboxw + " " + bboxh + " rectclip\n");
309         preamble.append("newpath\n");
310
311         StringBuffer JavaDoc post = new StringBuffer JavaDoc();
312         post.append("%%EndDocument\n");
313         post.append("count ops_count sub {pop} repeat\n");
314         post.append("countdictstack dict_stack sub {end} repeat\n");
315         post.append("PreEPS_state restore\n");
316         post.append("end % userdict\n");
317
318         //Write Preamble
319
out.write(PDFDocument.encode(preamble.toString()));
320         //Write EPS contents
321
out.write(((EPSImage)fopImage).getEPSImage());
322         //Writing trailer
323
out.write(PDFDocument.encode(post.toString()));
324     }
325
326     /**
327      * @see org.apache.fop.pdf.PDFImage#getICCStream()
328      */

329     public PDFICCStream getICCStream() {
330         return pdfICCStream;
331     }
332
333     /**
334      * Converts a ColorSpace object to a PDFColorSpace object.
335      * @param cs ColorSpace instance
336      * @return PDFColorSpace new converted object
337      */

338     public static PDFDeviceColorSpace toPDFColorSpace(ColorSpace cs) {
339         if (cs == null) {
340             return null;
341         }
342
343         PDFDeviceColorSpace pdfCS = new PDFDeviceColorSpace(0);
344         switch(cs.getType()) {
345             case ColorSpace.TYPE_CMYK:
346                 pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_CMYK);
347             break;
348             case ColorSpace.TYPE_RGB:
349                 pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
350             break;
351             case ColorSpace.TYPE_GRAY:
352                 pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_GRAY);
353             break;
354         }
355         return pdfCS;
356     }
357
358     /**
359      * @see org.apache.fop.pdf.PDFImage#getFilterHint()
360      */

361     public String JavaDoc getFilterHint() {
362         if (isPS) {
363             return PDFFilterList.CONTENT_FILTER;
364         } else if (isDCT) {
365             return PDFFilterList.JPEG_FILTER;
366         } else if (isCCF) {
367             return PDFFilterList.TIFF_FILTER;
368         } else {
369             return PDFFilterList.IMAGE_FILTER;
370         }
371     }
372
373 }
374
375
Popular Tags