Bladeren bron

some preliminary changes to image handling

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-ffa450edef68
pull/30/head
Keiron Liddle 22 jaren geleden
bovenliggende
commit
ca6552371e
38 gewijzigde bestanden met toevoegingen van 1185 en 1279 verwijderingen
  1. 3
    1
      src/org/apache/fop/apps/Driver.java
  2. 2
    0
      src/org/apache/fop/area/inline/Space.java
  3. 10
    0
      src/org/apache/fop/fo/FOUserAgent.java
  4. 20
    64
      src/org/apache/fop/fo/flow/Character.java
  5. 65
    205
      src/org/apache/fop/fo/flow/ExternalGraphic.java
  6. 4
    23
      src/org/apache/fop/fo/flow/InstreamForeignObject.java
  7. 13
    0
      src/org/apache/fop/fo/flow/Leader.java
  8. 0
    1
      src/org/apache/fop/fo/flow/Wrapper.java
  9. 48
    96
      src/org/apache/fop/image/AbstractFopImage.java
  10. 65
    62
      src/org/apache/fop/image/BmpImage.java
  11. 21
    31
      src/org/apache/fop/image/EPSImage.java
  12. 25
    22
      src/org/apache/fop/image/FopImage.java
  13. 7
    8
      src/org/apache/fop/image/FopImageConsumer.java
  14. 0
    23
      src/org/apache/fop/image/FopImageException.java
  15. 0
    203
      src/org/apache/fop/image/FopImageFactory.java
  16. 40
    40
      src/org/apache/fop/image/GifImage.java
  17. 3
    6
      src/org/apache/fop/image/ImageArea.java
  18. 21
    0
      src/org/apache/fop/image/ImageCache.java
  19. 381
    0
      src/org/apache/fop/image/ImageFactory.java
  20. 42
    0
      src/org/apache/fop/image/ImageLoader.java
  21. 40
    41
      src/org/apache/fop/image/JAIImage.java
  22. 43
    52
      src/org/apache/fop/image/JimiImage.java
  23. 64
    57
      src/org/apache/fop/image/JpegImage.java
  24. 13
    18
      src/org/apache/fop/image/SVGImage.java
  25. 4
    2
      src/org/apache/fop/image/analyser/AbstractImageReader.java
  26. 8
    5
      src/org/apache/fop/image/analyser/BMPReader.java
  27. 73
    71
      src/org/apache/fop/image/analyser/EPSReader.java
  28. 8
    6
      src/org/apache/fop/image/analyser/GIFReader.java
  29. 4
    2
      src/org/apache/fop/image/analyser/ImageReader.java
  30. 22
    24
      src/org/apache/fop/image/analyser/ImageReaderFactory.java
  31. 36
    33
      src/org/apache/fop/image/analyser/JPEGReader.java
  32. 11
    11
      src/org/apache/fop/image/analyser/PNGReader.java
  33. 34
    126
      src/org/apache/fop/image/analyser/SVGReader.java
  34. 8
    10
      src/org/apache/fop/image/analyser/TIFFReader.java
  35. 3
    8
      src/org/apache/fop/pdf/PDFXObject.java
  36. 22
    13
      src/org/apache/fop/render/ps/PSGraphics2D.java
  37. 0
    1
      src/org/apache/fop/render/ps/PSRenderer.java
  38. 22
    14
      src/org/apache/fop/svg/PDFGraphics2D.java

+ 3
- 1
src/org/apache/fop/apps/Driver.java Bestand weergeven

@@ -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) {

+ 2
- 0
src/org/apache/fop/area/inline/Space.java Bestand weergeven

@@ -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);

+ 10
- 0
src/org/apache/fop/fo/FOUserAgent.java Bestand weergeven

@@ -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.

+ 20
- 64
src/org/apache/fop/fo/flow/Character.java Bestand weergeven

@@ -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() {

+ 65
- 205
src/org/apache/fop/fo/flow/ExternalGraphic.java Bestand weergeven

@@ -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");
}

}

+ 4
- 23
src/org/apache/fop/fo/flow/InstreamForeignObject.java Bestand weergeven

@@ -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;
}

/**

+ 13
- 0
src/org/apache/fop/fo/flow/Leader.java Bestand weergeven

@@ -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

+ 0
- 1
src/org/apache/fop/fo/flow/Wrapper.java Bestand weergeven

@@ -25,7 +25,6 @@ public class Wrapper extends FObjMixed {

public Wrapper(FONode parent) {
super(parent);
// check that this occurs inside an fo:flow
}

}

+ 48
- 96
src/org/apache/fop/image/AbstractFopImage.java Bestand weergeven

@@ -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;
}

}


+ 65
- 62
src/org/apache/fop/image/BmpImage.java Bestand weergeven

@@ -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;
}

}

+ 21
- 31
src/org/apache/fop/image/EPSImage.java Bestand weergeven

@@ -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;
}
}

+ 25
- 22
src/org/apache/fop/image/FopImage.java Bestand weergeven

@@ -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();
}


+ 7
- 8
src/org/apache/fop/image/FopImageConsumer.java Bestand weergeven

@@ -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;
}

+ 0
- 23
src/org/apache/fop/image/FopImageException.java Bestand weergeven

@@ -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);
}

}

+ 0
- 203
src/org/apache/fop/image/FopImageFactory.java Bestand weergeven

@@ -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;
}

}


+ 40
- 40
src/org/apache/fop/image/GifImage.java Bestand weergeven

@@ -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;
}

}

+ 3
- 6
src/org/apache/fop/image/ImageArea.java Bestand weergeven

@@ -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;

+ 21
- 0
src/org/apache/fop/image/ImageCache.java Bestand weergeven

@@ -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);
}


+ 381
- 0
src/org/apache/fop/image/ImageFactory.java Bestand weergeven

@@ -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;
}

}

}


+ 42
- 0
src/org/apache/fop/image/ImageLoader.java Bestand weergeven

@@ -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;
}

}

+ 40
- 41
src/org/apache/fop/image/JAIImage.java Bestand weergeven

@@ -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());
*/}
}

}

+ 43
- 52
src/org/apache/fop/image/JimiImage.java Bestand weergeven

@@ -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);
}
}
}

+ 64
- 57
src/org/apache/fop/image/JpegImage.java Bestand weergeven

@@ -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
- 18
src/org/apache/fop/image/SVGImage.java Bestand weergeven

@@ -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;
}


+ 4
- 2
src/org/apache/fop/image/analyser/AbstractImageReader.java Bestand weergeven

@@ -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;

+ 8
- 5
src/org/apache/fop/image/analyser/BMPReader.java Bestand weergeven

@@ -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;

+ 73
- 71
src/org/apache/fop/image/analyser/EPSReader.java Bestand weergeven

@@ -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;
}
}

+ 8
- 6
src/org/apache/fop/image/analyser/GIFReader.java Bestand weergeven

@@ -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;

+ 4
- 2
src/org/apache/fop/image/analyser/ImageReader.java Bestand weergeven

@@ -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.

+ 22
- 24
src/org/apache/fop/image/analyser/ImageReaderFactory.java Bestand weergeven

@@ -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;
}

+ 36
- 33
src/org/apache/fop/image/analyser/JPEGReader.java Bestand weergeven

@@ -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
- 11
src/org/apache/fop/image/analyser/PNGReader.java Bestand weergeven

@@ -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;

+ 34
- 126
src/org/apache/fop/image/analyser/SVGReader.java Bestand weergeven

@@ -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) {}

}

}

+ 8
- 10
src/org/apache/fop/image/analyser/TIFFReader.java Bestand weergeven

@@ -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;

+ 3
- 8
src/org/apache/fop/pdf/PDFXObject.java Bestand weergeven

@@ -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());
}

+ 22
- 13
src/org/apache/fop/render/ps/PSGraphics2D.java Bestand weergeven

@@ -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;
}


+ 0
- 1
src/org/apache/fop/render/ps/PSRenderer.java Bestand weergeven

@@ -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.*;

+ 22
- 14
src/org/apache/fop/svg/PDFGraphics2D.java Bestand weergeven

@@ -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},

Laden…
Annuleren
Opslaan