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]