diff options
-rw-r--r-- | src/java/org/apache/fop/image/analyser/JPEGReader.java | 55 | ||||
-rw-r--r-- | src/java/org/apache/fop/svg/PDFImageElementBridge.java | 54 |
2 files changed, 92 insertions, 17 deletions
diff --git a/src/java/org/apache/fop/image/analyser/JPEGReader.java b/src/java/org/apache/fop/image/analyser/JPEGReader.java index 21adf0c60..3aafbb8bc 100644 --- a/src/java/org/apache/fop/image/analyser/JPEGReader.java +++ b/src/java/org/apache/fop/image/analyser/JPEGReader.java @@ -98,17 +98,35 @@ public class JPEGReader implements ImageReader { 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 @@ outer: 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"); } diff --git a/src/java/org/apache/fop/svg/PDFImageElementBridge.java b/src/java/org/apache/fop/svg/PDFImageElementBridge.java index 567e0c46d..a77855ed0 100644 --- a/src/java/org/apache/fop/svg/PDFImageElementBridge.java +++ b/src/java/org/apache/fop/svg/PDFImageElementBridge.java @@ -27,6 +27,8 @@ import org.apache.fop.image.analyser.ImageReaderFactory; 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 @@ public class PDFImageElementBridge extends SVGImageElementBridge { */ 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 @@ public class PDFImageElementBridge extends SVGImageElementBridge { } 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 @@ public class PDFImageElementBridge extends SVGImageElementBridge { } } 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); } } |