Images are put into a cache, different cahces are possible if information is required it needs to be explicitly loaded git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194663 13f79535-47bb-0310-9956-ffa450edef68pull/30/head
@@ -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) { |
@@ -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); |
@@ -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. |
@@ -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() { |
@@ -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"); | |||
} | |||
} |
@@ -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; | |||
} | |||
/** |
@@ -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 |
@@ -25,7 +25,6 @@ public class Wrapper extends FObjMixed { | |||
public Wrapper(FONode parent) { | |||
super(parent); | |||
// check that this occurs inside an fo:flow | |||
} | |||
} |
@@ -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). | |||
@@ -82,31 +83,6 @@ public abstract class AbstractFopImage implements FopImage { | |||
*/ | |||
protected PDFFilter m_compressionType = null; | |||
/** | |||
* 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 | |||
* @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: | |||
@@ -118,22 +94,51 @@ public abstract class AbstractFopImage implements FopImage { | |||
* @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; | |||
} | |||
} | |||
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
@@ -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; | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
@@ -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; | |||
} | |||
} |
@@ -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; |
@@ -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); | |||
} | |||
@@ -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; | |||
} | |||
} | |||
} | |||
@@ -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; | |||
} | |||
} |
@@ -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()); | |||
*/} | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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; |
@@ -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; | |||
} | |||
@@ -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; |
@@ -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; |
@@ -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; | |||
} | |||
} |
@@ -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; |
@@ -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. |
@@ -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; | |||
} |
@@ -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 | |||
} | |||
} |
@@ -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; |
@@ -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) {} | |||
} | |||
} |
@@ -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; |
@@ -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()); | |||
} |
@@ -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; | |||
} | |||
@@ -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.*; |
@@ -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}, |