diff options
38 files changed, 1185 insertions, 1279 deletions
diff --git a/src/org/apache/fop/apps/Driver.java b/src/org/apache/fop/apps/Driver.java index 5a49d02e2..e8be3c3ef 100644 --- a/src/org/apache/fop/apps/Driver.java +++ b/src/org/apache/fop/apps/Driver.java @@ -205,7 +205,9 @@ public class Driver { } private FOUserAgent getUserAgent() { - return new FOUserAgent(); + FOUserAgent ua = new FOUserAgent(); + ua.setLogger(log); + return ua; } public void setLogger(Logger logger) { diff --git a/src/org/apache/fop/area/inline/Space.java b/src/org/apache/fop/area/inline/Space.java index 7b98b3c17..1ba825524 100644 --- a/src/org/apache/fop/area/inline/Space.java +++ b/src/org/apache/fop/area/inline/Space.java @@ -10,6 +10,8 @@ package org.apache.fop.area.inline; import org.apache.fop.render.Renderer; public class Space extends Stretch { + public boolean collapse = true; + public boolean fixed = false; public void render(Renderer renderer) { renderer.renderInlineSpace(this); diff --git a/src/org/apache/fop/fo/FOUserAgent.java b/src/org/apache/fop/fo/FOUserAgent.java index 39f9b8bcf..c47bd3d2a 100644 --- a/src/org/apache/fop/fo/FOUserAgent.java +++ b/src/org/apache/fop/fo/FOUserAgent.java @@ -9,6 +9,7 @@ package org.apache.fop.fo; import org.apache.fop.render.XMLHandler; import org.apache.fop.render.RendererContext; +import org.apache.log.Logger; import org.w3c.dom.*; @@ -32,6 +33,15 @@ import java.util.HashMap; public class FOUserAgent { HashMap defaults = new HashMap(); HashMap handlers = new HashMap(); + Logger log; + + public void setLogger(Logger logger) { + log = logger; + } + + public Logger getLogger() { + return log; + } /** * Set the default xml handler for the given mime type. diff --git a/src/org/apache/fop/fo/flow/Character.java b/src/org/apache/fop/fo/flow/Character.java index 80cce3595..9f22c7c30 100644 --- a/src/org/apache/fop/fo/flow/Character.java +++ b/src/org/apache/fop/fo/flow/Character.java @@ -11,13 +11,18 @@ package org.apache.fop.fo.flow; import org.apache.fop.fo.*; import org.apache.fop.fo.properties.*; import org.apache.fop.datatypes.ColorType; -import org.apache.fop.layout.BlockArea; -import org.apache.fop.layout.*; -import org.apache.fop.layout.inline.InlineArea; import org.apache.fop.fo.FObj; import org.apache.fop.layout.FontState; -import org.apache.fop.layout.LineArea; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.HyphenationProps; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.RelativePositionProps; import org.apache.fop.apps.FOPException; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; /** @@ -43,14 +48,17 @@ public class Character extends FObj { super(parent); } - public Status layout(Area area) throws FOPException { - BlockArea blockArea; - if (!(area instanceof BlockArea)) { - log.warn("currently Character can only be in a BlockArea"); - return new Status(Status.OK); - } - blockArea = (BlockArea)area; - boolean textDecoration; + public LayoutManager getLayoutManager() { + LeafNodeLayoutManager lm = new LeafNodeLayoutManager(this); + lm.setCurrentArea(getInlineArea()); + return lm; + } + + protected InlineArea getInlineArea() { + return null; + } + + public void setup() throws FOPException { // Common Aural Properties AuralProps mAurProps = propMgr.getAuralProps(); @@ -94,58 +102,6 @@ public class Character extends FObj { // this.properties.get("text-shadow"); // this.properties.get("text-transform"); // this.properties.get("word-spacing"); - - // color properties - ColorType c = this.properties.get("color").getColorType(); - float red = c.red(); - float green = c.green(); - float blue = c.blue(); - - int whiteSpaceCollapse = - this.properties.get("white-space-collapse").getEnum(); - int wrapOption = ((FObj)this.parent).properties.get("wrap-option").getEnum(); - - int tmp = this.properties.get("text-decoration").getEnum(); - if (tmp == org.apache.fop.fo.properties.TextDecoration.UNDERLINE) { - textDecoration = true; - } else { - textDecoration = false; - } - - // Character specific properties - characterValue = this.properties.get("character").getCharacter(); - - - // initialize id - String id = this.properties.get("id").getString(); - blockArea.getIDReferences().initializeID(id, blockArea); - - LineArea la = blockArea.getCurrentLineArea(); - if (la == null) { - return new Status(Status.AREA_FULL_NONE); - } - la.changeFont(propMgr.getFontState(area.getFontInfo())); - la.changeColor(red, green, blue); - la.changeWrapOption(wrapOption); - la.changeWhiteSpaceCollapse(whiteSpaceCollapse); - blockArea.setupLinkSet(this.getLinkSet()); - int result = la.addCharacter(characterValue, this.getLinkSet(), - textDecoration); - if (result == Character.DOESNOT_FIT) { - la = blockArea.createNextLineArea(); - if (la == null) { - return new Status(Status.AREA_FULL_NONE); - } - la.changeFont(propMgr.getFontState(area.getFontInfo())); - la.changeColor(red, green, blue); - la.changeWrapOption(wrapOption); - la.changeWhiteSpaceCollapse(whiteSpaceCollapse); - blockArea.setupLinkSet(this.getLinkSet()); - la.addCharacter(characterValue, this.getLinkSet(), - textDecoration); - } - return new Status(Status.OK); - } public CharIterator charIterator() { diff --git a/src/org/apache/fop/fo/flow/ExternalGraphic.java b/src/org/apache/fop/fo/flow/ExternalGraphic.java index dac5ca9f9..386e475cd 100644 --- a/src/org/apache/fop/fo/flow/ExternalGraphic.java +++ b/src/org/apache/fop/fo/flow/ExternalGraphic.java @@ -13,13 +13,18 @@ import org.apache.fop.fo.properties.*; import org.apache.fop.layout.*; import org.apache.fop.apps.FOPException; import org.apache.fop.image.*; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; +import org.apache.fop.area.inline.Image; +import org.apache.fop.area.inline.Viewport; // Java import java.net.URL; import java.net.MalformedURLException; public class ExternalGraphic extends FObj { - + String url; int breakAfter; int breakBefore; int align; @@ -38,212 +43,67 @@ public class ExternalGraphic extends FObj { super(parent); } - public Status layout(Area area) throws FOPException { - - if (this.marker == START) { - - // Common Accessibility Properties - AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); - - // Common Aural Properties - AuralProps mAurProps = propMgr.getAuralProps(); - - // Common Border, Padding, and Background Properties - BorderAndPadding bap = propMgr.getBorderAndPadding(); - BackgroundProps bProps = propMgr.getBackgroundProps(); - - // Common Margin Properties-Inline - MarginInlineProps mProps = propMgr.getMarginInlineProps(); - - // Common Relative Position Properties - RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); - - // this.properties.get("alignment-adjust"); - // this.properties.get("alignment-baseline"); - // this.properties.get("baseline-shift"); - // this.properties.get("block-progression-dimension"); - // this.properties.get("content-height"); - // this.properties.get("content-type"); - // this.properties.get("content-width"); - // this.properties.get("display-align"); - // this.properties.get("dominant-baseline"); - // this.properties.get("height"); - // this.properties.get("id"); - // this.properties.get("inline-progression-dimension"); - // this.properties.get("keep-with-next"); - // this.properties.get("keep-with-previous"); - // this.properties.get("line-height"); - // this.properties.get("line-height-shift-adjustment"); - // this.properties.get("overflow"); - // this.properties.get("scaling"); - // this.properties.get("scaling-method"); - // this.properties.get("src"); - // this.properties.get("text-align"); - // this.properties.get("width"); - - // FIXME - this.align = this.properties.get("text-align").getEnum(); - - this.startIndent = - this.properties.get("start-indent").getLength().mvalue(); - this.endIndent = - this.properties.get("end-indent").getLength().mvalue(); - - this.spaceBefore = - this.properties.get("space-before.optimum").getLength().mvalue(); - this.spaceAfter = - this.properties.get("space-after.optimum").getLength().mvalue(); - - this.src = this.properties.get("src").getString(); - - this.width = this.properties.get("width").getLength().mvalue(); - - this.height = this.properties.get("height").getLength().mvalue(); - - this.id = this.properties.get("id").getString(); - - area.getIDReferences().createID(id); - /* - * if (area instanceof BlockArea) { - * area.end(); - * } - * if (this.isInTableCell) { - * startIndent += forcedStartOffset; - * endIndent = area.getAllocationWidth() - forcedWidth - - * forcedStartOffset; - * } - */ - this.marker = 0; - } - - try { - FopImage img = FopImageFactory.Make(src); - // if width / height needs to be computed - if ((width == 0) || (height == 0)) { - // aspect ratio - double imgWidth = img.getWidth(); - double imgHeight = img.getHeight(); - if ((width == 0) && (height == 0)) { - width = (int)((imgWidth * 1000d)); - height = (int)((imgHeight * 1000d)); - } else if (height == 0) { - height = (int)((imgHeight * ((double)width)) / imgWidth); - } else if (width == 0) { - width = (int)((imgWidth * ((double)height)) / imgHeight); - } - } - - // scale image if it doesn't fit in the area/page - // Need to be more tested... - double ratio = ((double)width) / ((double)height); - int areaWidth = area.getAllocationWidth() - startIndent - - endIndent; - int pageHeight = area.getPage().getBody().getMaxHeight() - - spaceBefore; - if (height > pageHeight) { - height = pageHeight; - width = (int)(ratio * ((double)height)); - } - if (width > areaWidth) { - width = areaWidth; - height = (int)(((double)width) / ratio); - } - - if (area.spaceLeft() < (height + spaceBefore)) { - return new Status(Status.AREA_FULL_NONE); - } - - this.imageArea = - new ImageArea(propMgr.getFontState(area.getFontInfo()), img, - area.getAllocationWidth(), width, height, - startIndent, endIndent, align); - - if ((spaceBefore != 0) && (this.marker == 0)) { - area.addDisplaySpace(spaceBefore); - } - - if (marker == 0) { - // configure id - area.getIDReferences().configureID(id, area); - } - - imageArea.start(); - imageArea.end(); - // area.addChild(imageArea); - // area.increaseHeight(imageArea.getHeight()); - - if (spaceAfter != 0) { - area.addDisplaySpace(spaceAfter); - } - if (breakBefore == BreakBefore.PAGE - || ((spaceBefore + imageArea.getHeight()) - > area.spaceLeft())) { - return new Status(Status.FORCE_PAGE_BREAK); - } - - if (breakBefore == BreakBefore.ODD_PAGE) { - return new Status(Status.FORCE_PAGE_BREAK_ODD); - } - - if (breakBefore == BreakBefore.EVEN_PAGE) { - return new Status(Status.FORCE_PAGE_BREAK_EVEN); - } - - - if (area instanceof BlockArea) { - BlockArea ba = (BlockArea)area; - LineArea la = ba.getCurrentLineArea(); - if (la == null) { - return new Status(Status.AREA_FULL_NONE); - } - la.addPending(); - if (imageArea.getContentWidth() > la.getRemainingWidth()) { - la = ba.createNextLineArea(); - if (la == null) { - return new Status(Status.AREA_FULL_NONE); - } - } - la.addInlineArea(imageArea); - } else { - area.addChild(imageArea); - area.increaseHeight(imageArea.getContentHeight()); - } - imageArea.setPage(area.getPage()); - - if (breakAfter == BreakAfter.PAGE) { - this.marker = BREAK_AFTER; - return new Status(Status.FORCE_PAGE_BREAK); - } - - if (breakAfter == BreakAfter.ODD_PAGE) { - this.marker = BREAK_AFTER; - return new Status(Status.FORCE_PAGE_BREAK_ODD); - } - - if (breakAfter == BreakAfter.EVEN_PAGE) { - this.marker = BREAK_AFTER; - return new Status(Status.FORCE_PAGE_BREAK_EVEN); - } - - - - - - } catch (MalformedURLException urlex) { - // bad URL - log.error("Error while creating area : " - + urlex.getMessage()); - } catch (FopImageException imgex) { - // image error - log.error("Error while creating area : " - + imgex.getMessage()); - } - - // if (area instanceof BlockArea) { - // area.start(); + public LayoutManager getLayoutManager() { + LeafNodeLayoutManager lm = new LeafNodeLayoutManager(this); + lm.setCurrentArea(getInlineArea()); + return lm; + } + + protected InlineArea getInlineArea() { + url = ImageFactory.getURL(url); + // if we need to load this image to get its size + // FopImage fopimage = ImageFactory.getImage(url, userAgent); + // if(fopimage == null) { + // error // } + // if(!fopimage.load(FopImage.DIMENSIONS)) { + // error + // } + Image imArea = new Image(url); + Viewport vp = new Viewport(imArea); + return vp; + } - return new Status(Status.OK); + public void setup() throws FOPException { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("alignment-adjust"); + // this.properties.get("alignment-baseline"); + // this.properties.get("baseline-shift"); + // this.properties.get("block-progression-dimension"); + // this.properties.get("content-height"); + // this.properties.get("content-type"); + // this.properties.get("content-width"); + // this.properties.get("display-align"); + // this.properties.get("dominant-baseline"); + // this.properties.get("height"); + // this.properties.get("id"); + // this.properties.get("inline-progression-dimension"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("overflow"); + // this.properties.get("scaling"); + // this.properties.get("scaling-method"); + // this.properties.get("src"); + // this.properties.get("text-align"); + // this.properties.get("width"); } } diff --git a/src/org/apache/fop/fo/flow/InstreamForeignObject.java b/src/org/apache/fop/fo/flow/InstreamForeignObject.java index 107ce8081..6afff0cac 100644 --- a/src/org/apache/fop/fo/flow/InstreamForeignObject.java +++ b/src/org/apache/fop/fo/flow/InstreamForeignObject.java @@ -23,7 +23,7 @@ import org.apache.fop.layout.MarginInlineProps; import org.apache.fop.layout.RelativePositionProps; import org.apache.fop.apps.FOPException; import org.apache.fop.layoutmgr.LayoutManager; -import org.apache.fop.layoutmgr.SplitContext; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; import org.w3c.dom.Document; @@ -58,28 +58,9 @@ public class InstreamForeignObject extends FObj { } public LayoutManager getLayoutManager() { - return new LayoutManager() { - LayoutManager lm; - public void generateAreas() { - lm.addChild(getInlineArea()); - } - - public Area getParentArea (Area childArea) { - return null; - } - - public void addChild (Area childArea) { - } - - public boolean splitArea(Area areaToSplit, SplitContext context) { - return false; - } - - public void setParentLM(LayoutManager lm) { - this.lm = lm; - } - - }; + LeafNodeLayoutManager lm = new LeafNodeLayoutManager(this); + lm.setCurrentArea(getInlineArea()); + return lm; } /** diff --git a/src/org/apache/fop/fo/flow/Leader.java b/src/org/apache/fop/fo/flow/Leader.java index 642b20dcd..7089ce78a 100644 --- a/src/org/apache/fop/fo/flow/Leader.java +++ b/src/org/apache/fop/fo/flow/Leader.java @@ -11,12 +11,15 @@ package org.apache.fop.fo.flow; import org.apache.fop.fo.*; import org.apache.fop.fo.properties.*; import org.apache.fop.datatypes.*; +import org.apache.fop.area.inline.InlineArea; import org.apache.fop.layout.*; import org.apache.fop.layout.BlockArea; import org.apache.fop.layout.inline.LeaderArea; import org.apache.fop.layout.LineArea; import org.apache.fop.layout.FontState; import org.apache.fop.apps.FOPException; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; /** * Implements fo:leader; main property of leader leader-pattern. @@ -29,6 +32,16 @@ public class Leader extends FObjMixed { super(parent); } + public LayoutManager getLayoutManager() { + LeafNodeLayoutManager lm = new LeafNodeLayoutManager(this); + lm.setCurrentArea(getInlineArea()); + return lm; + } + + protected InlineArea getInlineArea() { + return null; + } + public Status layout(Area area) throws FOPException { BlockArea blockArea; // restriction in this version diff --git a/src/org/apache/fop/fo/flow/Wrapper.java b/src/org/apache/fop/fo/flow/Wrapper.java index f31e4764e..53f728bd5 100644 --- a/src/org/apache/fop/fo/flow/Wrapper.java +++ b/src/org/apache/fop/fo/flow/Wrapper.java @@ -25,7 +25,6 @@ public class Wrapper extends FObjMixed { public Wrapper(FONode parent) { super(parent); - // check that this occurs inside an fo:flow } } diff --git a/src/org/apache/fop/image/AbstractFopImage.java b/src/org/apache/fop/image/AbstractFopImage.java index 4669758c7..f55d4f01c 100644 --- a/src/org/apache/fop/image/AbstractFopImage.java +++ b/src/org/apache/fop/image/AbstractFopImage.java @@ -8,7 +8,6 @@ package org.apache.fop.image; // Java -import java.util.Hashtable; import java.net.URL; // FOP @@ -17,6 +16,7 @@ import org.apache.fop.pdf.PDFColor; import org.apache.fop.pdf.PDFFilter; import org.apache.fop.image.analyser.ImageReaderFactory; import org.apache.fop.image.analyser.ImageReader; +import org.apache.fop.fo.FOUserAgent; /** * Base class to implement the FopImage interface. @@ -25,6 +25,7 @@ import org.apache.fop.image.analyser.ImageReader; * @see FopImage */ public abstract class AbstractFopImage implements FopImage { + protected int loaded = 0; /** * Image width (in pixel). @@ -91,49 +92,53 @@ public abstract class AbstractFopImage implements FopImage { * </UL> * The image data isn't kept in memory. * @param href image URL - * @return a new FopImage object - * @exception FopImageException an error occured during initialization - */ - public AbstractFopImage(URL href) throws FopImageException { - this.m_href = href; - try { - this.m_imageReader = - ImageReaderFactory.Make(this.m_href.toExternalForm(), - this.m_href.openStream()); - } catch (Exception e) { - throw new FopImageException(e.getMessage()); - } - this.m_width = this.m_imageReader.getWidth(); - this.m_height = this.m_imageReader.getHeight(); - } - - /** - * Constructor. - * Construct a new FopImage object and initialize its default properties: - * <UL> - * <LI>image width - * <LI>image height - * </UL> - * The image data isn't kept in memory. - * @param href image URL * imgReader ImageReader object * @return a new FopImage object - * @exception FopImageException an error occured during initialization */ - public AbstractFopImage(URL href, - ImageReader imgReader) throws FopImageException { + public AbstractFopImage(URL href, ImageReader imgReader) { this.m_href = href; this.m_imageReader = imgReader; this.m_width = this.m_imageReader.getWidth(); this.m_height = this.m_imageReader.getHeight(); + loaded = loaded & DIMENSIONS; + } + + public String getMimeType() { + return m_imageReader.getMimeType(); } /** * Load image data and initialize its properties. - * Subclasses need to implement this method. - * @exception FopImageException an error occured during loading */ - abstract protected void loadImage() throws FopImageException; + public synchronized boolean load(int type, FOUserAgent ua) { + if((loaded & type) != 0) { + return true; + } + boolean success = true; + if(((type & DIMENSIONS) != 0) && ((loaded & DIMENSIONS) == 0)) { + success = success && loadDimensions(ua); + + if(!success) { + return false; + } + loaded = loaded & DIMENSIONS; + } + if(((type & BITMAP) != 0) && ((loaded & BITMAP) == 0)) { + success = success && loadBitmap(ua); + if(success) { + loaded = loaded & BITMAP; + } + } + return success; + } + + protected boolean loadDimensions(FOUserAgent ua) { + return false; + } + + protected boolean loadBitmap(FOUserAgent ua) { + return false; + } /** * Return the image URL. @@ -146,149 +151,96 @@ public abstract class AbstractFopImage implements FopImage { /** * Return the image width. * @return the image width - * @exception FopImageException an error occured during property retriaval */ - public int getWidth() throws FopImageException { - if (this.m_width == 0) - this.loadImage(); - + public int getWidth() { return this.m_width; } /** * Return the image height. * @return the image height - * @exception FopImageException an error occured during property retriaval */ - public int getHeight() throws FopImageException { - if (this.m_height == 0) - this.loadImage(); - + public int getHeight() { return this.m_height; } /** * Return the image color space. * @return the image color space (org.apache.fop.datatypes.ColorSpace) - * @exception FopImageException an error occured during property retriaval */ - public ColorSpace getColorSpace() throws FopImageException { - if (this.m_colorSpace == null) - this.loadImage(); - + public ColorSpace getColorSpace() { return this.m_colorSpace; } /** * Return the number of bits per pixel. * @return number of bits per pixel - * @exception FopImageException an error occured during property retriaval */ - public int getBitsPerPixel() throws FopImageException { - if (this.m_bitsPerPixel == 0) - this.loadImage(); - + public int getBitsPerPixel() { return this.m_bitsPerPixel; } /** * Return the image transparency. * @return true if the image is transparent - * @exception FopImageException an error occured during property retriaval */ - public boolean isTransparent() throws FopImageException { + public boolean isTransparent() { return this.m_isTransparent; } /** * Return the transparent color. * @return the transparent color (org.apache.fop.pdf.PDFColor) - * @exception FopImageException an error occured during property retriaval */ - public PDFColor getTransparentColor() throws FopImageException { + public PDFColor getTransparentColor() { return this.m_transparentColor; } /** * Return the image data (uncompressed). * @return the image data - * @exception FopImageException an error occured during loading */ - public byte[] getBitmaps() throws FopImageException { - if (this.m_bitmaps == null) - this.loadImage(); - + public byte[] getBitmaps() { return this.m_bitmaps; } /** * Return the image data size (uncompressed). * @return the image data size - * @exception FopImageException an error occured during loading */ - public int getBitmapsSize() throws FopImageException { - if (this.m_bitmapsSize == 0) - this.loadImage(); - + public int getBitmapsSize() { return this.m_bitmapsSize; } /** * Return the original image data (compressed). * @return the original image data - * @exception FopImageException an error occured during loading */ - public byte[] getRessourceBytes() throws FopImageException { + public byte[] getRessourceBytes() { return null; } /** * Return the original image data size (compressed). * @return the original image data size - * @exception FopImageException an error occured during loading */ - public int getRessourceBytesSize() throws FopImageException { + public int getRessourceBytesSize() { return 0; } /** * Return the original image compression type. * @return the original image compression type (org.apache.fop.pdf.PDFFilter) - * @exception FopImageException an error occured during loading */ - public PDFFilter getPDFFilter() throws FopImageException { + public PDFFilter getPDFFilter() { /* * Added by Eric Dalquist * Using the bitsPerPixel var as our flag since many imges will * have a null m_compressionType even after being loaded */ - if (this.m_bitsPerPixel == 0) - this.loadImage(); - return m_compressionType; } - /** - * Free all ressource. - */ - public void close() { - /* - * For the moment, only release the bitmaps (image areas - * can share the same FopImage object) - * Thus, even if it had been called, other properties - * are still available. - */ - // this.m_width = 0; - // this.m_height = 0; - // this.m_href = null; - // this.m_colorSpace = null; - // this.m_bitsPerPixel = 0; - this.m_bitmaps = null; - this.m_bitmapsSize = 0; - // this.m_isTransparent = false; - // this.m_transparentColor = null; - } - } diff --git a/src/org/apache/fop/image/BmpImage.java b/src/org/apache/fop/image/BmpImage.java index 6918d2604..7d2c275e7 100644 --- a/src/org/apache/fop/image/BmpImage.java +++ b/src/org/apache/fop/image/BmpImage.java @@ -23,20 +23,16 @@ import java.io.IOException; import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.image.analyser.ImageReader; +import org.apache.fop.fo.FOUserAgent; public class BmpImage extends AbstractFopImage { - public BmpImage(URL href) throws FopImageException { - super(href); - } - - public BmpImage(URL href, - ImageReader imgReader) throws FopImageException { + public BmpImage(URL href, ImageReader imgReader) { super(href, imgReader); } - protected void loadImage() throws FopImageException { + protected boolean loadBitmap(FOUserAgent ua) { int wpos = 18; - int hpos = 22; // offset positioning for w and height in bmp files + int hpos = 22; // offset positioning for w and height in bmp files int[] headermap = new int[54]; int filepos = 0; InputStream file = null; @@ -63,8 +59,8 @@ public class BmpImage extends AbstractFopImage { if (input == -1) eof = true; else if (count2 >= 0) { - palette[countr * 3 + count2] = (byte)(input - & 0xFF); + palette[countr * 3 + count2] = + (byte)(input & 0xFF); } count2--; filepos++; @@ -73,35 +69,37 @@ public class BmpImage extends AbstractFopImage { } } } catch (IOException e) { - throw new FopImageException("Error while loading image " - + this.m_href.toString() + " : " - + e.getClass() + " - " - + e.getMessage()); + ua.getLogger().error("Error while loading image " + + this.m_href.toString() + " : " + + e.getClass() + " - " + + e.getMessage(), e); + return false; } // gets h & w from headermap - this.m_width = headermap[wpos] + headermap[wpos + 1] * 256 - + headermap[wpos + 2] * 256 * 256 - + headermap[wpos + 3] * 256 * 256 * 256; - this.m_height = headermap[hpos] + headermap[hpos + 1] * 256 - + headermap[hpos + 2] * 256 * 256 - + headermap[hpos + 3] * 256 * 256 * 256; + this.m_width = headermap[wpos] + headermap[wpos + 1] * 256 + + headermap[wpos + 2] * 256 * 256 + + headermap[wpos + 3] * 256 * 256 * 256; + this.m_height = headermap[hpos] + headermap[hpos + 1] * 256 + + headermap[hpos + 2] * 256 * 256 + + headermap[hpos + 3] * 256 * 256 * 256; - int imagestart = headermap[10] + headermap[11] * 256 - + headermap[12] * 256 * 256 - + headermap[13] * 256 * 256 * 256; + int imagestart = headermap[10] + headermap[11] * 256 + + headermap[12] * 256 * 256 + headermap[13] * 256 * 256 * 256; this.m_bitsPerPixel = headermap[28]; this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); - int bytes; + int bytes = 0; if (this.m_bitsPerPixel == 1) bytes = (this.m_width + 7) / 8; else if (this.m_bitsPerPixel == 24) bytes = this.m_width * 3; else if (this.m_bitsPerPixel == 4 || this.m_bitsPerPixel == 8) bytes = this.m_width / (8 / this.m_bitsPerPixel); - else - throw new FopImageException("Image (" + this.m_href.toString() - + ") has " + this.m_bitsPerPixel - + " which is not a supported BMP format."); + else { + ua.getLogger().error("Image (" + this.m_href.toString() + + ") has " + this.m_bitsPerPixel + + " which is not a supported BMP format."); + return false; + } if ((bytes & 0x03) != 0) { bytes |= 0x03; bytes++; @@ -120,10 +118,11 @@ public class BmpImage extends AbstractFopImage { temp[count++] = input; file.close(); } catch (IOException e) { - throw new FopImageException("Error while loading image " - + this.m_href.toString() + " : " - + e.getClass() + " - " - + e.getMessage()); + ua.getLogger().error("Error while loading image " + + this.m_href.toString() + " : " + + e.getClass() + " - " + + e.getMessage(), e); + return false; } for (int i = 0; i < this.m_height; i++) { @@ -135,44 +134,46 @@ public class BmpImage extends AbstractFopImage { if (this.m_bitsPerPixel == 24 && x < this.m_width) { int countr = 2; do { - this.m_bitmaps[3 * (i * this.m_width + x) + countr] = - (byte)(temp[(this.m_height - i - 1) * bytes + j] - & 0xFF); + this.m_bitmaps[3 * (i * this.m_width + x) + + countr] = + (byte)(temp[(this.m_height - i - 1) * + bytes + j] & 0xFF); j++; - } while (--countr >= 0); + } while (--countr >= 0) + ; x++; } else if (this.m_bitsPerPixel == 1) { - for (int countr = 0; countr < 8 && x < this.m_width; - countr++) { + for (int countr = 0; + countr < 8 && x < this.m_width; countr++) { if ((p & 0x80) != 0) { - this.m_bitmaps[3 * (i * this.m_width + x)] = - (byte)0xFF; - this.m_bitmaps[3 * (i * this.m_width + x) + 1] = - (byte)0xFF; - this.m_bitmaps[3 * (i * this.m_width + x) + 2] = - (byte)0xFF; + this.m_bitmaps[3 * + (i * this.m_width + x)] = (byte) 0xFF; + this.m_bitmaps[3 * (i * this.m_width + x) + + 1] = (byte) 0xFF; + this.m_bitmaps[3 * (i * this.m_width + x) + + 2] = (byte) 0xFF; } else { - this.m_bitmaps[3 * (i * this.m_width + x)] = - (byte)0; - this.m_bitmaps[3 * (i * this.m_width + x) + 1] = - (byte)0; - this.m_bitmaps[3 * (i * this.m_width + x) + 2] = - (byte)0; + this.m_bitmaps[3 * + (i * this.m_width + x)] = (byte) 0; + this.m_bitmaps[3 * (i * this.m_width + x) + + 1] = (byte) 0; + this.m_bitmaps[3 * (i * this.m_width + x) + + 2] = (byte) 0; } p <<= 1; x++; } j++; } else if (this.m_bitsPerPixel == 4) { - for (int countr = 0; countr < 2 && x < this.m_width; - countr++) { + for (int countr = 0; + countr < 2 && x < this.m_width; countr++) { int pal = ((p & 0xF0) >> 4) * 3; this.m_bitmaps[3 * (i * this.m_width + x)] = - palette[pal]; - this.m_bitmaps[3 * (i * this.m_width + x) + 1] = - palette[pal + 1]; - this.m_bitmaps[3 * (i * this.m_width + x) + 2] = - palette[pal + 2]; + palette[pal]; + this.m_bitmaps[3 * (i * this.m_width + x) + + 1] = palette[pal + 1]; + this.m_bitmaps[3 * (i * this.m_width + x) + + 2] = palette[pal + 2]; p <<= 4; x++; } @@ -181,11 +182,11 @@ public class BmpImage extends AbstractFopImage { if (x < this.m_width) { p *= 3; this.m_bitmaps[3 * (i * this.m_width + x)] = - palette[p]; - this.m_bitmaps[3 * (i * this.m_width + x) + 1] = - palette[p + 1]; - this.m_bitmaps[3 * (i * this.m_width + x) + 2] = - palette[p + 2]; + palette[p]; + this.m_bitmaps[3 * (i * this.m_width + x) + + 1] = palette[p + 1]; + this.m_bitmaps[3 * (i * this.m_width + x) + + 2] = palette[p + 2]; j++; x++; } else @@ -199,6 +200,8 @@ public class BmpImage extends AbstractFopImage { // m_bitsPerPixel to 8. If I do not do this Acrobat is unable to read the resultant PDF, // so we will hardcode this... this.m_bitsPerPixel = 8; + + return true; } } diff --git a/src/org/apache/fop/image/EPSImage.java b/src/org/apache/fop/image/EPSImage.java index e766fb733..bef874847 100644 --- a/src/org/apache/fop/image/EPSImage.java +++ b/src/org/apache/fop/image/EPSImage.java @@ -31,64 +31,54 @@ import org.xml.sax.XMLReader; public class EPSImage extends AbstractFopImage { private String docName; private int[] bbox; - + private byte[] epsImage = null; private EPSReader epsReader = null; - - /** - * Initialize docName and bounding box - */ + + /** + * Initialize docName and bounding box + */ private void init(URL href) { bbox = new int[4]; bbox[0] = 0; bbox[1] = 0; bbox[2] = 0; bbox[3] = 0; - + docName = href.toString(); } - - /** - * Return the name of the eps - */ + + /** + * Return the name of the eps + */ public String getDocName() { return docName; } - - /** - * Return the bounding box - */ + + /** + * Return the bounding box + */ public int[] getBBox() { return bbox; } - - public EPSImage(URL href) throws FopImageException { - super(href); - init(href); - } - - public EPSImage(URL href, - ImageReader imgReader) throws FopImageException { + + public EPSImage(URL href, ImageReader imgReader) { super(href, imgReader); init(href); if (imgReader instanceof EPSReader) { - EPSReader eimgReader = (EPSReader)imgReader; + EPSReader eimgReader = (EPSReader) imgReader; epsReader = eimgReader; epsImage = eimgReader.getEpsFile(); m_bitmaps = epsImage; bbox = eimgReader.getBBox(); } } - - protected void loadImage() throws FopImageException { - // Image is loaded in reader - } - - public byte[] getEPSImage() throws FopImageException { - if (epsImage == null) { + + public byte[] getEPSImage() { + if (epsImage == null) { //log.error("ERROR LOADING EXTERNAL EPS"); } return epsImage; } - + } diff --git a/src/org/apache/fop/image/FopImage.java b/src/org/apache/fop/image/FopImage.java index 2cbcc45c5..6cb674988 100644 --- a/src/org/apache/fop/image/FopImage.java +++ b/src/org/apache/fop/image/FopImage.java @@ -13,50 +13,53 @@ package org.apache.fop.image; import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.pdf.PDFFilter; +import org.apache.fop.fo.FOUserAgent; public interface FopImage { - // Init the object. - // If href protocol isn't file://, can load the entire image - // and keep it in memory. - // Should cache the input stream, and load data when needed. - // public FopImage(URL href) throws FopImageException; + public static final int DIMENSIONS = 1; + public static final int ORIGINAL_DATA = 2; + public static final int BITMAP = 4; - // Get image general properties. - // Methods throw exception because they can retrieve data - // when needed. + public String getMimeType(); + + /** + * Load particular inforamtion for this image + * This must be called before attempting to get + * the information. + * @return boolean true if the information could be loaded + */ + public boolean load(int type, FOUserAgent ua); // Ressource location public String getURL(); // image size - public int getWidth() throws FopImageException; - public int getHeight() throws FopImageException; + public int getWidth(); + public int getHeight(); // DeviceGray, DeviceRGB, or DeviceCMYK - public ColorSpace getColorSpace() throws FopImageException; + public ColorSpace getColorSpace(); // bits per pixel - public int getBitsPerPixel() throws FopImageException; + public int getBitsPerPixel(); // For transparent images - public boolean isTransparent() throws FopImageException; - public PDFColor getTransparentColor() throws FopImageException; + public boolean isTransparent(); + public PDFColor getTransparentColor(); // get the image bytes, and bytes properties // get uncompressed image bytes - public byte[] getBitmaps() throws FopImageException; + public byte[] getBitmaps(); // width * (bitsPerPixel / 8) * height, no ? - public int getBitmapsSize() throws FopImageException; + public int getBitmapsSize(); // get compressed image bytes // I don't know if we really need it, nor if it // should be changed... - public byte[] getRessourceBytes() throws FopImageException; - public int getRessourceBytesSize() throws FopImageException; + public byte[] getRessourceBytes(); + public int getRessourceBytesSize(); // return null if no corresponding PDFFilter - public PDFFilter getPDFFilter() throws FopImageException; - - // release memory - public void close(); + public PDFFilter getPDFFilter(); } + diff --git a/src/org/apache/fop/image/FopImageConsumer.java b/src/org/apache/fop/image/FopImageConsumer.java index 0ad27cc7a..15b8c5ca3 100644 --- a/src/org/apache/fop/image/FopImageConsumer.java +++ b/src/org/apache/fop/image/FopImageConsumer.java @@ -56,8 +56,8 @@ public class FopImageConsumer implements ImageConsumer { */ synchronized (this.imageStatus) { // Need to stop status if image done - if (imageStatus.intValue() != ImageConsumer.STATICIMAGEDONE - && imageStatus.intValue() != ImageConsumer.SINGLEFRAMEDONE) + if (imageStatus.intValue() != ImageConsumer.STATICIMAGEDONE && + imageStatus.intValue() != ImageConsumer.SINGLEFRAMEDONE) this.imageStatus = new Integer(status); } } @@ -96,8 +96,8 @@ public class FopImageConsumer implements ImageConsumer { if (this.imageStatus.intValue() == ImageConsumer.IMAGEERROR) throw new Exception("Image error"); - if (imageStatus.intValue() == ImageConsumer.STATICIMAGEDONE - || imageStatus.intValue() == ImageConsumer.SINGLEFRAMEDONE) + if (imageStatus.intValue() == ImageConsumer.STATICIMAGEDONE || + imageStatus.intValue() == ImageConsumer.SINGLEFRAMEDONE) return true; return false; @@ -119,8 +119,7 @@ public class FopImageConsumer implements ImageConsumer { public int[] getImage() throws Exception { int tmpMap[] = new int[this.width * this.height]; PixelGrabber pg = new PixelGrabber(this.ip, 0, 0, this.width, - this.height, tmpMap, 0, - this.width); + this.height, tmpMap, 0, this.width); pg.setDimensions(this.width, this.height); pg.setColorModel(this.cm); pg.setHints(this.hints); @@ -128,8 +127,8 @@ public class FopImageConsumer implements ImageConsumer { try { pg.grabPixels(); } catch (InterruptedException intex) { - throw new Exception("Image grabbing interrupted : " - + intex.getMessage()); + throw new Exception("Image grabbing interrupted : " + + intex.getMessage()); } return tmpMap; } diff --git a/src/org/apache/fop/image/FopImageException.java b/src/org/apache/fop/image/FopImageException.java deleted file mode 100644 index c85ecb73d..000000000 --- a/src/org/apache/fop/image/FopImageException.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -// Author: Eric SCHAEFFER -// Description: Image Exception - -package org.apache.fop.image; - -public class FopImageException extends Exception { - - public FopImageException() { - super(); - } - - public FopImageException(String message) { - super(message); - } - -} diff --git a/src/org/apache/fop/image/FopImageFactory.java b/src/org/apache/fop/image/FopImageFactory.java deleted file mode 100644 index 7e98c9a0d..000000000 --- a/src/org/apache/fop/image/FopImageFactory.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image; - -// Java -import java.io.IOException; -import java.io.InputStream; -import java.io.File; -import java.net.URL; -import java.net.MalformedURLException; -import java.lang.reflect.Constructor; -import java.util.Hashtable; - -// FOP -import org.apache.fop.image.analyser.ImageReaderFactory; -import org.apache.fop.image.analyser.ImageReader; -import org.apache.fop.configuration.Configuration; - -/* -handle context: base dir, logger, caching - -*/ - -/** - * create FopImage objects (with a configuration file - not yet implemented). - * @author Eric SCHAEFFER - */ -public class FopImageFactory { - - private static Hashtable m_urlMap = new Hashtable(); - - /** - * create an FopImage objects. - * @param href image URL as a String - * @return a new FopImage object - * @exception java.net.MalformedURLException bad URL - * @exception FopImageException an error occured during construction - */ - public static FopImage Make(String href) - throws MalformedURLException, FopImageException { - - /* - * According to section 5.11 a <uri-specification> is: - * "url(" + URI + ")" - * according to 7.28.7 a <uri-specification> is: - * URI - * So handle both. - */ - // Get the absolute URL - URL absoluteURL = null; - InputStream imgIS = null; - href = href.trim(); - if(href.startsWith("url(") && (href.indexOf(")") != -1)) { - href = href.substring(4, href.indexOf(")")).trim(); - if(href.startsWith("'") && href.endsWith("'")) { - href = href.substring(1, href.length() - 1); - } else if(href.startsWith("\"") && href.endsWith("\"")) { - href = href.substring(1, href.length() - 1); - } - } - try { - // try url as complete first, this can cause - // a problem with relative uri's if there is an - // image relative to where fop is run and relative - // to the base dir of the document - try { - absoluteURL = new URL(href); - } catch (MalformedURLException mue) { - // if the href contains only a path then file is assumed - absoluteURL = new URL("file:" + href); - } - imgIS = absoluteURL.openStream(); - } catch (MalformedURLException e_context) { - throw new FopImageException("Error with image URL: " - + e_context.getMessage()); - } catch (Exception e) { - // maybe relative - URL context_url = null; - String base = Configuration.getStringValue("baseDir"); - if(base == null) { - throw new FopImageException("Error with image URL: " - + e.getMessage() - + " and no base directory is specified"); - } - try { - absoluteURL = new URL(Configuration.getStringValue("baseDir") - + absoluteURL.getFile()); - } catch (MalformedURLException e_context) { - // pb context url - throw new FopImageException("Invalid Image URL - error on relative URL : " - + e_context.getMessage()); - } - } - - // check if already created - FopImage imageObject = (FopImage)m_urlMap.get(absoluteURL.toString()); - if (imageObject != null) - return imageObject; - - // If not, check image type - ImageReader imgReader = null; - try { - if (imgIS == null) { - imgIS = absoluteURL.openStream(); - } - imgReader = ImageReaderFactory.Make(absoluteURL.toExternalForm(), - imgIS); - } catch (Exception e) { - throw new FopImageException("Error while recovering Image Informations (" - + absoluteURL.toString() + ") : " - + e.getMessage()); - } - finally { - if (imgIS != null) { - try { - imgIS.close(); - } catch (IOException e) {} - } - } - if (imgReader == null) - throw new FopImageException("No ImageReader for this type of image (" - + absoluteURL.toString() + ")"); - // Associate mime-type to FopImage class - String imgMimeType = imgReader.getMimeType(); - String imgClassName = null; - if ("image/gif".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.GifImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/jpeg".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.JpegImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/bmp".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.BmpImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/eps".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.EPSImage"; - } else if ("image/png".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.JimiImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/tga".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.JimiImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/tiff".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.JimiImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/svg+xml".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.SVGImage"; - } - if (imgClassName == null) - throw new FopImageException("Unsupported image type (" - + absoluteURL.toString() + ") : " - + imgMimeType); - - // load the right image class - // return new <FopImage implementing class> - Object imageInstance = null; - Class imageClass = null; - try { - imageClass = Class.forName(imgClassName); - Class[] imageConstructorParameters = new Class[2]; - imageConstructorParameters[0] = Class.forName("java.net.URL"); - imageConstructorParameters[1] = - Class.forName("org.apache.fop.image.analyser.ImageReader"); - Constructor imageConstructor = - imageClass.getDeclaredConstructor(imageConstructorParameters); - Object[] initArgs = new Object[2]; - initArgs[0] = absoluteURL; - initArgs[1] = imgReader; - imageInstance = imageConstructor.newInstance(initArgs); - } catch (java.lang.reflect.InvocationTargetException ex) { - Throwable t = ex.getTargetException(); - String msg; - if (t != null) { - msg = t.getMessage(); - } else { - msg = ex.getMessage(); - } - throw new FopImageException("Error creating FopImage object (" - + absoluteURL.toString() + ") : " - + msg); - } catch (Exception ex) { - throw new FopImageException("Error creating FopImage object (" - + "Error creating FopImage object (" - + absoluteURL.toString() + ") : " - + ex.getMessage()); - } - if (!(imageInstance instanceof org.apache.fop.image.FopImage)) { - throw new FopImageException("Error creating FopImage object (" - + absoluteURL.toString() + ") : " - + "class " + imageClass.getName() - + " doesn't implement org.apache.fop.image.FopImage interface"); - } - m_urlMap.put(absoluteURL.toString(), imageInstance); - return (FopImage)imageInstance; - } - -} - diff --git a/src/org/apache/fop/image/GifImage.java b/src/org/apache/fop/image/GifImage.java index 5c64b0bfb..56dbac64c 100644 --- a/src/org/apache/fop/image/GifImage.java +++ b/src/org/apache/fop/image/GifImage.java @@ -17,6 +17,7 @@ import java.awt.image.IndexColorModel; import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.image.analyser.ImageReader; +import org.apache.fop.fo.FOUserAgent; /** * FopImage object for GIF images, using Java native classes. @@ -26,19 +27,14 @@ import org.apache.fop.image.analyser.ImageReader; * @see FopImage */ public class GifImage extends AbstractFopImage { - public GifImage(URL href) throws FopImageException { - super(href); - } - - public GifImage(URL href, - ImageReader imgReader) throws FopImageException { + public GifImage(URL href, ImageReader imgReader) { super(href, imgReader); } - protected void loadImage() throws FopImageException { + protected boolean loadBitmap(FOUserAgent ua) { int[] tmpMap = null; try { - ImageProducer ip = (ImageProducer)this.m_href.getContent(); + ImageProducer ip = (ImageProducer) this.m_href.getContent(); FopImageConsumer consumer = new FopImageConsumer(ip); ip.startProduction(consumer); @@ -54,8 +50,9 @@ public class GifImage extends AbstractFopImage { try { tmpMap = consumer.getImage(); } catch (Exception ex) { - throw new FopImageException("Image grabbing interrupted : " - + ex.getMessage()); + ua.getLogger().error("Image grabbing interrupted : " + + ex.getMessage(), ex); + return false; } ColorModel cm = consumer.getColorModel(); @@ -63,34 +60,34 @@ public class GifImage extends AbstractFopImage { // this.m_bitsPerPixel = cm.getPixelSize(); this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); if (cm.hasAlpha()) { - int transparencyType = - cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT + int transparencyType = cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT if (transparencyType == java.awt.Transparency.OPAQUE) { this.m_isTransparent = false; - } else if (transparencyType - == java.awt.Transparency.BITMASK) { + } else if (transparencyType == + java.awt.Transparency.BITMASK) { if (cm instanceof IndexColorModel) { this.m_isTransparent = false; - byte[] alphas = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] reds = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] greens = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] blues = - new byte[((IndexColorModel)cm).getMapSize()]; - ((IndexColorModel)cm).getAlphas(alphas); - ((IndexColorModel)cm).getReds(reds); - ((IndexColorModel)cm).getGreens(greens); - ((IndexColorModel)cm).getBlues(blues); + byte[] alphas = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] reds = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] greens = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] blues = new byte[ + ((IndexColorModel) cm).getMapSize()]; + ((IndexColorModel) cm).getAlphas(alphas); + ((IndexColorModel) cm).getReds(reds); + ((IndexColorModel) cm).getGreens(greens); + ((IndexColorModel) cm).getBlues(blues); for (int i = 0; - i < ((IndexColorModel)cm).getMapSize(); i++) { + i < ((IndexColorModel) cm).getMapSize(); + i++) { if ((alphas[i] & 0xFF) == 0) { this.m_isTransparent = true; - this.m_transparentColor = - new PDFColor((int)(reds[i] & 0xFF), - (int)(greens[i] & 0xFF), - (int)(blues[i] & 0xFF)); + this.m_transparentColor = new PDFColor( + (int)(reds[i] & 0xFF), + (int)(greens[i] & 0xFF), + (int)(blues[i] & 0xFF)); break; } } @@ -116,10 +113,11 @@ public class GifImage extends AbstractFopImage { this.m_isTransparent = false; } } catch (Exception ex) { - throw new FopImageException("Error while loading image " - + this.m_href.toString() + " : " - + ex.getClass() + " - " - + ex.getMessage()); + ua.getLogger().error("Error while loading image " + + this.m_href.toString() + " : " + + ex.getClass() + " - " + + ex.getMessage(), ex); + return false; } // Should take care of the ColorSpace and bitsPerPixel @@ -131,13 +129,15 @@ public class GifImage extends AbstractFopImage { int r = (p >> 16) & 0xFF; int g = (p >> 8) & 0xFF; int b = (p) & 0xFF; - this.m_bitmaps[3 * (i * this.m_width + j)] = (byte)(r & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 1] = (byte)(g - & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 2] = (byte)(b - & 0xFF); + this.m_bitmaps[3 * (i * this.m_width + j)] = + (byte)(r & 0xFF); + this.m_bitmaps[3 * (i * this.m_width + j) + 1] = + (byte)(g & 0xFF); + this.m_bitmaps[3 * (i * this.m_width + j) + 2] = + (byte)(b & 0xFF); } } + return true; } } diff --git a/src/org/apache/fop/image/ImageArea.java b/src/org/apache/fop/image/ImageArea.java index 311e1769a..32e473fd4 100644 --- a/src/org/apache/fop/image/ImageArea.java +++ b/src/org/apache/fop/image/ImageArea.java @@ -13,9 +13,6 @@ import org.apache.fop.layout.inline.*; import org.apache.fop.render.Renderer; -import java.util.Vector; -import java.util.Enumeration; - public class ImageArea extends InlineArea { protected int xOffset = 0; @@ -24,9 +21,9 @@ public class ImageArea extends InlineArea { protected FopImage image; - public ImageArea(FontState fontState, FopImage img, int AllocationWidth, - int width, int height, int startIndent, int endIndent, - int align) { + public ImageArea(FontState fontState, FopImage img, + int AllocationWidth, int width, int height, + int startIndent, int endIndent, int align) { super(fontState, width, 0, 0, 0); this.currentHeight = height; this.contentRectangleWidth = width; diff --git a/src/org/apache/fop/image/ImageCache.java b/src/org/apache/fop/image/ImageCache.java new file mode 100644 index 000000000..b94d8b73f --- /dev/null +++ b/src/org/apache/fop/image/ImageCache.java @@ -0,0 +1,21 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.image; + +// FOP +import org.apache.fop.fo.FOUserAgent; + +import org.apache.log.Logger; + +public interface ImageCache { + public FopImage getImage(String url, FOUserAgent context); + public void releaseImage(String url, FOUserAgent context); + public void invalidateImage(String url, FOUserAgent context); + public void removeContext(FOUserAgent context); +} + diff --git a/src/org/apache/fop/image/ImageFactory.java b/src/org/apache/fop/image/ImageFactory.java new file mode 100644 index 000000000..6b5fb3738 --- /dev/null +++ b/src/org/apache/fop/image/ImageFactory.java @@ -0,0 +1,381 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.image; + +// Java +import java.io.IOException; +import java.io.InputStream; +import java.io.File; +import java.net.URL; +import java.net.MalformedURLException; +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.WeakHashMap; +import java.util.Map; +import java.util.HashSet; +import java.util.Set; +import java.util.Collections; + +// FOP +import org.apache.fop.image.analyser.ImageReaderFactory; +import org.apache.fop.image.analyser.ImageReader; +import org.apache.fop.fo.FOUserAgent; + +import org.apache.log.Logger; + +/* +handle context: base dir, logger, caching + + */ + +/** + * create FopImage objects (with a configuration file - not yet implemented). + * @author Eric SCHAEFFER + */ +public class ImageFactory { + private static ImageFactory factory = new ImageFactory(); + ImageCache cache = new ContextImageCache(); + + private ImageFactory() {} + + public static ImageFactory getInstance() { + return factory; + } + + public static String getURL(String href) { + /* + * According to section 5.11 a <uri-specification> is: + * "url(" + URI + ")" + * according to 7.28.7 a <uri-specification> is: + * URI + * So handle both. + */ + // Get the absolute URL + URL absoluteURL = null; + InputStream imgIS = null; + href = href.trim(); + if (href.startsWith("url(") && (href.indexOf(")") != -1)) { + href = href.substring(4, href.indexOf(")")).trim(); + if (href.startsWith("'") && href.endsWith("'")) { + href = href.substring(1, href.length() - 1); + } else if (href.startsWith("\"") && href.endsWith("\"")) { + href = href.substring(1, href.length() - 1); + } + } else { + // warn + } + return href; + } + + /** + * Get the image from the cache or load. + * If this returns null then the image could not be loaded + * due to an error. Messages should be logged. + * Before calling this the getURL(url) must be used. + */ + public FopImage getImage(String url, FOUserAgent context) { + return cache.getImage(url, context); + } + + /** + * Release an image from the cache. + * This can be used if the renderer has its own cache of + * the image. + * The image should then be put into the weak cache. + */ + public void releaseImage(String url, FOUserAgent context) { + cache.releaseImage(url, context); + } + + /** + * create an FopImage objects. + * @param href image URL as a String + * @return a new FopImage object + * @exception java.net.MalformedURLException bad URL + * @exception FopImageException an error occured during construction + */ + protected static FopImage loadImage(String href, String baseURL, + FOUserAgent ua) { + Logger log = ua.getLogger(); + // Get the absolute URL + URL absoluteURL = null; + InputStream imgIS = null; + try { + // try url as complete first, this can cause + // a problem with relative uri's if there is an + // image relative to where fop is run and relative + // to the base dir of the document + try { + absoluteURL = new URL(href); + } catch (MalformedURLException mue) { + // if the href contains only a path then file is assumed + absoluteURL = new URL("file:" + href); + } + imgIS = absoluteURL.openStream(); + } catch (MalformedURLException e_context) { + log.error("Error with image URL: " + e_context.getMessage()); + return null; + } + catch (Exception e) { + // maybe relative + URL context_url = null; + if (baseURL == null) { + log.error("Error with image URL: " + e.getMessage() + " and no base directory is specified"); + return null; + } + try { + absoluteURL = new URL(baseURL + absoluteURL.getFile()); + } catch (MalformedURLException e_context) { + // pb context url + log.error( "Invalid Image URL - error on relative URL : " + + e_context.getMessage()); + return null; + } + } + + // If not, check image type + ImageReader imgReader = null; + try { + if (imgIS == null) { + imgIS = absoluteURL.openStream(); + } + imgReader = ImageReaderFactory.make( + absoluteURL.toExternalForm(), imgIS, ua); + } catch (Exception e) { + log.error("Error while recovering Image Informations (" + + absoluteURL.toString() + ") : " + e.getMessage()); + return null; + } + finally { if (imgIS != null) { + try { + imgIS.close(); + } catch (IOException e) {} + } + } if (imgReader == null) { + log.error("No ImageReader for this type of image (" + + absoluteURL.toString() + ")"); + return null; + } + // Associate mime-type to FopImage class + String imgMimeType = imgReader.getMimeType(); + String imgClassName = null; + if ("image/gif".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.GifImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/jpeg".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.JpegImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/bmp".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.BmpImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/eps".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.EPSImage"; + } else if ("image/png".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.JimiImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/tga".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.JimiImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/tiff".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.JimiImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/svg+xml".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.SVGImage"; + } + if (imgClassName == null) { + log.error("Unsupported image type (" + + absoluteURL.toString() + ") : " + imgMimeType); + return null; + } + + // load the right image class + // return new <FopImage implementing class> + Object imageInstance = null; + Class imageClass = null; + try { + imageClass = Class.forName(imgClassName); + Class[] imageConstructorParameters = new Class[2]; + imageConstructorParameters[0] = Class.forName("java.net.URL"); + imageConstructorParameters[1] = Class.forName("org.apache.fop.image.analyser.ImageReader"); + Constructor imageConstructor = + imageClass.getDeclaredConstructor( + imageConstructorParameters); + Object[] initArgs = new Object[2]; + initArgs[0] = absoluteURL; + initArgs[1] = imgReader; + imageInstance = imageConstructor.newInstance(initArgs); + } catch (java.lang.reflect.InvocationTargetException ex) { + Throwable t = ex.getTargetException(); + String msg; + if (t != null) { + msg = t.getMessage(); + } else { + msg = ex.getMessage(); + } + log.error("Error creating FopImage object (" + + absoluteURL.toString() + ") : " + msg); + return null; + } + catch (Exception ex) { + log.error("Error creating FopImage object (" + + "Error creating FopImage object (" + + absoluteURL.toString() + ") : " + ex.getMessage()); + return null; + } + if (!(imageInstance instanceof org.apache.fop.image.FopImage)) { + log.error("Error creating FopImage object (" + + absoluteURL.toString() + ") : " + "class " + + imageClass.getName() + " doesn't implement org.apache.fop.image.FopImage interface"); + return null; + } + return (FopImage) imageInstance; + } + +} + +class BasicImageCache implements ImageCache { + Set invalid = Collections.synchronizedSet(new HashSet()); + Map contextStore = Collections.synchronizedMap(new HashMap()); + + public FopImage getImage(String url, FOUserAgent context) { + if (invalid.contains(url)) { + return null; + } + return null; + } + + public void releaseImage(String url, FOUserAgent context) { + // do nothing + } + + public void invalidateImage(String url, FOUserAgent context) { + // cap size of invalid list + if (invalid.size() > 100) { + invalid.clear(); + } + invalid.add(url); + } + + public void removeContext(FOUserAgent context) { + // do nothing + } +} + +/** + * This is the context image cache. + * This caches images on the basis of the given context. + * Common images in different contexts are currently not handled. + * There are two possiblities, each context handles its own images + * and renderers can cache information or images are shared and + * all information is retained. + * Once a context is removed then all images are placed into a + * weak hashmap so they may be garbage collected. + */ +class ContextImageCache implements ImageCache { + Set invalid = Collections.synchronizedSet(new HashSet()); + Map contextStore = Collections.synchronizedMap(new HashMap()); + Map weakStore = Collections.synchronizedMap(new WeakHashMap()); + + // sync around lookups and puts + // another sync around load for a particular image + public FopImage getImage(String url, FOUserAgent context) { + ImageLoader im; + // this protects the finding or creating of a new + // ImageLoader for multi threads + synchronized (this) { + if (invalid.contains(url)) { + return null; + } + Context con = (Context) contextStore.get(context); + if (con == null) { + con = new Context(context); + contextStore.put(context, con); + } + im = (ImageLoader) weakStore.get(url); + if (im != null) { + con.putImage(url, im); + } else { + im = con.getImage(url, this); + } + } + + // the ImageLoader is synchronized so images with the + // same url will not be loaded at the same time + if (im != null) { + return im.loadImage(); + } + return null; + } + + public void releaseImage(String url, FOUserAgent context) { + Context con = (Context) contextStore.get(context); + if (con != null) { + ImageLoader im = con.getImage(url); + weakStore.put(url, im); + con.releaseImage(url); + } + } + + public void invalidateImage(String url, FOUserAgent context) { + // cap size of invalid list + if (invalid.size() > 100) { + invalid.clear(); + } + invalid.add(url); + Context con = (Context) contextStore.get(context); + if (con != null) { + con.releaseImage(url); + } + } + + public void removeContext(FOUserAgent context) { + Context con = (Context) contextStore.get(context); + if (con != null) { + Map images = con.getImages(); + weakStore.putAll(images); + contextStore.remove(context); + } + } + + class Context { + Map images = Collections.synchronizedMap(new HashMap()); + FOUserAgent userAgent; + + public Context(FOUserAgent ua) { + userAgent = ua; + } + + public ImageLoader getImage(String url, ImageCache c) { + if (images.containsKey(url)) { + return (ImageLoader) images.get(url); + } + ImageLoader loader = new ImageLoader(url, c, userAgent); + images.put(url, loader); + return loader; + } + + public void putImage(String url, ImageLoader image) { + images.put(url, image); + } + + public ImageLoader getImage(String url) { + return (ImageLoader) images.get(url); + } + + public void releaseImage(String url) { + images.remove(url); + } + + public Map getImages() { + return images; + } + + } + +} + diff --git a/src/org/apache/fop/image/ImageLoader.java b/src/org/apache/fop/image/ImageLoader.java new file mode 100644 index 000000000..6c95f1da7 --- /dev/null +++ b/src/org/apache/fop/image/ImageLoader.java @@ -0,0 +1,42 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.image; + +import org.apache.fop.configuration.Configuration; +import org.apache.fop.fo.FOUserAgent; + +/** + * Class to load images. + */ +class ImageLoader { + String url; + ImageCache cache; + boolean valid = true; + FOUserAgent userAgent; + FopImage image = null; + + public ImageLoader(String u, ImageCache c, FOUserAgent ua) { + url = u; + cache = c; + userAgent = ua; + } + + public synchronized FopImage loadImage() { + if (!valid || image != null) { + return image; + } + String base = Configuration.getStringValue("baseDir"); + image = ImageFactory.loadImage(url, base, userAgent); + if (image == null) { + cache.invalidateImage(url, userAgent); + valid = false; + } + return image; + } + +} diff --git a/src/org/apache/fop/image/JAIImage.java b/src/org/apache/fop/image/JAIImage.java index 0e8524759..f62e39b62 100644 --- a/src/org/apache/fop/image/JAIImage.java +++ b/src/org/apache/fop/image/JAIImage.java @@ -34,16 +34,15 @@ import org.apache.fop.image.analyser.ImageReader; * @see FopImage */ public class JAIImage extends AbstractFopImage { - public JAIImage(URL href) throws FopImageException { + public JAIImage(URL href) { super(href); } - public JAIImage(URL href, - ImageReader imgReader) throws FopImageException { + public JAIImage(URL href, ImageReader imgReader) { super(href, imgReader); } - protected void loadImage() throws FopImageException { + protected void loadImage() { try { InputStream inputStream = this.m_href.openStream(); /* @@ -51,7 +50,7 @@ public class JAIImage extends AbstractFopImage { * inputStream.reset(); */ com.sun.media.jai.codec.FileCacheSeekableStream seekableInput = - new FileCacheSeekableStream(inputStream); + new FileCacheSeekableStream(inputStream); RenderedOp imageOp = JAI.create("stream", seekableInput); this.m_height = imageOp.getHeight(); @@ -64,38 +63,37 @@ public class JAIImage extends AbstractFopImage { BufferedImage imageData = imageOp.getAsBufferedImage(); int[] tmpMap = imageData.getRGB(0, 0, this.m_width, - this.m_height, null, 0, - this.m_width); + this.m_height, null, 0, this.m_width); if (cm.hasAlpha()) { - int transparencyType = - cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT + int transparencyType = cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT if (transparencyType == java.awt.Transparency.OPAQUE) { this.m_isTransparent = false; - } else if (transparencyType - == java.awt.Transparency.BITMASK) { + } else if (transparencyType == + java.awt.Transparency.BITMASK) { if (cm instanceof IndexColorModel) { this.m_isTransparent = false; - byte[] alphas = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] reds = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] greens = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] blues = - new byte[((IndexColorModel)cm).getMapSize()]; - ((IndexColorModel)cm).getAlphas(alphas); - ((IndexColorModel)cm).getReds(reds); - ((IndexColorModel)cm).getGreens(greens); - ((IndexColorModel)cm).getBlues(blues); + byte[] alphas = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] reds = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] greens = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] blues = new byte[ + ((IndexColorModel) cm).getMapSize()]; + ((IndexColorModel) cm).getAlphas(alphas); + ((IndexColorModel) cm).getReds(reds); + ((IndexColorModel) cm).getGreens(greens); + ((IndexColorModel) cm).getBlues(blues); for (int i = 0; - i < ((IndexColorModel)cm).getMapSize(); i++) { + i < ((IndexColorModel) cm).getMapSize(); + i++) { if ((alphas[i] & 0xFF) == 0) { this.m_isTransparent = true; - this.m_transparentColor = - new PDFColor((int)(reds[i] & 0xFF), - (int)(greens[i] & 0xFF), - (int)(blues[i] & 0xFF)); + this.m_transparentColor = new PDFColor( + (int)(reds[i] & 0xFF), + (int)(greens[i] & 0xFF), + (int)(blues[i] & 0xFF)); break; } } @@ -127,24 +125,25 @@ public class JAIImage extends AbstractFopImage { for (int i = 0; i < this.m_height; i++) { for (int j = 0; j < this.m_width; j++) { int p = tmpMap[i * this.m_width + j]; - int r = (p >> 16) & 0xFF; - int g = (p >> 8) & 0xFF; + int r = (p > > 16) & 0xFF; + int g = (p > > 8) & 0xFF; int b = (p) & 0xFF; - this.m_bitmaps[3 * (i * this.m_width + j)] = (byte)(r - & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 1] = (byte)(g - & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 2] = (byte)(b - & 0xFF); + this.m_bitmaps[3 * (i * this.m_width + j)] = + (byte)(r & 0xFF); + this.m_bitmaps[3 * (i * this.m_width + j) + 1] = + (byte)(g & 0xFF); + this.m_bitmaps[3 * (i * this.m_width + j) + 2] = + (byte)(b & 0xFF); } } - } catch (Exception ex) { - throw new FopImageException("Error while loading image " - + this.m_href.toString() + " : " - + ex.getClass() + " - " - + ex.getMessage()); } + catch (Exception ex) { + /*throw new FopImageException("Error while loading image " + + this.m_href.toString() + " : " + + ex.getClass() + " - " + + ex.getMessage()); + */} } } diff --git a/src/org/apache/fop/image/JimiImage.java b/src/org/apache/fop/image/JimiImage.java index ddd2c49ea..6ed39c722 100644 --- a/src/org/apache/fop/image/JimiImage.java +++ b/src/org/apache/fop/image/JimiImage.java @@ -29,31 +29,21 @@ import org.apache.fop.image.analyser.ImageReader; * @see FopImage */ public class JimiImage extends AbstractFopImage { - public JimiImage(URL href) throws FopImageException { - super(href); - try { - Class c = Class.forName("com.sun.jimi.core.Jimi"); - } catch (ClassNotFoundException e) { - throw new FopImageException("Jimi image library not available"); - } - } - - public JimiImage(URL href, - ImageReader imgReader) throws FopImageException { + public JimiImage(URL href, ImageReader imgReader) { super(href, imgReader); try { Class c = Class.forName("com.sun.jimi.core.Jimi"); } catch (ClassNotFoundException e) { - throw new FopImageException("Jimi image library not available"); + //throw new FopImageException("Jimi image library not available"); } } - protected void loadImage() throws FopImageException { + protected void loadImage() { int[] tmpMap = null; try { - ImageProducer ip = Jimi.getImageProducer(this.m_href.openStream(), - Jimi.SYNCHRONOUS - | Jimi.IN_MEMORY); + ImageProducer ip = + Jimi.getImageProducer(this.m_href.openStream(), + Jimi.SYNCHRONOUS | Jimi.IN_MEMORY); FopImageConsumer consumer = new FopImageConsumer(ip); ip.startProduction(consumer); @@ -66,43 +56,43 @@ public class JimiImage extends AbstractFopImage { try { tmpMap = consumer.getImage(); } catch (Exception ex) { - throw new FopImageException("Image grabbing interrupted : " - + ex.getMessage()); - } + /*throw new FopImageException("Image grabbing interrupted : " + + ex.getMessage()); + */} ColorModel cm = consumer.getColorModel(); this.m_bitsPerPixel = 8; // this.m_bitsPerPixel = cm.getPixelSize(); this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); if (cm.hasAlpha()) { - int transparencyType = - cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT + int transparencyType = cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT if (transparencyType == java.awt.Transparency.OPAQUE) { this.m_isTransparent = false; - } else if (transparencyType - == java.awt.Transparency.BITMASK) { + } else if (transparencyType == + java.awt.Transparency.BITMASK) { if (cm instanceof IndexColorModel) { this.m_isTransparent = false; - byte[] alphas = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] reds = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] greens = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] blues = - new byte[((IndexColorModel)cm).getMapSize()]; - ((IndexColorModel)cm).getAlphas(alphas); - ((IndexColorModel)cm).getReds(reds); - ((IndexColorModel)cm).getGreens(greens); - ((IndexColorModel)cm).getBlues(blues); + byte[] alphas = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] reds = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] greens = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] blues = new byte[ + ((IndexColorModel) cm).getMapSize()]; + ((IndexColorModel) cm).getAlphas(alphas); + ((IndexColorModel) cm).getReds(reds); + ((IndexColorModel) cm).getGreens(greens); + ((IndexColorModel) cm).getBlues(blues); for (int i = 0; - i < ((IndexColorModel)cm).getMapSize(); i++) { + i < ((IndexColorModel) cm).getMapSize(); + i++) { if ((alphas[i] & 0xFF) == 0) { this.m_isTransparent = true; - this.m_transparentColor = - new PDFColor((int)(reds[i] & 0xFF), - (int)(greens[i] & 0xFF), - (int)(blues[i] & 0xFF)); + this.m_transparentColor = new PDFColor( + (int)(reds[i] & 0xFF), + (int)(greens[i] & 0xFF), + (int)(blues[i] & 0xFF)); break; } } @@ -128,11 +118,11 @@ public class JimiImage extends AbstractFopImage { this.m_isTransparent = false; } } catch (Exception ex) { - throw new FopImageException("Error while loading image " - + this.m_href.toString() + " : " - + ex.getClass() + " - " - + ex.getMessage()); - } + /*throw new FopImageException("Error while loading image " + + this.m_href.toString() + " : " + + ex.getClass() + " - " + + ex.getMessage()); + */} // Should take care of the ColorSpace and bitsPerPixel @@ -141,14 +131,15 @@ public class JimiImage extends AbstractFopImage { for (int i = 0; i < this.m_height; i++) { for (int j = 0; j < this.m_width; j++) { int p = tmpMap[i * this.m_width + j]; - int r = (p >> 16) & 0xFF; - int g = (p >> 8) & 0xFF; + int r = (p > > 16) & 0xFF; + int g = (p > > 8) & 0xFF; int b = (p) & 0xFF; - this.m_bitmaps[3 * (i * this.m_width + j)] = (byte)(r & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 1] = (byte)(g - & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 2] = (byte)(b - & 0xFF); + this.m_bitmaps[3 * (i * this.m_width + j)] = + (byte)(r & 0xFF); + this.m_bitmaps[3 * (i * this.m_width + j) + 1] = + (byte)(g & 0xFF); + this.m_bitmaps[3 * (i * this.m_width + j) + 2] = + (byte)(b & 0xFF); } } } diff --git a/src/org/apache/fop/image/JpegImage.java b/src/org/apache/fop/image/JpegImage.java index 23974cd6b..cc0032bf5 100644 --- a/src/org/apache/fop/image/JpegImage.java +++ b/src/org/apache/fop/image/JpegImage.java @@ -20,6 +20,7 @@ import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.pdf.DCTFilter; import org.apache.fop.image.analyser.ImageReader; +import org.apache.fop.fo.FOUserAgent; /** * FopImage object for JPEG images, Using Java native classes. @@ -30,17 +31,12 @@ import org.apache.fop.image.analyser.ImageReader; public class JpegImage extends AbstractFopImage { boolean found_icc_profile = false; boolean found_dimensions = false; - - public JpegImage(URL href) throws FopImageException { - super(href); - } - - public JpegImage(URL href, - ImageReader imgReader) throws FopImageException { + + public JpegImage(URL href, ImageReader imgReader) { super(href, imgReader); } - - protected void loadImage() throws FopImageException { + + protected boolean loadBitmap(FOUserAgent ua) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream iccStream = new ByteArrayOutputStream(); InputStream inStream; @@ -49,53 +45,57 @@ public class JpegImage extends AbstractFopImage { int bytes_read; int index = 0; boolean cont = true; - + this.m_compressionType = new DCTFilter(); this.m_compressionType.setApplied(true); - + try { inStream = this.m_href.openStream(); - + while ((bytes_read = inStream.read(readBuf)) != -1) { baos.write(readBuf, 0, bytes_read); } } catch (java.io.IOException ex) { - throw new FopImageException("Error while loading image " + - this.m_href.toString() + " : " + ex.getClass() + - " - " + ex.getMessage()); + ua.getLogger().error("Error while loading image " + + this.m_href.toString() + " : " + ex.getClass() + + " - " + ex.getMessage(), ex); + return false; } - + this.m_bitmaps = baos.toByteArray(); this.m_bitsPerPixel = 8; this.m_isTransparent = false; - + if (this.m_bitmaps.length > (index + 2) && - uByte(this.m_bitmaps[index]) == 255 && - uByte(this.m_bitmaps[index + 1]) == 216) { + uByte(this.m_bitmaps[index]) == 255 && + uByte(this.m_bitmaps[index + 1]) == 216) { index += 2; - + while (index < this.m_bitmaps.length && cont) { - //check to be sure this is the begining of a header + //check to be sure this is the begining of a header if (this.m_bitmaps.length > (index + 2) && - uByte(this.m_bitmaps[index]) == 255) { - - //192 or 194 are the header bytes that contain the jpeg width height and color depth. + uByte(this.m_bitmaps[index]) == 255) { + + //192 or 194 are the header bytes that contain the jpeg width height and color depth. if (uByte(this.m_bitmaps[index + 1]) == 192 || - uByte(this.m_bitmaps[index + 1]) == 194) { - + uByte(this.m_bitmaps[index + 1]) == 194) { + this.m_height = calcBytes(this.m_bitmaps[index + 5], this.m_bitmaps[index + 6]); this.m_width = calcBytes(this.m_bitmaps[index + 7], this.m_bitmaps[index + 8]); - + if (this.m_bitmaps[index + 9] == 1) { - this.m_colorSpace.setColorSpace(ColorSpace.DEVICE_GRAY); + this.m_colorSpace.setColorSpace( + ColorSpace.DEVICE_GRAY); } else if (this.m_bitmaps[index + 9] == 3) { - this.m_colorSpace.setColorSpace(ColorSpace.DEVICE_RGB); + this.m_colorSpace.setColorSpace( + ColorSpace.DEVICE_RGB); } else if (this.m_bitmaps[index + 9] == 4) { - this.m_colorSpace.setColorSpace(ColorSpace.DEVICE_CMYK); + this.m_colorSpace.setColorSpace( + ColorSpace.DEVICE_CMYK); } - + found_dimensions = true; if (found_icc_profile) { cont = false; @@ -103,57 +103,64 @@ public class JpegImage extends AbstractFopImage { } index += calcBytes(this.m_bitmaps[index + 2], this.m_bitmaps[index + 3]) + 2; - - } else if (uByte(this.m_bitmaps[index+1]) == 226 && - this.m_bitmaps.length > (index+60)) { - // Check if ICC profile + + } else if (uByte(this.m_bitmaps[index + 1]) == + 226 && this.m_bitmaps.length > (index + 60)) { + // Check if ICC profile byte[] icc_string = new byte[11]; - System.arraycopy(this.m_bitmaps, index+4, icc_string, 0, 11); - - if ("ICC_PROFILE".equals(new String(icc_string))){ - int chunkSize = calcBytes(this.m_bitmaps[index + 2], - this.m_bitmaps[index + 3]) + 2; - + System.arraycopy(this.m_bitmaps, index + 4, + icc_string, 0, 11); + + if ("ICC_PROFILE".equals(new String(icc_string))) { + int chunkSize = calcBytes( + this.m_bitmaps[index + 2], + this.m_bitmaps[index + 3]) + 2; + if (iccStream.size() == 0) - iccStream.write(this.m_bitmaps, index+18, - chunkSize - 20); + iccStream.write(this.m_bitmaps, + index + 18, chunkSize - 20); else - iccStream.write(this.m_bitmaps, index+16, - chunkSize - 18); - + iccStream.write(this.m_bitmaps, + index + 16, chunkSize - 18); + } - + index += calcBytes(this.m_bitmaps[index + 2], this.m_bitmaps[index + 3]) + 2; } else { index += calcBytes(this.m_bitmaps[index + 2], this.m_bitmaps[index + 3]) + 2; } - + } else { cont = false; } } } else { - throw new FopImageException( "\n1 Error while loading image " + - this.m_href.toString() + - " : JpegImage - Invalid JPEG Header."); + ua.getLogger().error( "1 Error while loading image " + + this.m_href.toString() + + " : JpegImage - Invalid JPEG Header."); + return false; } if (iccStream.size() > 0) { byte[] align = new byte[((iccStream.size()) % 8) + 8]; - try {iccStream.write(align);} catch (Exception e) { - throw new FopImageException( "\n1 Error while loading image " + - this.m_href.toString() + " : " + - e.getMessage()); + try { + iccStream.write(align); + } catch (Exception e) { + ua.getLogger().error( "1 Error while loading image " + + this.m_href.toString() + " : " + + e.getMessage(), e); + return false; } this.m_colorSpace.setICCProfile(iccStream.toByteArray()); } + return true; } - + private int calcBytes(byte bOne, byte bTwo) { return (uByte(bOne) * 256) + uByte(bTwo); } - + private int uByte(byte bIn) { if (bIn < 0) { return 256 + bIn; diff --git a/src/org/apache/fop/image/SVGImage.java b/src/org/apache/fop/image/SVGImage.java index 4fd0d1b7b..7e7f1a026 100644 --- a/src/org/apache/fop/image/SVGImage.java +++ b/src/org/apache/fop/image/SVGImage.java @@ -13,12 +13,9 @@ import org.w3c.dom.svg.SVGDocument; // FOP import org.apache.fop.apps.Driver; -import org.apache.fop.datatypes.ColorSpace; -import org.apache.fop.pdf.PDFColor; import org.apache.fop.image.analyser.ImageReader; - -import org.xml.sax.InputSource; -import org.xml.sax.XMLReader; +import org.apache.fop.image.analyser.SVGReader; +import org.apache.fop.fo.FOUserAgent; import org.apache.batik.dom.svg.SAXSVGDocumentFactory; @@ -29,13 +26,11 @@ import org.apache.batik.dom.svg.SAXSVGDocumentFactory; public class SVGImage extends AbstractFopImage { SVGDocument doc; - public SVGImage(URL href) throws FopImageException { - super(href); - } - - public SVGImage(URL href, - ImageReader imgReader) throws FopImageException { + public SVGImage(URL href, ImageReader imgReader) { super(href, imgReader); + if(imgReader instanceof SVGReader) { + doc = ((SVGReader)imgReader).getDocument(); + } } /** @@ -49,20 +44,20 @@ public class SVGImage extends AbstractFopImage { return parserClassName; } - protected void loadImage() throws FopImageException { + protected boolean loadData(FOUserAgent ua) { try { SAXSVGDocumentFactory factory = - new SAXSVGDocumentFactory(SVGImage.getParserName()); + new SAXSVGDocumentFactory(SVGImage.getParserName()); doc = factory.createDocument(this.m_href.toExternalForm()); } catch (Exception e) { - //log.error("Could not load external SVG: " - // + e.getMessage()); + ua.getLogger().error("Could not load external SVG: " + + e.getMessage(), e); + return false; } + return true; } - public SVGDocument getSVGDocument() throws FopImageException { - if (doc == null) - this.loadImage(); + public SVGDocument getSVGDocument() { return doc; } diff --git a/src/org/apache/fop/image/analyser/AbstractImageReader.java b/src/org/apache/fop/image/analyser/AbstractImageReader.java index aeb6e02b9..999ffa127 100644 --- a/src/org/apache/fop/image/analyser/AbstractImageReader.java +++ b/src/org/apache/fop/image/analyser/AbstractImageReader.java @@ -11,6 +11,8 @@ package org.apache.fop.image.analyser; import java.io.BufferedInputStream; import java.io.IOException; +import org.apache.fop.fo.FOUserAgent; + /** * Base class implementing ImageReader. * @author Pankaj Narula @@ -34,8 +36,8 @@ public abstract class AbstractImageReader implements ImageReader { */ protected BufferedInputStream imageStream = null; - public abstract boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException; + public abstract boolean verifySignature(String uri, + BufferedInputStream fis, FOUserAgent ua) throws IOException; public int getHeight() { return this.height; diff --git a/src/org/apache/fop/image/analyser/BMPReader.java b/src/org/apache/fop/image/analyser/BMPReader.java index c09a6238e..5e7cd8513 100644 --- a/src/org/apache/fop/image/analyser/BMPReader.java +++ b/src/org/apache/fop/image/analyser/BMPReader.java @@ -11,6 +11,8 @@ package org.apache.fop.image.analyser; import java.io.BufferedInputStream; import java.io.IOException; +import org.apache.fop.fo.FOUserAgent; + /** * ImageReader object for BMP image type. * @author Pankaj Narula @@ -21,12 +23,12 @@ public class BMPReader extends AbstractImageReader { protected byte[] header; - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { + public boolean verifySignature(String uri, BufferedInputStream fis, + FOUserAgent ua) throws IOException { this.imageStream = fis; this.setDefaultHeader(); - boolean supported = ((header[0] == (byte)0x42) - && (header[1] == (byte)0x4d)); + boolean supported = ((header[0] == (byte) 0x42) && + (header[1] == (byte) 0x4d)); if (supported) { setDimension(); return true; @@ -44,7 +46,8 @@ public class BMPReader extends AbstractImageReader { int byte2 = header[19] & 0xff; int byte3 = header[20] & 0xff; int byte4 = header[21] & 0xff; - long l = (long)((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1); + long l = (long)((byte4 << 24) | (byte3 << 16) | + (byte2 << 8) | byte1); this.width = (int)(l & 0xffffffff); byte1 = header[22] & 0xff; diff --git a/src/org/apache/fop/image/analyser/EPSReader.java b/src/org/apache/fop/image/analyser/EPSReader.java index 23ffaee3b..fbaaffe6d 100644 --- a/src/org/apache/fop/image/analyser/EPSReader.java +++ b/src/org/apache/fop/image/analyser/EPSReader.java @@ -17,86 +17,86 @@ import java.net.URL; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; +import org.apache.fop.fo.FOUserAgent; + /** * ImageReader object for EPS document image type. */ public class EPSReader extends AbstractImageReader { private long[] bbox; private boolean isAscii; // True if plain ascii eps file - - // offsets if not ascii + + // offsets if not ascii long psStart = 0; long psLength = 0; long wmfStart = 0; long wmfLength = 0; long tiffStart = 0; long tiffLength = 0; - - /** raw eps file */ + + /** raw eps file */ private byte[] rawEps; - /** eps part */ + /** eps part */ private byte[] epsFile; private byte[] preview = null; - + private long getLong(byte[] buf, int idx) { int b1 = buf[idx] & 0xff; - int b2 = buf[idx+1] & 0xff; - int b3 = buf[idx+2] & 0xff; - int b4 = buf[idx+3] & 0xff; - + int b2 = buf[idx + 1] & 0xff; + int b3 = buf[idx + 2] & 0xff; + int b4 = buf[idx + 3] & 0xff; + return (long)((b4 << 24) | (b3 << 16) | (b2 << 8) | b1); } - - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { + + public boolean verifySignature(String uri, BufferedInputStream fis, + FOUserAgent ua) throws IOException { boolean isEPS = false; this.imageStream = fis; fis.mark(32); byte[] header = new byte[30]; fis.read(header, 0, 30); fis.reset(); - - // Check if binary header + + // Check if binary header if (getLong(header, 0) == 0xC6D3D0C5) { isAscii = false; isEPS = true; - + psStart = getLong(header, 4); psLength = getLong(header, 8); wmfStart = getLong(header, 12); wmfLength = getLong(header, 16); tiffStart = getLong(header, 20); tiffLength = getLong(header, 24); - + } else { - // Check if plain ascii + // Check if plain ascii byte[] epsh = "%!PS".getBytes(); - if (epsh[0] == header[0] && - epsh[1] == header[1] && - epsh[2] == header[2] && - epsh[3] == header[3]) { + if (epsh[0] == header[0] && epsh[1] == header[1] && + epsh[2] == header[2] && epsh[3] == header[3]) { isAscii = true; isEPS = true; } } - + if (isEPS) { readEPSImage(fis); bbox = readBBox(); - + if (bbox != null) { - width = (int)(bbox[2]-bbox[0]); - height = (int)(bbox[3]-bbox[1]); + width = (int)(bbox[2] - bbox[0]); + height = (int)(bbox[3] - bbox[1]); } else { - // Ain't eps if no BoundingBox + // Ain't eps if no BoundingBox isEPS = false; } } - + return isEPS; } - - /** read the eps file and extract eps part */ + + /** read the eps file and extract eps part */ private void readEPSImage(BufferedInputStream fis) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] file; @@ -104,58 +104,61 @@ public class EPSReader extends AbstractImageReader { int bytes_read; int index = 0; boolean cont = true; - - + + try { while ((bytes_read = fis.read(readBuf)) != -1) { baos.write(readBuf, 0, bytes_read); } } catch (java.io.IOException ex) { - throw new IOException("Error while loading EPS image " + ex.getMessage()); + throw new IOException("Error while loading EPS image " + + ex.getMessage()); } - + file = baos.toByteArray(); - + if (isAscii) { rawEps = null; epsFile = new byte[file.length]; System.arraycopy(file, 0, epsFile, 0, epsFile.length); } else { rawEps = new byte[file.length]; - epsFile = new byte[(int)psLength]; + epsFile = new byte[(int) psLength]; System.arraycopy(file, 0, rawEps, 0, rawEps.length); - System.arraycopy(rawEps, (int)psStart, epsFile, 0, (int)psLength); + System.arraycopy(rawEps, (int) psStart, epsFile, 0, + (int) psLength); } } - + public byte[] getEpsFile() { return epsFile; } - - /* Get embedded preview or null */ + + /* Get embedded preview or null */ public byte[] getPreview() { InputStream is = null; if (preview == null) { if (tiffLength > 0) { - preview = new byte[(int)tiffLength]; - System.arraycopy(rawEps, (int)tiffStart, preview, 0, (int)tiffLength); + preview = new byte[(int) tiffLength]; + System.arraycopy(rawEps, (int) tiffStart, preview, 0, + (int) tiffLength); } } return preview; } - - /** Extract bounding box from eps part - */ + + /** Extract bounding box from eps part + */ private long[] readBBox() { long[] mbbox = null; int idx = 0; byte[] bbxName = "%%BoundingBox: ".getBytes(); boolean found = false; - - while (!found && (epsFile.length > (idx + bbxName.length))) { + + while (!found && (epsFile.length > (idx + bbxName.length))) { boolean sfound = true; int i = idx; - for (i = idx; sfound && (i-idx) < bbxName.length; i++) { + for (i = idx; sfound && (i - idx) < bbxName.length; i++) { if (bbxName[i - idx] != epsFile[i]) sfound = false; } @@ -166,52 +169,51 @@ public class EPSReader extends AbstractImageReader { idx++; } } - + if (!found) return mbbox; - - + + mbbox = new long[4]; idx += readLongString(mbbox, 0, idx); idx += readLongString(mbbox, 1, idx); idx += readLongString(mbbox, 2, idx); idx += readLongString(mbbox, 3, idx); - + return mbbox; } - + private int readLongString(long[] mbbox, int i, int idx) { - while (idx < epsFile.length && - (epsFile[idx] == 32)) + while (idx < epsFile.length && (epsFile[idx] == 32)) idx++; - + int nidx = idx; - + while (nidx < epsFile.length && - (epsFile[nidx] >= 48 && epsFile[nidx] <= 57)) + (epsFile[nidx] >= 48 && epsFile[nidx] <= 57)) nidx++; - + byte[] num = new byte[nidx - idx]; - System.arraycopy(epsFile, idx, num, 0, nidx-idx); + System.arraycopy(epsFile, idx, num, 0, nidx - idx); String ns = new String(num); mbbox[i] = Long.parseLong(ns); - - return (1+nidx - idx); + + return (1 + nidx - idx); } - + public String getMimeType() { return "image/eps"; } - - /** - * Return the BoundingBox - */ + + /** + * Return the BoundingBox + */ public int[] getBBox() { int[] bbox = new int[4]; - bbox[0] = (int)this.bbox[0]; - bbox[1] = (int)this.bbox[1]; - bbox[2] = (int)this.bbox[2]; - bbox[3] = (int)this.bbox[3]; + bbox[0] = (int) this.bbox[0]; + bbox[1] = (int) this.bbox[1]; + bbox[2] = (int) this.bbox[2]; + bbox[3] = (int) this.bbox[3]; return bbox; } } diff --git a/src/org/apache/fop/image/analyser/GIFReader.java b/src/org/apache/fop/image/analyser/GIFReader.java index b3b8edd23..0618d9540 100644 --- a/src/org/apache/fop/image/analyser/GIFReader.java +++ b/src/org/apache/fop/image/analyser/GIFReader.java @@ -11,6 +11,8 @@ package org.apache.fop.image.analyser; import java.io.BufferedInputStream; import java.io.IOException; +import org.apache.fop.fo.FOUserAgent; + /** * ImageReader object for GIF image type. * @author Pankaj Narula @@ -20,14 +22,14 @@ public class GIFReader extends AbstractImageReader { static protected final int GIF_SIG_LENGTH = 10; protected byte[] header; - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { + public boolean verifySignature(String uri, BufferedInputStream fis, + FOUserAgent ua) throws IOException { this.imageStream = fis; this.setDefaultHeader(); - boolean supported = ((header[0] == 'G') && (header[1] == 'I') - && (header[2] == 'F') && (header[3] == '8') - && (header[4] == '7' || header[4] == '9') - && (header[5] == 'a')); + boolean supported = ((header[0] == 'G') && (header[1] == 'I') && + (header[2] == 'F') && (header[3] == '8') && + (header[4] == '7' || header[4] == '9') && + (header[5] == 'a')); if (supported) { setDimension(); return true; diff --git a/src/org/apache/fop/image/analyser/ImageReader.java b/src/org/apache/fop/image/analyser/ImageReader.java index 52f43bff4..5554b5db5 100644 --- a/src/org/apache/fop/image/analyser/ImageReader.java +++ b/src/org/apache/fop/image/analyser/ImageReader.java @@ -11,6 +11,8 @@ package org.apache.fop.image.analyser; import java.io.BufferedInputStream; import java.io.IOException; +import org.apache.fop.fo.FOUserAgent; + /** * ImageReader objects read image headers to determine the image size. * @author Pankaj Narula @@ -24,8 +26,8 @@ public interface ImageReader { * @return true if image type is the handled one * @exception IOException io error */ - public boolean verifySignature(String uri, BufferedInputStream bis) - throws IOException; + public boolean verifySignature(String uri, BufferedInputStream bis, + FOUserAgent ua) throws IOException; /** * Return the used InputStream. diff --git a/src/org/apache/fop/image/analyser/ImageReaderFactory.java b/src/org/apache/fop/image/analyser/ImageReaderFactory.java index f2c2160b7..62591eac3 100644 --- a/src/org/apache/fop/image/analyser/ImageReaderFactory.java +++ b/src/org/apache/fop/image/analyser/ImageReaderFactory.java @@ -11,11 +11,9 @@ package org.apache.fop.image.analyser; import java.io.InputStream; import java.io.BufferedInputStream; import java.io.IOException; -import java.util.Enumeration; -import java.util.Vector; +import java.util.ArrayList; -// FOP -import org.apache.fop.image.FopImageException; +import org.apache.fop.fo.FOUserAgent; /** * Factory for ImageReader objects. @@ -23,41 +21,41 @@ import org.apache.fop.image.FopImageException; * @version 1.0 */ public class ImageReaderFactory { - static protected Vector formats = null; + static protected ArrayList formats = new ArrayList(); + static { + formats.add(new JPEGReader()); + formats.add(new BMPReader()); + formats.add(new GIFReader()); + formats.add(new PNGReader()); + formats.add(new TIFFReader()); + formats.add(new EPSReader()); + formats.add(new SVGReader()); + }; + + // TODO - a way to add other readers /** * ImageReader maker. * @param in image input stream * @return ImageReader object - * @exception FopImageException an error occured during creation or * image type is not supported */ - static public ImageReader Make(String uri, - InputStream in) throws FopImageException { - - // need to use a config file and remove static methods - formats = new Vector(); - formats.addElement(new JPEGReader()); - formats.addElement(new BMPReader()); - formats.addElement(new GIFReader()); - formats.addElement(new PNGReader()); - formats.addElement(new TIFFReader()); - formats.addElement(new EPSReader()); - formats.addElement(new SVGReader()); - // + static public ImageReader make(String uri, InputStream in, + FOUserAgent ua) { ImageReader reader; BufferedInputStream bis = new BufferedInputStream(in); - Enumeration itr = formats.elements(); try { - while (itr.hasMoreElements()) { - reader = (ImageReader)itr.nextElement(); - if (reader.verifySignature(uri, bis)) { + for (int count = 0; count < formats.size(); count++) { + reader = (ImageReader) formats.get(count); + if (reader.verifySignature(uri, bis, ua)) { return reader; } } } catch (IOException ex) { - throw new FopImageException(ex.getMessage()); + ua.getLogger().error( + "Error while recovering Image Informations (" + + uri + ") : " + ex.getMessage()); } return null; } diff --git a/src/org/apache/fop/image/analyser/JPEGReader.java b/src/org/apache/fop/image/analyser/JPEGReader.java index 0e1412a8b..16964e4fe 100644 --- a/src/org/apache/fop/image/analyser/JPEGReader.java +++ b/src/org/apache/fop/image/analyser/JPEGReader.java @@ -11,6 +11,8 @@ package org.apache.fop.image.analyser; import java.io.BufferedInputStream; import java.io.IOException; +import org.apache.fop.fo.FOUserAgent; + /** * ImageReader object for JPEG image type. * @author Pankaj Narula @@ -25,26 +27,26 @@ public class JPEGReader extends AbstractImageReader { * inside the APPn marker. And we don't want to confuse those dimensions with * the image dimensions. */ - static protected final int MARK = 0xff; // Beginneing of a Marker - static protected final int NULL = 0x00; // Special case for 0xff00 - static protected final int SOF1 = 0xc0; // Baseline DCT - static protected final int SOF2 = 0xc1; // Extended Sequential DCT - static protected final int SOF3 = 0xc2; // Progrssive DCT only PDF 1.3 - static protected final int SOFA = 0xca; // Progressice DCT only PDF 1.3 - static protected final int APP0 = 0xe0; // Application marker, JFIF - static protected final int APPF = 0xef; // Application marker - static protected final int SOS = 0xda; // Start of Scan - static protected final int SOI = 0xd8; // start of Image + static protected final int MARK = 0xff; // Beginneing of a Marker + static protected final int NULL = 0x00; // Special case for 0xff00 + static protected final int SOF1 = 0xc0; // Baseline DCT + static protected final int SOF2 = 0xc1; // Extended Sequential DCT + static protected final int SOF3 = 0xc2; // Progrssive DCT only PDF 1.3 + static protected final int SOFA = 0xca; // Progressice DCT only PDF 1.3 + static protected final int APP0 = 0xe0; // Application marker, JFIF + static protected final int APPF = 0xef; // Application marker + static protected final int SOS = 0xda; // Start of Scan + static protected final int SOI = 0xd8; // start of Image static protected final int JPG_SIG_LENGTH = 2; protected byte[] header; - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { + public boolean verifySignature(String uri, BufferedInputStream fis, + FOUserAgent ua) throws IOException { this.imageStream = fis; this.setDefaultHeader(); - boolean supported = ((header[0] == (byte)0xff) - && (header[1] == (byte)0xd8)); + boolean supported = ((header[0] == (byte) 0xff) && + (header[1] == (byte) 0xd8)); if (supported) { setDimension(); return true; @@ -81,25 +83,26 @@ public class JPEGReader extends AbstractImageReader { } do { marker = imageStream.read(); - } while (marker == MARK); + } while (marker == MARK) + ; switch (marker) { - case SOI: - break; - case NULL: - break; - case SOF1: - case SOF2: - case SOF3: // SOF3 and SOFA are only supported by PDF 1.3 - case SOFA: - this.skip(3); - this.height = this.read2bytes(); - this.width = this.read2bytes(); - break outer; - default: - length = this.read2bytes(); - skipped = this.skip(length - 2); - if (skipped != length - 2) - throw new IOException("Skipping Error"); + case SOI: + break; + case NULL: + break; + case SOF1: + case SOF2: + case SOF3: // SOF3 and SOFA are only supported by PDF 1.3 + case SOFA: + this.skip(3); + this.height = this.read2bytes(); + this.width = this.read2bytes(); + break outer; + default: + length = this.read2bytes(); + skipped = this.skip(length - 2); + if (skipped != length - 2) + throw new IOException("Skipping Error"); } } } catch (IOException ioe) { @@ -122,7 +125,7 @@ public class JPEGReader extends AbstractImageReader { imageStream.read(); discarded++; } - return discarded; // scope for exception + return discarded; // scope for exception } } diff --git a/src/org/apache/fop/image/analyser/PNGReader.java b/src/org/apache/fop/image/analyser/PNGReader.java index 64f175b2e..29d794504 100644 --- a/src/org/apache/fop/image/analyser/PNGReader.java +++ b/src/org/apache/fop/image/analyser/PNGReader.java @@ -11,6 +11,8 @@ package org.apache.fop.image.analyser; import java.io.BufferedInputStream; import java.io.IOException; +import org.apache.fop.fo.FOUserAgent; + /** * ImageReader object for PNG image type. * @author Pankaj Narula @@ -20,18 +22,15 @@ public class PNGReader extends AbstractImageReader { static protected final int PNG_SIG_LENGTH = 24; protected byte[] header; - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { + public boolean verifySignature(String uri, BufferedInputStream fis, + FOUserAgent ua) throws IOException { this.imageStream = fis; this.setDefaultHeader(); - boolean supported = ((header[0] == (byte)0x89) - && (header[1] == (byte)0x50) - && (header[2] == (byte)0x4e) - && (header[3] == (byte)0x47) - && (header[4] == (byte)0x0d) - && (header[5] == (byte)0x0a) - && (header[6] == (byte)0x1a) - && (header[7] == (byte)0x0a)); + boolean supported = ((header[0] == (byte) 0x89) && + (header[1] == (byte) 0x50) && (header[2] == (byte) 0x4e) && + (header[3] == (byte) 0x47) && (header[4] == (byte) 0x0d) && + (header[5] == (byte) 0x0a) && + (header[6] == (byte) 0x1a) && (header[7] == (byte) 0x0a)); if (supported) { setDimension(); return true; @@ -49,7 +48,8 @@ public class PNGReader extends AbstractImageReader { int byte2 = header[17] & 0xff; int byte3 = header[18] & 0xff; int byte4 = header[19] & 0xff; - long l = (long)((byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4); + long l = (long)((byte1 << 24) | (byte2 << 16) | + (byte3 << 8) | byte4); this.width = (int)(l); byte1 = header[20] & 0xff; diff --git a/src/org/apache/fop/image/analyser/SVGReader.java b/src/org/apache/fop/image/analyser/SVGReader.java index bf0a43919..54b25f90f 100644 --- a/src/org/apache/fop/image/analyser/SVGReader.java +++ b/src/org/apache/fop/image/analyser/SVGReader.java @@ -46,18 +46,30 @@ import java.awt.Point; import java.awt.geom.Dimension2D; import java.awt.Dimension; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.svg.SVGUserAgent; + /** * ImageReader object for SVG document image type. */ public class SVGReader extends AbstractImageReader { - public boolean verifySignature(String uri, - BufferedInputStream fis) throws IOException { + public static final String SVG_MIME_TYPE = "image/svg+xml"; + FOUserAgent userAgent; + SVGDocument doc; + + public boolean verifySignature(String uri, BufferedInputStream fis, + FOUserAgent ua) throws IOException { this.imageStream = fis; + userAgent = ua; return loadImage(uri); } public String getMimeType() { - return "image/svg+xml"; + return SVG_MIME_TYPE; + } + + public SVGDocument getDocument() { + return doc; } /** @@ -67,156 +79,52 @@ public class SVGReader extends AbstractImageReader { protected boolean loadImage(String uri) { // parse document and get the size attributes of the svg element try { + int length = imageStream.available(); + imageStream.mark(length); SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(SVGImage.getParserName()); - SVGDocument doc = factory.createDocument(uri, imageStream); + doc = factory.createDocument(uri, imageStream); - Element e = ((SVGDocument)doc).getRootElement(); + Element e = ((SVGDocument) doc).getRootElement(); String s; - UserAgent userAgent = new MUserAgent(new AffineTransform()); - BridgeContext ctx = new BridgeContext(userAgent); - UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, e); + SVGUserAgent userAg = new SVGUserAgent(new AffineTransform()); + userAg.setLogger(userAgent.getLogger()); + BridgeContext ctx = new BridgeContext(userAg); + UnitProcessor.Context uctx = + UnitProcessor.createContext(ctx, e); // 'width' attribute - default is 100% s = e.getAttributeNS(null, SVGOMDocument.SVG_WIDTH_ATTRIBUTE); if (s.length() == 0) { s = SVGOMDocument.SVG_SVG_WIDTH_DEFAULT_VALUE; } - width = (int)UnitProcessor.svgHorizontalLengthToUserSpace - (s, SVGOMDocument.SVG_WIDTH_ATTRIBUTE, uctx); + width = (int) UnitProcessor.svgHorizontalLengthToUserSpace ( + s, SVGOMDocument.SVG_WIDTH_ATTRIBUTE, uctx); // 'height' attribute - default is 100% s = e.getAttributeNS(null, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE); if (s.length() == 0) { s = SVGOMDocument.SVG_SVG_HEIGHT_DEFAULT_VALUE; } - height = (int)UnitProcessor.svgVerticalLengthToUserSpace - (s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx); + height = (int) UnitProcessor.svgVerticalLengthToUserSpace ( + s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx); return true; } catch (NoClassDefFoundError ncdfe) { - //log.error("Batik not in class path"); + //userAgent.getLogger().error("Batik not in class path", ncdfe); return false; } catch (Exception e) { - //log.error("Could not load external SVG: " + - // e.getMessage()); + //userAgent.getLogger().error("Could not load external SVG: " + + // e.getMessage(), e); // assuming any exception means this document is not svg // or could not be loaded for some reason - return false; - } - } - - protected class MUserAgent implements UserAgent { - AffineTransform currentTransform = null; - - /** - * Creates a new SVGUserAgent. - */ - protected MUserAgent(AffineTransform at) { - currentTransform = at; - } - - /** - * Displays an error message. - */ - public void displayError(String message) { - System.err.println(message); - } - - /** - * Displays an error resulting from the specified Exception. - */ - public void displayError(Exception ex) { - ex.printStackTrace(System.err); - } - - /** - * Displays a message in the User Agent interface. - * The given message is typically displayed in a status bar. - */ - public void displayMessage(String message) { - System.out.println(message); - } - - /** - * Returns a customized the pixel to mm factor. - */ - public float getPixelToMM() { - // this is set to 72dpi as the values in fo are 72dpi - return 0.35277777777777777778f; // 72 dpi - // return 0.26458333333333333333333333333333f; // 96dpi - } - - /** - * Returns the language settings. - */ - public String getLanguages() { - return "en"; // userLanguages; - } - - public String getMedia() { - return "print"; - } - - /** - * Returns the user stylesheet uri. - * @return null if no user style sheet was specified. - */ - public String getUserStyleSheetURI() { - return null; // userStyleSheetURI; - } + try { + imageStream.reset(); + } catch (IOException ioe) { } - /** - * Returns the class name of the XML parser. - */ - public String getXMLParserClassName() { - return org.apache.fop.apps.Driver.getParserClassName(); - } - - public boolean isXMLParserValidating() { return false; } - - /** - * Opens a link in a new component. - * @param doc The current document. - * @param uri The document URI. - */ - public void openLink(SVGAElement elt) { - } - - public Point getClientAreaLocationOnScreen() { - return new Point(0, 0); - } - - public void setSVGCursor(java.awt.Cursor cursor) {} - - - public AffineTransform getTransform() { - return currentTransform; - } - - public Dimension2D getViewportSize() { - return new Dimension(100, 100); - } - - public EventDispatcher getEventDispatcher() { - return null; - } - - public boolean supportExtension(String str) { - return false; - } - - public boolean hasFeature(String str) { - return false; - } - - public void registerExtension(BridgeExtension be) {} - - public void handleElement(Element elt, Object data) {} - } } diff --git a/src/org/apache/fop/image/analyser/TIFFReader.java b/src/org/apache/fop/image/analyser/TIFFReader.java index 9434ac3ff..ea8d2fec9 100644 --- a/src/org/apache/fop/image/analyser/TIFFReader.java +++ b/src/org/apache/fop/image/analyser/TIFFReader.java @@ -11,6 +11,8 @@ package org.apache.fop.image.analyser; import java.io.BufferedInputStream; import java.io.IOException; +import org.apache.fop.fo.FOUserAgent; + /** * ImageReader object for TIFF image type. * @author Pankaj Narula, Michael Lee @@ -20,25 +22,21 @@ public class TIFFReader extends AbstractImageReader { static protected final int TIFF_SIG_LENGTH = 8; protected byte[] header; - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { + public boolean verifySignature(String uri, BufferedInputStream fis, + FOUserAgent ua) throws IOException { this.imageStream = fis; this.setDefaultHeader(); boolean supported = false; - if (header[0] == (byte)0x49 - && header[1] - == (byte)0x49) // first 2 bytes = II (little endian encoding) - { + if (header[0] == (byte) 0x49 && header[1] == (byte) 0x49)// first 2 bytes = II (little endian encoding) + { // look for '42' in byte 3 and '0' in byte 4 if (header[2] == 42 && header[3] == 0) supported = true; } - if (header[0] == (byte)0x4D - && header[1] - == (byte)0x4D) // first 2 bytes == MM (big endian encoding) - { + if (header[0] == (byte) 0x4D && header[1] == (byte) 0x4D)// first 2 bytes == MM (big endian encoding) + { // look for '42' in byte 4 and '0' in byte 3 if (header[2] == 0 && header[3] == 42) supported = true; diff --git a/src/org/apache/fop/pdf/PDFXObject.java b/src/org/apache/fop/pdf/PDFXObject.java index 35754b739..6b97e43c7 100644 --- a/src/org/apache/fop/pdf/PDFXObject.java +++ b/src/org/apache/fop/pdf/PDFXObject.java @@ -21,7 +21,6 @@ import org.apache.fop.pdf.PDFICCStream; import org.apache.fop.image.FopImage; import org.apache.fop.image.EPSImage; import org.apache.fop.image.JpegImage; -import org.apache.fop.image.FopImageException; /** * PDF XObject @@ -50,8 +49,9 @@ public class PDFXObject extends PDFObject { super(number); isPS = false; this.Xnum = Xnumber; - if (img == null) + if (img == null) { //log.error("FISH"); + } fopimage = img; this.pdfDoc = pdfdoc; pdfICCStream = null; @@ -142,8 +142,6 @@ public class PDFXObject extends PDFObject { p = p + "/Subtype /PS\n"; p = p + "/Length " + imgStream.getDataLength(); - // don't know if it's the good place (other objects can have references to it) - fopimage.close(); p = p + dictEntries; p = p + ">>\n"; @@ -208,9 +206,6 @@ public class PDFXObject extends PDFObject { p = p + dictEntries; p = p + ">>\n"; - // don't know if it's the good place (other objects can have references to it) - fopimage.close(); - // push the pdf dictionary on the writer byte[] pdfBytes = p.getBytes(); stream.write(pdfBytes); @@ -222,7 +217,7 @@ public class PDFXObject extends PDFObject { stream.write(pdfBytes); length += pdfBytes.length; } - } catch (FopImageException imgex) { + } catch (Exception imgex) { //log.error("Error in XObject : " // + imgex.getMessage()); } diff --git a/src/org/apache/fop/render/ps/PSGraphics2D.java b/src/org/apache/fop/render/ps/PSGraphics2D.java index 0ab552695..e2fe42180 100644 --- a/src/org/apache/fop/render/ps/PSGraphics2D.java +++ b/src/org/apache/fop/render/ps/PSGraphics2D.java @@ -13,6 +13,7 @@ import org.apache.fop.fonts.*; import org.apache.fop.render.pdf.*; import org.apache.fop.image.*; import org.apache.fop.datatypes.ColorSpace; +import org.apache.fop.fo.FOUserAgent; import org.apache.batik.ext.awt.g2d.*; @@ -235,7 +236,7 @@ public class PSGraphics2D extends AbstractGraphics2D { PDFColor transparent = new PDFColor(255, 255, 255); TempImage(int width, int height, byte[] result, - byte[] mask) throws FopImageException { + byte[] mask) { this.m_height = height; this.m_width = width; this.m_bitsPerPixel = 8; @@ -246,67 +247,75 @@ public class PSGraphics2D extends AbstractGraphics2D { this.m_mask = mask; } + public boolean load(int type, FOUserAgent ua) { + return true; + } + + public String getMimeType() { + return ""; + } + public String getURL() { return "" + m_bitmaps; } // image size - public int getWidth() throws FopImageException { + public int getWidth() { return m_width; } - public int getHeight() throws FopImageException { + public int getHeight() { return m_height; } // DeviceGray, DeviceRGB, or DeviceCMYK - public ColorSpace getColorSpace() throws FopImageException { + public ColorSpace getColorSpace() { return m_colorSpace; } // bits per pixel - public int getBitsPerPixel() throws FopImageException { + public int getBitsPerPixel() { return m_bitsPerPixel; } // For transparent images - public boolean isTransparent() throws FopImageException { + public boolean isTransparent() { return transparent != null; } - public PDFColor getTransparentColor() throws FopImageException { + public PDFColor getTransparentColor() { return transparent; } - public byte[] getMask() throws FopImageException { + public byte[] getMask() { return m_mask; } // get the image bytes, and bytes properties // get uncompressed image bytes - public byte[] getBitmaps() throws FopImageException { + public byte[] getBitmaps() { return m_bitmaps; } // width * (bitsPerPixel / 8) * height, no ? - public int getBitmapsSize() throws FopImageException { + public int getBitmapsSize() { return m_width * m_height * 3; } // get compressed image bytes // I don't know if we really need it, nor if it // should be changed... - public byte[] getRessourceBytes() throws FopImageException { + public byte[] getRessourceBytes() { return null; } - public int getRessourceBytesSize() throws FopImageException { + public int getRessourceBytesSize() { return 0; } // return null if no corresponding PDFFilter - public PDFFilter getPDFFilter() throws FopImageException { + public PDFFilter getPDFFilter() { return null; } diff --git a/src/org/apache/fop/render/ps/PSRenderer.java b/src/org/apache/fop/render/ps/PSRenderer.java index 6a5699cec..cae6e4287 100644 --- a/src/org/apache/fop/render/ps/PSRenderer.java +++ b/src/org/apache/fop/render/ps/PSRenderer.java @@ -13,7 +13,6 @@ import org.apache.fop.render.AbstractRenderer; import org.apache.fop.render.Renderer; import org.apache.fop.image.ImageArea; import org.apache.fop.image.FopImage; -import org.apache.fop.image.FopImageException; import org.apache.fop.layout.*; import org.apache.fop.layout.inline.*; import org.apache.fop.datatypes.*; diff --git a/src/org/apache/fop/svg/PDFGraphics2D.java b/src/org/apache/fop/svg/PDFGraphics2D.java index 45bc493c1..21e9598e2 100644 --- a/src/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/org/apache/fop/svg/PDFGraphics2D.java @@ -15,6 +15,7 @@ import org.apache.fop.image.*; import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.render.pdf.CIDFont; import org.apache.fop.render.pdf.fonts.LazyFont; +import org.apache.fop.fo.FOUserAgent; import org.apache.batik.ext.awt.g2d.*; import org.apache.batik.ext.awt.image.GraphicsUtil; @@ -320,7 +321,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { PDFColor transparent = new PDFColor(255, 255, 255); TempImage(int width, int height, byte[] result, - byte[] mask) throws FopImageException { + byte[] mask) { this.m_height = height; this.m_width = width; this.m_bitsPerPixel = 8; @@ -331,67 +332,75 @@ public class PDFGraphics2D extends AbstractGraphics2D { this.m_mask = mask; } + public boolean load(int type, FOUserAgent ua) { + return true; + } + + public String getMimeType() { + return ""; + } + public String getURL() { return "" + m_bitmaps; } // image size - public int getWidth() throws FopImageException { + public int getWidth() { return m_width; } - public int getHeight() throws FopImageException { + public int getHeight() { return m_height; } // DeviceGray, DeviceRGB, or DeviceCMYK - public ColorSpace getColorSpace() throws FopImageException { + public ColorSpace getColorSpace() { return m_colorSpace; } // bits per pixel - public int getBitsPerPixel() throws FopImageException { + public int getBitsPerPixel() { return m_bitsPerPixel; } // For transparent images - public boolean isTransparent() throws FopImageException { + public boolean isTransparent() { return transparent != null; } - public PDFColor getTransparentColor() throws FopImageException { + public PDFColor getTransparentColor() { return transparent; } - public byte[] getMask() throws FopImageException { + public byte[] getMask() { return m_mask; } // get the image bytes, and bytes properties // get uncompressed image bytes - public byte[] getBitmaps() throws FopImageException { + public byte[] getBitmaps() { return m_bitmaps; } // width * (bitsPerPixel / 8) * height, no ? - public int getBitmapsSize() throws FopImageException { + public int getBitmapsSize() { return m_width * m_height * 3; } // get compressed image bytes // I don't know if we really need it, nor if it // should be changed... - public byte[] getRessourceBytes() throws FopImageException { + public byte[] getRessourceBytes() { return null; } - public int getRessourceBytesSize() throws FopImageException { + public int getRessourceBytesSize() { return 0; } // return null if no corresponding PDFFilter - public PDFFilter getPDFFilter() throws FopImageException { + public PDFFilter getPDFFilter() { return null; } @@ -780,7 +789,6 @@ public class PDFGraphics2D extends AbstractGraphics2D { System.out.println("drawRenderedImage"); } - /** * Renders a * {@link RenderableImage}, |