diff options
author | Christian Geisert <chrisg@apache.org> | 2002-11-18 14:37:47 +0000 |
---|---|---|
committer | Christian Geisert <chrisg@apache.org> | 2002-11-18 14:37:47 +0000 |
commit | 24187929060686cfe4e90ee36ab563e5aae150a8 (patch) | |
tree | 3919d6fa947fa60800b1fe1f7d68e2df915c6795 /src | |
parent | c109bf7927a5f99d8d9378db31fbc3d87ce9d3b1 (diff) | |
download | xmlgraphics-fop-24187929060686cfe4e90ee36ab563e5aae150a8.tar.gz xmlgraphics-fop-24187929060686cfe4e90ee36ab563e5aae150a8.zip |
Added support for CCITT Group 4 encoded TIFF files
Made JAI support dynamic (no recompile needed anymore)
Submitted by: Manuel Mall <mm@arcus.com.au> (see bug #13866)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-0_20_2-maintain@195555 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r-- | src/org/apache/fop/image/FopImageFactory.java | 44 | ||||
-rwxr-xr-x | src/org/apache/fop/image/TiffImage.java | 170 | ||||
-rw-r--r-- | src/org/apache/fop/messaging/MessageHandler.java | 85 | ||||
-rwxr-xr-x | src/org/apache/fop/pdf/CCFFilter.java | 42 | ||||
-rw-r--r-- | src/org/apache/fop/pdf/PDFXObject.java | 11 | ||||
-rw-r--r-- | src/org/apache/fop/tools/anttasks/Fop.java | 49 |
6 files changed, 327 insertions, 74 deletions
diff --git a/src/org/apache/fop/image/FopImageFactory.java b/src/org/apache/fop/image/FopImageFactory.java index b672446ce..33735d3c8 100644 --- a/src/org/apache/fop/image/FopImageFactory.java +++ b/src/org/apache/fop/image/FopImageFactory.java @@ -30,6 +30,13 @@ public class FopImageFactory { private static Map m_urlMap = new java.util.HashMap(); /** + * The class name of the generic image handler. + * Will be either jimi or jai depending on what + * is available. + */ + private static String m_genericImageClassName = null; + + /** * create an FopImage objects. * @param href image URL as a String * @return a new FopImage object @@ -126,24 +133,18 @@ public class FopImageFactory { String imgClassName = null; if ("image/gif".equals(imgMimeType)) { imgClassName = "org.apache.fop.image.GifImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; } else if ("image/jpeg".equals(imgMimeType)) { imgClassName = "org.apache.fop.image.JpegImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; } else if ("image/bmp".equals(imgMimeType)) { imgClassName = "org.apache.fop.image.BmpImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; } else if ("image/png".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.JimiImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; + imgClassName = getGenericImageClassName(); } else if ("image/tga".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.JimiImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; + imgClassName = getGenericImageClassName(); } else if ("image/eps".equals(imgMimeType)) { imgClassName = "org.apache.fop.image.EPSImage"; } else if ("image/tiff".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.JimiImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; + imgClassName = getGenericImageClassName(); } else if ("image/svg+xml".equals(imgMimeType)) { imgClassName = "org.apache.fop.image.SVGImage"; } @@ -152,8 +153,8 @@ public class FopImageFactory { + absoluteURL.toString() + ") : " + imgMimeType); - // load the right image class - // return new <FopImage implementing class> + // load the right image class + // return new <FopImage implementing class> Object imageInstance = null; Class imageClass = null; try { @@ -195,6 +196,27 @@ public class FopImageFactory { return (FopImage)imageInstance; } + + /** + * Determines the class name of the generic image handler + * This should really come from a config file but we leave this + * to some future time. + */ + private static String getGenericImageClassName() { + + if (m_genericImageClassName == null) { + try { + Class.forName("org.apache.fop.image.JAIImage"); + m_genericImageClassName = "org.apache.fop.image.JAIImage"; + } catch (Exception ex) { + /* on any exception assume Jai is not present and use Jimi instead */ + m_genericImageClassName = "org.apache.fop.image.JimiImage"; + } + } + return m_genericImageClassName; + } + + /** * Clear the image cache. */ diff --git a/src/org/apache/fop/image/TiffImage.java b/src/org/apache/fop/image/TiffImage.java new file mode 100755 index 000000000..5ebb3bfb3 --- /dev/null +++ b/src/org/apache/fop/image/TiffImage.java @@ -0,0 +1,170 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.image; + +// Java +import java.net.URL; +import java.io.InputStream; +import java.io.ByteArrayOutputStream; +import java.io.BufferedInputStream; + +// AWT +import java.awt.image.ColorModel; +import java.awt.image.IndexColorModel; +import java.awt.image.BufferedImage; + +// JAI +import javax.media.jai.JAI; +import javax.media.jai.RenderedOp; +// Sun codec +import com.sun.media.jai.codec.FileCacheSeekableStream; +// FOP +import org.apache.fop.datatypes.ColorSpace; +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.pdf.CCFFilter; +import org.apache.fop.pdf.DCTFilter; +import org.apache.fop.image.analyser.ImageReader; + +/** + * FopImage object using JAI for TIFF images. + * Allows to store certain compresssed TIFF images directly + * in the output stream. Does revert to the standard JAI + * image for anything it doesn't understand. + * @author Manuel MALL + * @see AbstractFopImage + * @see FopImage + */ +public class TiffImage extends JAIImage { + public TiffImage(URL href) throws FopImageException { + super(href); + } + + public TiffImage(URL href, + ImageReader imgReader) throws FopImageException { + super(href, imgReader); + } + + protected void loadImage() throws FopImageException { + try { + InputStream inputStream = this.m_href.openStream(); + /* + * BufferedInputStream inputStream = this.m_imageReader.getInputStream(); + * inputStream.reset(); + */ + com.sun.media.jai.codec.FileCacheSeekableStream seekableInput = + new FileCacheSeekableStream(inputStream); + + com.sun.media.jai.codec.TIFFDirectory ifd = new com.sun.media.jai.codec.TIFFDirectory(seekableInput, 0); + com.sun.media.jai.codec.TIFFField fld = null; + + this.m_height = (int)ifd.getFieldAsLong(0x101); + this.m_width = (int)ifd.getFieldAsLong(0x100); + + fld = ifd.getField(0x115); // The samples per pixel field + if (fld != null && fld.getAsInt(0) != 1) { + throw new FopImageException("Error while loading image " + + this.m_href.toString() + " : " + + this.getClass() + " - " + + "unsupported samples per pixel value " + fld.getAsInt(0)); + } + + this.m_bitsPerPixel = 1; + fld = ifd.getField(0x102); // The bits per sample field + if (fld != null) { + this.m_bitsPerPixel = fld.getAsInt(0); + } + + this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_GRAY); + fld = ifd.getField(0x106); // The photometric interpretation field + if (fld != null) { + if (fld.getAsInt(0) == 0) { + // All is fine + } + else if (fld.getAsInt(0) == 2) { + this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); + } + else { + throw new FopImageException("Error while loading image " + + this.m_href.toString() + " : " + + this.getClass() + " - " + + "unsupported photometric interpretation value " + fld.getAsInt(0)); + } + } + + this.m_isTransparent = false; + + int comp = 1; + fld = ifd.getField(0x103); // The compression field + if (fld != null) { + comp = fld.getAsInt(0); + } + if (comp == 1) { + } + else if (comp == 3) { + this.m_compressionType = new CCFFilter(); + this.m_compressionType.setApplied(true); + } + else if (comp == 4) { + CCFFilter ccf = new CCFFilter(); + this.m_compressionType = ccf; + this.m_compressionType.setApplied(true); + ccf.setDecodeParms("<< /K -1 /Columns " + this.m_width + " >>"); + } + else if (comp == 6) { + this.m_compressionType = new DCTFilter(); + this.m_compressionType.setApplied(true); + } + else { + throw new FopImageException("Error while loading image " + + this.m_href.toString() + " : " + + this.getClass() + " - " + + "unsupported compression value " + comp); + } + + fld = ifd.getField(0x116); // The rows per strip field + if (fld != null) { + if (this.m_height != fld.getAsLong(0)) { + throw new FopImageException("Error while loading image " + + this.m_href.toString() + " : " + + this.getClass() + " - " + + "only single strip images supported "); + } + } + long offset = ifd.getFieldAsLong(0x111); + long length = ifd.getFieldAsLong(0x117); + + byte[] readBuf = new byte[(int)length]; + int bytes_read; + + inputStream.close(); + inputStream = this.m_href.openStream(); + inputStream.skip(offset); + bytes_read = inputStream.read(readBuf); + if (bytes_read != length) { + throw new FopImageException("Error while loading image " + + this.m_href.toString() + " : " + + this.getClass() + " - " + + "length mismatch on read"); + } + + this.m_bitmaps = readBuf; + } catch (FopImageException fie) { + org.apache.fop.messaging.MessageHandler.logln("Reverting to TIFF image handling through JAI: " + + fie.getMessage()); + this.m_compressionType = null; + super.loadImage(); + } catch (Exception ex) { + throw new FopImageException("Error while loading image " + + this.m_href.toString() + " : " + + ex.getClass() + " - " + + ex.getMessage()); + } + } + +} + diff --git a/src/org/apache/fop/messaging/MessageHandler.java b/src/org/apache/fop/messaging/MessageHandler.java index a21ed2daf..68ec86892 100644 --- a/src/org/apache/fop/messaging/MessageHandler.java +++ b/src/org/apache/fop/messaging/MessageHandler.java @@ -87,42 +87,43 @@ public class MessageHandler { * @param message the message for the user */ public static void log(String message) { - if (quiet) - return; + if (quiet) { + return; + } + + if (logger == null) { + logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); + logger.warn("Screen logger not set."); + } - if (logger == null) { - logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); - logger.warn("Screen logger not set."); - } - - setMessage(message); - switch (outputMethod) { - case SCREEN: - logger.debug(getMessage()); - break; - case FILE: - if (fileOpened) { - writer.print(getMessage()); - writer.flush(); - } else { - openFile(); - writer.print(getMessage()); - writer.flush(); - } - break; - case EVENT: - setMessage(message); - Enumeration enum = listeners.elements(); - while (enum.hasMoreElements()) { - ((MessageListener)enum.nextElement()).processMessage(new MessageEvent(getMessage())); - } - break; - case NONE: - // do nothing - break; - default: - logger.debug(message); - } + setMessage(message); + switch (outputMethod) { + case SCREEN: + logger.info(getMessage()); + break; + case FILE: + if (fileOpened) { + writer.print(getMessage()); + writer.flush(); + } else { + openFile(); + writer.print(getMessage()); + writer.flush(); + } + break; + case EVENT: + setMessage(message); + Enumeration enum = listeners.elements(); + while (enum.hasMoreElements()) { + ((MessageListener)enum.nextElement()).processMessage(new MessageEvent(getMessage())); + } + break; + case NONE: + // do nothing + break; + default: + logger.info(message); + } } /** @@ -139,10 +140,10 @@ public class MessageHandler { */ public static void error(String errorMessage) { - if (logger == null) { - logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); - logger.warn("Screen logger not set."); - } + if (logger == null) { + logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); + logger.warn("Screen logger not set."); + } setMessage(errorMessage); switch (outputMethod) { @@ -205,9 +206,9 @@ public class MessageHandler { * @param newLogger a logger for screen output. This may not be null. */ public static void setScreenLogger(Logger newLogger) { - if (newLogger == null) - throw new NullPointerException(); - logger = newLogger; + if (newLogger == null) + throw new NullPointerException(); + logger = newLogger; } /** diff --git a/src/org/apache/fop/pdf/CCFFilter.java b/src/org/apache/fop/pdf/CCFFilter.java new file mode 100755 index 000000000..17c45389f --- /dev/null +++ b/src/org/apache/fop/pdf/CCFFilter.java @@ -0,0 +1,42 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.pdf; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + + +/** + * CCF Filter class. Right now it is just used as a dummy filter flag so + * we can write TIFF images to the PDF. The encode method just returns the + * data passed to it. In the future an actual CCITT Group 4 compression should be + * added to the encode method so other images can be compressed. + * + * @author Manuel Mall + */ +public class CCFFilter extends PDFFilter { + + private String m_decodeParms; + + public String getName() { + return "/CCITTFaxDecode"; + } + + public String getDecodeParms() { + return this.m_decodeParms; + } + + public void setDecodeParms(String decodeParms) { + this.m_decodeParms = decodeParms; + } + + public byte[] encode(byte[] data) { + return data; + } +} + diff --git a/src/org/apache/fop/pdf/PDFXObject.java b/src/org/apache/fop/pdf/PDFXObject.java index f16e50fe3..4783df74c 100644 --- a/src/org/apache/fop/pdf/PDFXObject.java +++ b/src/org/apache/fop/pdf/PDFXObject.java @@ -187,12 +187,19 @@ public class PDFXObject extends PDFObject { * Added by Eric Dalquist * If the DCT filter hasn't been added to the object we add it here */ + /* + * Added by Manuel Mall + * Only add the default filters if we don't have an image filter to + * avoid double encoding of images + */ + if (fopimage.getPDFFilter() != null) { imgStream.addFilter(fopimage.getPDFFilter()); + } else { + imgStream.addDefaultFilters(); } - imgStream.addDefaultFilters(); - + String dictEntries = imgStream.applyFilters(); String p = this.number + " " + this.generation + " obj\n"; diff --git a/src/org/apache/fop/tools/anttasks/Fop.java b/src/org/apache/fop/tools/anttasks/Fop.java index bd914fb0a..5decb0eb6 100644 --- a/src/org/apache/fop/tools/anttasks/Fop.java +++ b/src/org/apache/fop/tools/anttasks/Fop.java @@ -194,8 +194,8 @@ class FOPTaskStarter extends Starter { FOPTaskStarter(Fop task) throws FOPException { this.task = task; - log = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); - MessageHandler.setScreenLogger(log); + log = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); + MessageHandler.setScreenLogger(log); } private int determineRenderer(String format) { @@ -264,17 +264,22 @@ class FOPTaskStarter extends Starter { try { if (task.getFofile() != null) { - Configuration.put("baseDir", - task.getFofile().getParentFile().toURL(). - toExternalForm()); + if (task.getBasedir() != null) { + Configuration.put("baseDir", + task.getBasedir().toURL(). + toExternalForm()); + } else { + Configuration.put("baseDir", + task.getFofile().getParentFile().toURL(). + toExternalForm()); + } } + task.log("Using base directory: " + + Configuration.getValue("baseDir"), Project.MSG_DEBUG); } catch (Exception e) { log.error("Error setting base directory",e); } - task.log("Using base directory: " + - Configuration.getValue("baseDir"), Project.MSG_DEBUG); - int rint = determineRenderer(task.getFormat()); String newExtension = determineExtension(rint); @@ -308,13 +313,19 @@ class FOPTaskStarter extends Starter { outf = new File(task.getOutdir(), outf.getName()); } try { - Configuration.put("baseDir", - fs.getDir(task.getProject()).toURL(). - toExternalForm()); - + if (task.getBasedir() != null) { + Configuration.put("baseDir", + task.getBasedir().toURL(). + toExternalForm()); + } else { + Configuration.put("baseDir", + fs.getDir(task.getProject()).toURL(). + toExternalForm()); + } + task.log("Using base directory: " + + Configuration.getValue("baseDir"), Project.MSG_DEBUG); } catch (Exception e) { - task.log("Error setting base directory", - Project.MSG_DEBUG); + log.error("Error setting base directory", e); } render(f, outf, rint); @@ -348,11 +359,11 @@ class FOPTaskStarter extends Starter { Driver driver = new Driver(inputHandler.getInputSource(), out); driver.setLogger(log); driver.setRenderer(renderer); - if (renderer == Driver.RENDER_XML) { - HashMap rendererOptions = new HashMap(); - rendererOptions.put("fineDetail", new Boolean(true)); - driver.getRenderer().setOptions(rendererOptions); - } + if (renderer == Driver.RENDER_XML) { + HashMap rendererOptions = new HashMap(); + rendererOptions.put("fineDetail", new Boolean(true)); + driver.getRenderer().setOptions(rendererOptions); + } driver.setXMLReader(parser); driver.run(); out.close(); |