jeremias    2004/08/16 12:33:19

  Modified:    src/java/org/apache/fop/svg PDFImageElementBridge.java
               src/java/org/apache/fop/image/analyser JPEGReader.java
  Log:
  Fix JPEG with many long APPS markers.
  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.
  Submitted by: Thomas DeWeese <Thomas.DeWeese.at.Kodak.com>
  
  Revision  Changes    Path
  1.10      +41 -13    xml-fop/src/java/org/apache/fop/svg/PDFImageElementBridge.java
  
  Index: PDFImageElementBridge.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/svg/PDFImageElementBridge.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- PDFImageElementBridge.java        12 May 2004 23:19:53 -0000      1.9
  +++ PDFImageElementBridge.java        16 Aug 2004 19:33:19 -0000      1.10
  @@ -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,17 +61,25 @@
        */
       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);
                   jpeg.load(FopImage.ORIGINAL_DATA);
  -                PDFJpegNode node = new PDFJpegNode(jpeg, origGN);
  +                PDFJpegNode node = new PDFJpegNode(jpeg, ctx, e, purl);
   
                   Rectangle2D imgBounds = getImageBounds(ctx, e);
               Rectangle2D bounds = node.getPrimitiveBounds();
  @@ -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);
               }
           }
  
  
  
  1.4       +51 -4     xml-fop/src/java/org/apache/fop/image/analyser/JPEGReader.java
  
  Index: JPEGReader.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/image/analyser/JPEGReader.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- JPEGReader.java   27 Feb 2004 17:47:30 -0000      1.3
  +++ JPEGReader.java   16 Aug 2004 19:33:19 -0000      1.4
  @@ -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");
                           }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to