Hi guys,
These patches have nothing to do with your recent request for more information about the PDFTranscoder. The most important one is the fix for getPixelUnitToMillimeter which currently causes PDF output to be the wrong size.
The other patches enable the JPEG code to work correctly for JPEG files that have lots of long APP markers in them. I think Photoshop and a few other apps can do this. It also defers the creation of the original node until it absolutely has to thus avoiding decoding the JPEG file and creating the raster unless needed.
Let me know if you have any questions on either of these and I will be looking to Jeremias's questions shortly.
? diffs ? foUnits.pdf ? pdfDPI.patch ? pdfImage.patch ? pdfJpeg.patch ? pdfTranscoder.patch Index: src/java/org/apache/fop/image/analyser/JPEGReader.java =================================================================== RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/image/analyser/JPEGReader.java,v retrieving revision 1.3 diff -w -u -r1.3 JPEGReader.java --- src/java/org/apache/fop/image/analyser/JPEGReader.java 27 Feb 2004 17:47:30 -0000 1.3 +++ src/java/org/apache/fop/image/analyser/JPEGReader.java 15 Aug 2004 17:54:47 -0000 @@ -98,17 +98,35 @@ private FopImage.ImageInfo getDimension(InputStream imageStream) throws IOException { FopImage.ImageInfo info = new FopImage.ImageInfo(); try { - imageStream.mark(imageStream.available()); + int pos=0, avail = imageStream.available(); + imageStream.mark(avail); int marker = NULL; long length, skipped; outer: - while (imageStream.available() > 0) { - while ((marker = imageStream.read()) != MARK) { - //nop, simply skip + while (true) { + do { + if (avail == 0) { + imageStream.reset(); + avail = 2*pos; + imageStream.mark(avail); + pos = (int)this.skip(imageStream, pos); + avail -= pos; } + marker = imageStream.read(); + pos++; avail--; + } while (marker != MARK); + do { + if (avail == 0) { + imageStream.reset(); + avail = 2*pos; + imageStream.mark(avail); + pos = (int)this.skip(imageStream, pos); + avail -= pos; + } marker = imageStream.read(); + pos++; avail--; } while (marker == MARK); switch (marker) { @@ -120,13 +138,42 @@ case SOF2: case SOF3: // SOF3 and SOFA are only supported by PDF 1.3 case SOFA: + while (avail < 7) { + imageStream.reset(); + avail = 2*pos; + imageStream.mark(avail); + pos = (int)this.skip(imageStream, pos); + avail -= pos; + } this.skip(imageStream, 3); + pos+=3; avail-=3; info.height = this.read2bytes(imageStream); + pos+=2; avail-=2; info.width = this.read2bytes(imageStream); + pos+=2; avail-=2; break outer; default: + while (avail < 2) { + imageStream.reset(); + avail = 2*pos; + imageStream.mark(avail); + pos = (int)this.skip(imageStream, pos); + avail -= pos; + } length = this.read2bytes(imageStream); + pos+=2; avail-=2; + if (avail < length) { + imageStream.reset(); + avail = 2*pos; + if (avail < pos+length+10) { + avail = (int)(pos+length+10); + } + imageStream.mark(avail); + pos = (int)this.skip(imageStream, pos); + avail -= pos; + } skipped = this.skip(imageStream, length - 2); + pos += skipped; avail -= skipped; if (skipped != length - 2) { throw new IOException("Skipping Error"); } Index: src/java/org/apache/fop/svg/PDFImageElementBridge.java =================================================================== RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/svg/PDFImageElementBridge.java,v retrieving revision 1.9 diff -w -u -r1.9 PDFImageElementBridge.java --- src/java/org/apache/fop/svg/PDFImageElementBridge.java 12 May 2004 23:19:53 -0000 1.9 +++ src/java/org/apache/fop/svg/PDFImageElementBridge.java 15 Aug 2004 17:54:48 -0000 @@ -27,6 +27,8 @@ import java.awt.Shape; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; +import java.io.BufferedInputStream; +import java.io.InputStream; import org.w3c.dom.Element; @@ -59,12 +61,20 @@ */ protected GraphicsNode createImageGraphicsNode (BridgeContext ctx, Element e, ParsedURL purl) { - GraphicsNode origGN = super.createImageGraphicsNode - (ctx, e, purl); try { + InputStream is = purl.openStream(); + if (!is.markSupported()) { + is = new BufferedInputStream(is, 1024); + } + + is.mark(3); + byte [] data = new byte[3]; + is.read(data); + is.reset(); + if ((data[0] == (byte)0xFF) && (data[1] == (byte)0xD8) && + (data[2] == (byte)0xFF)) { FopImage.ImageInfo ii = ImageReaderFactory.make - (purl.toString(), purl.openStream(), null); - if (ii.mimeType.toLowerCase() == "image/jpeg") { + (purl.toString(), is, null); JpegImage jpeg = new JpegImage(ii); SimpleLog logger = new SimpleLog("FOP/SVG"); logger.setLevel(SimpleLog.LOG_LEVEL_INFO); @@ -87,26 +97,37 @@ } catch (Exception ex) { } - return origGN; + return superCreateGraphicsNode(ctx, e, purl); } + protected GraphicsNode superCreateGraphicsNode + (BridgeContext ctx, Element e, ParsedURL purl) { + return super.createImageGraphicsNode(ctx, e, purl); + } + + /** * A PDF jpeg node. * This holds a jpeg image so that it can be drawn into * the PDFGraphics2D. */ - public static class PDFJpegNode extends AbstractGraphicsNode { + public class PDFJpegNode extends AbstractGraphicsNode { private JpegImage jpeg; - private GraphicsNode origGraphicsNode ; + private BridgeContext ctx; + private Element e; + private ParsedURL purl; + private GraphicsNode origGraphicsNode=null; /** * Create a new pdf jpeg node for drawing jpeg images * into pdf graphics. * @param j the jpeg image */ - public PDFJpegNode(JpegImage j, - GraphicsNode origGraphicsNode) { - jpeg = j; - this.origGraphicsNode = origGraphicsNode; + public PDFJpegNode(JpegImage j, BridgeContext ctx, + Element e, ParsedURL purl) { + this.jpeg = j; + this.ctx = ctx; + this.e = e; + this.purl = purl; } /** @@ -137,7 +158,14 @@ } } else { // Not going directly into PDF so use - // original implemtation so filters etc work. + // original implementation so filters etc work. + if (origGraphicsNode == null) { + // Haven't constructed baseclass Graphics Node, + // so do so now. + origGraphicsNode = + PDFImageElementBridge.this.superCreateGraphicsNode + (ctx, e, purl); + } origGraphicsNode.primitivePaint(g2d); } } Index: src/java/org/apache/fop/svg/PDFTranscoder.java =================================================================== RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/svg/PDFTranscoder.java,v retrieving revision 1.11 diff -w -u -r1.11 PDFTranscoder.java --- src/java/org/apache/fop/svg/PDFTranscoder.java 31 Mar 2004 10:55:07 -0000 1.11 +++ src/java/org/apache/fop/svg/PDFTranscoder.java 15 Aug 2004 17:54:48 -0000 @@ -83,7 +83,7 @@ return new AbstractFOPTranscoder.FOPTranscoderUserAgent() { // The PDF stuff wants everything at 72dpi public float getPixelUnitToMillimeter() { - return 0.3427778f; //72dpi + return 0.352778f; //72dpi } }; }