import org.apache.commons.logging.Log;
import org.apache.xmlgraphics.image.GraphicsUtil;
-import org.apache.xmlgraphics.image.codec.tiff.TIFFEncodeParam;
-import org.apache.xmlgraphics.image.codec.tiff.TIFFField;
-import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder;
-import org.apache.xmlgraphics.image.codec.tiff.TIFFImageEncoder;
import org.apache.xmlgraphics.image.rendered.FormatRed;
+import org.apache.xmlgraphics.image.writer.ImageWriter;
+import org.apache.xmlgraphics.image.writer.ImageWriterParams;
+import org.apache.xmlgraphics.image.writer.ImageWriterRegistry;
+import org.apache.xmlgraphics.image.writer.MultiImageWriter;
import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.java2d.Java2DRenderer;
/** The MIME type for tiff-Rendering */
public static final String MIME_TYPE = MimeConstants.MIME_TIFF;
- /** */
- private TIFFEncodeParam renderParams;
-
+ //private static final String COMPRESSION_NONE = "NONE";
+ //private static final String COMPRESSION_JPEG = "JPEG";
+ private static final String COMPRESSION_PACKBITS = "PackBits";
+ //private static final String COMPRESSION_DEFLATE = "Deflate";
+ //private static final String COMPRESSION_LZW = "LZW";
+ //private static final String COMPRESSION_ZLIB = "ZLib";
+ private static final String COMPRESSION_CCITT_T6 = "CCITT T.6"; //CCITT Group 4
+ private static final String COMPRESSION_CCITT_T4 = "CCITT T.4"; //CCITT Group 3
+
+ /** ImageWriter parameters */
+ private ImageWriterParams writerParams;
+
+ /** Image Type as parameter for the BufferedImage constructor (see BufferedImage.TYPE_*) */
+ private int bufferedImageType = BufferedImage.TYPE_INT_ARGB;
+
private OutputStream outputStream;
/** @see org.apache.fop.render.AbstractRenderer */
/** Creates TIFF renderer. */
public TIFFRenderer() {
- renderParams = new TIFFEncodeParam();
- //Default to packbits compression which is widely supported
- renderParams.setCompression(TIFFEncodeParam.COMPRESSION_PACKBITS);
+ writerParams = new ImageWriterParams();
+ writerParams.setCompressionMethod(COMPRESSION_PACKBITS);
+ }
+
+ /**
+ * @see org.apache.fop.render.java2d.Java2DRenderer#setUserAgent(
+ * org.apache.fop.apps.FOUserAgent)
+ */
+ public void setUserAgent(FOUserAgent foUserAgent) {
+ super.setUserAgent(foUserAgent);
+
+ //Set target resolution
+ int dpi = Math.round(userAgent.getTargetResolution());
+ writerParams.setResolution(dpi);
}
/**
public void configure(Configuration cfg) throws ConfigurationException {
super.configure(cfg);
- //TODO Support output of monochrome bitmaps (fax-style)
- int comp = cfg.getChild("compression").getAttributeAsInteger("value", 1);
- String name = null;
- switch (comp) {
- case TIFFEncodeParam.COMPRESSION_NONE:
- name = "COMPRESSION_NONE";
- break;
- case TIFFEncodeParam.COMPRESSION_JPEG_TTN2:
- name = "COMPRESSION_JPEG_TTN2";
- break;
- case TIFFEncodeParam.COMPRESSION_PACKBITS:
- name = "COMPRESSION_PACKBITS";
- break;
- case TIFFEncodeParam.COMPRESSION_DEFLATE:
- name = "COMPRESSION_DEFLATE";
- break;
- default:
- log.info("TIFF compression not supported: " + comp);
- return;
+ //set compression
+ String name = cfg.getChild("compression").getValue(COMPRESSION_PACKBITS);
+ //Some compression formats need a special image format:
+ if (name.equalsIgnoreCase(COMPRESSION_CCITT_T6)) {
+ bufferedImageType = BufferedImage.TYPE_BYTE_BINARY;
+ } else if (name.equalsIgnoreCase(COMPRESSION_CCITT_T4)) {
+ bufferedImageType = BufferedImage.TYPE_BYTE_BINARY;
+ } else {
+ bufferedImageType = BufferedImage.TYPE_INT_ARGB;
+ }
+ if (!"NONE".equalsIgnoreCase(name)) {
+ writerParams.setCompressionMethod(name);
}
log.info("TIFF compression set to " + name);
-
}
/** @see org.apache.fop.render.Renderer#startRenderer(java.io.OutputStream) */
/** @see org.apache.fop.render.Renderer#stopRenderer() */
public void stopRenderer() throws IOException {
-
super.stopRenderer();
- log.debug("Starting Tiff encoding ...");
-
- //Set target resolution
- float pixSzMM = userAgent.getTargetPixelUnitToMillimeter();
- // num Pixs in 100 Meters
- int numPix = (int)(((1000 * 100) / pixSzMM) + 0.5);
- int denom = 100 * 100; // Centimeters per 100 Meters;
- long [] rational = {numPix, denom};
- TIFFField [] fields = {
- new TIFFField(TIFFImageDecoder.TIFF_RESOLUTION_UNIT,
- TIFFField.TIFF_SHORT, 1,
- new char[] {(char)3}),
- new TIFFField(TIFFImageDecoder.TIFF_X_RESOLUTION,
- TIFFField.TIFF_RATIONAL, 1,
- new long[][] {rational}),
- new TIFFField(TIFFImageDecoder.TIFF_Y_RESOLUTION,
- TIFFField.TIFF_RATIONAL, 1,
- new long[][] {rational})
- };
- renderParams.setExtraFields(fields);
-
- // Creates encoder
- TIFFImageEncoder enc = new TIFFImageEncoder(outputStream, renderParams);
+ log.debug("Starting TIFF encoding ...");
// Creates lazy iterator over generated page images
Iterator pageImagesItr = new LazyPageImagesIterator(getNumberOfPages(), log);
- // The first image to be passed to enc
- RenderedImage first = (RenderedImage) pageImagesItr.next();
-
- // The other images are set to the renderParams
- renderParams.setExtraImages(pageImagesItr);
-
- // Start encoding
- enc.encode(first);
+ // Creates writer
+ ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(getMimeType());
+ if (writer == null) {
+ throw new NullPointerException("No ImageWriter for " + getMimeType() + " available!");
+ }
+ if (writer.supportsMultiImageWriter()) {
+ MultiImageWriter multiWriter = writer.createMultiImageWriter(outputStream);
+ try {
+ // Write all pages/images
+ while (pageImagesItr.hasNext()) {
+ RenderedImage img = (RenderedImage) pageImagesItr.next();
+ multiWriter.writeImage(img, writerParams);
+ }
+ } finally {
+ multiWriter.close();
+ }
+ } else {
+ writer.writeImage((RenderedImage) pageImagesItr.next(), outputStream, writerParams);
+ if (pageImagesItr.hasNext()) {
+ log.error("Image encoder does not support multiple images. Only the first page"
+ + " has been produced.");
+ }
+ }
// Cleaning
outputStream.flush();
clearViewportList();
- log.debug("Tiff encoding done.");
-
+ log.debug("TIFF encoding done.");
+ }
+
+ /** @see org.apache.fop.render.java2d.Java2DRenderer#getBufferedImage(int, int) */
+ protected BufferedImage getBufferedImage(int bitmapWidth, int bitmapHeight) {
+ return new BufferedImage(bitmapWidth, bitmapHeight, bufferedImageType);
}
/** Private inner class to lazy page rendering. */
}
public Object next() {
- log.debug("[" + (current + 1) + "]");
+ if (log.isDebugEnabled()) {
+ log.debug("[" + (current + 1) + "]");
+ }
// Renders current page as image
BufferedImage pageImage = null;
return null;
}
- switch (renderParams.getCompression()) {
- // These types of compression require a monochrome image
- /* these compression types are not supported by the Batik codec
- case TIFFEncodeParam.COMPRESSION_GROUP3_1D:
- case TIFFEncodeParam.COMPRESSION_GROUP3_2D:
- case TIFFEncodeParam.COMPRESSION_GROUP4:
- BufferedImage faxImage = new BufferedImage(
- pageImage.getWidth(), pageImage.getHeight(),
- BufferedImage.TYPE_BYTE_BINARY);
- faxImage.getGraphics().drawImage(pageImage, 0, 0, null);
- return faxImage;*/
- default:
+ if (COMPRESSION_CCITT_T4.equalsIgnoreCase(writerParams.getCompressionMethod())
+ || COMPRESSION_CCITT_T6.equalsIgnoreCase(writerParams.getCompressionMethod())) {
+ return pageImage;
+ } else {
//Decorate the image with a packed sample model for encoding by the codec
SinglePixelPackedSampleModel sppsm;
sppsm = (SinglePixelPackedSampleModel)pageImage.getSampleModel();