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
             }
         };
     }

Reply via email to