KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > render > bitmap > TIFFRenderer


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: TIFFRenderer.java 447325 2006-09-18 10:55:33 +0200 (Mon, 18 Sep 2006) jeremias $ */
19
20 package org.apache.fop.render.bitmap;
21
22 // Code originaly contributed by Oleg Tkachenko of Multiconn International Ltd
23
// (olegt@multiconn.com).
24

25 import java.awt.image.BufferedImage JavaDoc;
26 import java.awt.image.DataBuffer JavaDoc;
27 import java.awt.image.PixelInterleavedSampleModel JavaDoc;
28 import java.awt.image.RenderedImage JavaDoc;
29 import java.awt.image.SampleModel JavaDoc;
30 import java.awt.image.SinglePixelPackedSampleModel JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.OutputStream JavaDoc;
33 import java.util.Iterator JavaDoc;
34
35 import org.apache.avalon.framework.configuration.Configuration;
36 import org.apache.avalon.framework.configuration.ConfigurationException;
37
38 import org.apache.commons.logging.Log;
39
40 import org.apache.xmlgraphics.image.GraphicsUtil;
41 import org.apache.xmlgraphics.image.rendered.FormatRed;
42 import org.apache.xmlgraphics.image.writer.ImageWriter;
43 import org.apache.xmlgraphics.image.writer.ImageWriterParams;
44 import org.apache.xmlgraphics.image.writer.ImageWriterRegistry;
45 import org.apache.xmlgraphics.image.writer.MultiImageWriter;
46
47 import org.apache.fop.apps.FOPException;
48 import org.apache.fop.apps.FOUserAgent;
49 import org.apache.fop.apps.MimeConstants;
50 import org.apache.fop.render.java2d.Java2DRenderer;
51
52 /**
53  * <p>
54  * This class represents renderer to TIFF (Tagged Image File Format) format. It
55  * is one of the most popular and flexible of the current public domain raster
56  * file formats, which was is primarily designed for raster data interchange.
57  * Supported compression types are:
58  * <ul>
59  * <li>Raw noncompressed data</li>
60  * <li>Byte-oriented run-length encoding "PackBits" compression.</li>
61  * <li>Modified Huffman Compression (CCITT Group 3 1D facsimile compression)</li>
62  * <li>CCITT T.4 bilevel compression (CCITT Group 3 2D facsimile compression)</li>
63  * <li>CCITT T.6 bilevel compression (CCITT Group 4 facsimile compression)</li>
64  * <li>JPEG-in-TIFF compression</li>
65  * <li>DEFLATE lossless compression (also known as "Zip-in-TIFF")</li>
66  * <li>LZW compression</li>
67  * TODO
68  * <p>
69  * This class actually does not render itself, instead it extends
70  * <code>org.apache.fop.render.java2D.Java2DRenderer</code> and just encode
71  * rendering results into TIFF format using Batik's image codec
72  */

73 public class TIFFRenderer extends Java2DRenderer {
74
75     /** The MIME type for tiff-Rendering */
76     public static final String JavaDoc MIME_TYPE = MimeConstants.MIME_TIFF;
77
78     //private static final String COMPRESSION_NONE = "NONE";
79
//private static final String COMPRESSION_JPEG = "JPEG";
80
private static final String JavaDoc COMPRESSION_PACKBITS = "PackBits";
81     //private static final String COMPRESSION_DEFLATE = "Deflate";
82
//private static final String COMPRESSION_LZW = "LZW";
83
//private static final String COMPRESSION_ZLIB = "ZLib";
84
private static final String JavaDoc COMPRESSION_CCITT_T6 = "CCITT T.6"; //CCITT Group 4
85
private static final String JavaDoc COMPRESSION_CCITT_T4 = "CCITT T.4"; //CCITT Group 3
86

87     /** ImageWriter parameters */
88     private ImageWriterParams writerParams;
89     
90     /** Image Type as parameter for the BufferedImage constructor (see BufferedImage.TYPE_*) */
91     private int bufferedImageType = BufferedImage.TYPE_INT_ARGB;
92     
93     private OutputStream JavaDoc outputStream;
94
95     /** @see org.apache.fop.render.AbstractRenderer */
96     public String JavaDoc getMimeType() {
97         return MIME_TYPE;
98     }
99
100     /** Creates TIFF renderer. */
101     public TIFFRenderer() {
102         writerParams = new ImageWriterParams();
103         writerParams.setCompressionMethod(COMPRESSION_PACKBITS);
104     }
105
106     /**
107      * @see org.apache.fop.render.java2d.Java2DRenderer#setUserAgent(
108      * org.apache.fop.apps.FOUserAgent)
109      */

110     public void setUserAgent(FOUserAgent foUserAgent) {
111         super.setUserAgent(foUserAgent);
112
113         //Set target resolution
114
int dpi = Math.round(userAgent.getTargetResolution());
115         writerParams.setResolution(dpi);
116     }
117
118     /**
119      * Configure the TIFF renderer. Get the configuration to be used for
120      * compression
121      * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
122      */

123     public void configure(Configuration cfg) throws ConfigurationException {
124         super.configure(cfg);
125
126         //set compression
127
String JavaDoc name = cfg.getChild("compression").getValue(COMPRESSION_PACKBITS);
128         //Some compression formats need a special image format:
129
if (name.equalsIgnoreCase(COMPRESSION_CCITT_T6)) {
130             bufferedImageType = BufferedImage.TYPE_BYTE_BINARY;
131         } else if (name.equalsIgnoreCase(COMPRESSION_CCITT_T4)) {
132             bufferedImageType = BufferedImage.TYPE_BYTE_BINARY;
133         } else {
134             bufferedImageType = BufferedImage.TYPE_INT_ARGB;
135         }
136         if (!"NONE".equalsIgnoreCase(name)) {
137             writerParams.setCompressionMethod(name);
138         }
139         log.info("TIFF compression set to " + name);
140     }
141
142     /** @see org.apache.fop.render.Renderer#startRenderer(java.io.OutputStream) */
143     public void startRenderer(OutputStream JavaDoc outputStream) throws IOException JavaDoc {
144         this.outputStream = outputStream;
145         super.startRenderer(outputStream);
146     }
147
148     /** @see org.apache.fop.render.Renderer#stopRenderer() */
149     public void stopRenderer() throws IOException JavaDoc {
150         super.stopRenderer();
151         log.debug("Starting TIFF encoding ...");
152
153         // Creates lazy iterator over generated page images
154
Iterator JavaDoc pageImagesItr = new LazyPageImagesIterator(getNumberOfPages(), log);
155
156         // Creates writer
157
ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(getMimeType());
158         if (writer == null) {
159             throw new NullPointerException JavaDoc("No ImageWriter for " + getMimeType() + " available!");
160         }
161         if (writer.supportsMultiImageWriter()) {
162             MultiImageWriter multiWriter = writer.createMultiImageWriter(outputStream);
163             try {
164                 // Write all pages/images
165
while (pageImagesItr.hasNext()) {
166                     RenderedImage JavaDoc img = (RenderedImage JavaDoc) pageImagesItr.next();
167                     multiWriter.writeImage(img, writerParams);
168                 }
169             } finally {
170                 multiWriter.close();
171             }
172         } else {
173             writer.writeImage((RenderedImage JavaDoc) pageImagesItr.next(), outputStream, writerParams);
174             if (pageImagesItr.hasNext()) {
175                 log.error("Image encoder does not support multiple images. Only the first page"
176                         + " has been produced.");
177             }
178         }
179
180         // Cleaning
181
outputStream.flush();
182         clearViewportList();
183         log.debug("TIFF encoding done.");
184     }
185     
186     /** @see org.apache.fop.render.java2d.Java2DRenderer#getBufferedImage(int, int) */
187     protected BufferedImage JavaDoc getBufferedImage(int bitmapWidth, int bitmapHeight) {
188         return new BufferedImage JavaDoc(bitmapWidth, bitmapHeight, bufferedImageType);
189     }
190
191     /** Private inner class to lazy page rendering. */
192     private class LazyPageImagesIterator implements Iterator JavaDoc {
193         /** logging instance */
194         private Log log;
195
196         private int count;
197
198         private int current = 0;
199
200         /**
201          * Main constructor
202          * @param c number of pages to iterate over
203          * @param log the logger to use (this is a hack so this compiles under JDK 1.3)
204          */

205         public LazyPageImagesIterator(int c, Log log) {
206             count = c;
207             this.log = log;
208         }
209
210         public boolean hasNext() {
211             return current < count;
212         }
213
214         public Object JavaDoc next() {
215             if (log.isDebugEnabled()) {
216                 log.debug("[" + (current + 1) + "]");
217             }
218
219             // Renders current page as image
220
BufferedImage JavaDoc pageImage = null;
221             try {
222                 pageImage = getPageImage(current++);
223             } catch (FOPException e) {
224                 log.error(e);
225                 return null;
226             }
227
228             if (COMPRESSION_CCITT_T4.equalsIgnoreCase(writerParams.getCompressionMethod())
229                    || COMPRESSION_CCITT_T6.equalsIgnoreCase(writerParams.getCompressionMethod())) {
230                 return pageImage;
231             } else {
232                 //Decorate the image with a packed sample model for encoding by the codec
233
SinglePixelPackedSampleModel JavaDoc sppsm;
234                 sppsm = (SinglePixelPackedSampleModel JavaDoc)pageImage.getSampleModel();
235                 
236                 int bands = sppsm.getNumBands();
237                 int[] off = new int[bands];
238                 int w = pageImage.getWidth();
239                 int h = pageImage.getHeight();
240                 for (int i = 0; i < bands; i++) {
241                     off[i] = i;
242                 }
243                 SampleModel JavaDoc sm = new PixelInterleavedSampleModel JavaDoc(
244                         DataBuffer.TYPE_BYTE, w, h, bands, w * bands, off);
245                 
246                 RenderedImage JavaDoc rimg = new FormatRed(GraphicsUtil.wrap(pageImage), sm);
247                 return rimg;
248             }
249         }
250
251         public void remove() {
252             throw new UnsupportedOperationException JavaDoc(
253                     "Method 'remove' is not supported.");
254         }
255     }
256 }
257
Popular Tags