aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/java-1.4/org/apache/fop/image/ImageIOImage.java11
-rw-r--r--src/java/org/apache/fop/image/BatikImage.java211
-rw-r--r--src/java/org/apache/fop/image/BmpImage.java36
-rw-r--r--src/java/org/apache/fop/image/GifImage.java40
-rw-r--r--src/java/org/apache/fop/image/ImageFactory.java3
-rw-r--r--src/java/org/apache/fop/image/JAIImage.java69
-rw-r--r--src/java/org/apache/fop/image/JimiImage.java44
-rw-r--r--src/java/org/apache/fop/image/JpegImage.java21
-rw-r--r--src/java/org/apache/fop/image/PNGImage.java2
-rw-r--r--src/java/org/apache/fop/image/TIFFImage.java92
-rw-r--r--src/java/org/apache/fop/pdf/BitmapImage.java16
-rw-r--r--src/java/org/apache/fop/pdf/CCFFilter.java55
-rw-r--r--src/java/org/apache/fop/pdf/PDFFilterList.java35
-rw-r--r--src/java/org/apache/fop/pdf/PDFImage.java16
-rw-r--r--src/java/org/apache/fop/pdf/PDFXObject.java7
-rw-r--r--src/java/org/apache/fop/render/pdf/FopPDFImage.java71
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderer.java26
-rw-r--r--test/layoutengine/testcases/external-graphic-tiff.xml10
-rw-r--r--test/resources/images/tiff_group4.tifbin0 -> 8656 bytes
19 files changed, 528 insertions, 237 deletions
diff --git a/src/java-1.4/org/apache/fop/image/ImageIOImage.java b/src/java-1.4/org/apache/fop/image/ImageIOImage.java
index 369bb6e8d..882f36d92 100644
--- a/src/java-1.4/org/apache/fop/image/ImageIOImage.java
+++ b/src/java-1.4/org/apache/fop/image/ImageIOImage.java
@@ -42,9 +42,20 @@ public class ImageIOImage extends AbstractFopImage {
super(info);
}
+ /**
+ * @see org.apache.fop.image.AbstractFopImage#loadDimensions()
+ */
+ protected boolean loadDimensions() {
+ if (this.bitmaps == null) {
+ return loadBitmap();
+ }
+ return true;
+ }
+
/** @see org.apache.fop.image.AbstractFopImage#loadBitmap() */
protected boolean loadBitmap() {
try {
+ inputStream.reset();
BufferedImage imageData = ImageIO.read(inputStream);
this.height = imageData.getHeight();
diff --git a/src/java/org/apache/fop/image/BatikImage.java b/src/java/org/apache/fop/image/BatikImage.java
index b0987906e..9c99eb465 100644
--- a/src/java/org/apache/fop/image/BatikImage.java
+++ b/src/java/org/apache/fop/image/BatikImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2004 The Apache Software Foundation
+ * Copyright 2004-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,6 +43,16 @@ public abstract class BatikImage extends AbstractFopImage {
private byte[] softMask = null;
/**
+ * The InputStream wrapped into a SeekableStream for decoding.
+ */
+ protected SeekableStream seekableInput = null;
+
+ /**
+ * The Batik representation of the image
+ */
+ protected CachableRed cr = null;
+
+ /**
* Constructs a new BatikImage instance.
* @param imgReader basic metadata for the image
*/
@@ -54,11 +64,72 @@ public abstract class BatikImage extends AbstractFopImage {
* @see org.apache.fop.image.AbstractFopImage#loadDimensions()
*/
protected boolean loadDimensions() {
- if (this.bitmaps == null) {
- loadImage();
- }
+ if (seekableInput == null && inputStream != null) {
+ try {
+ seekableInput = new FileCacheSeekableStream(inputStream);
+ } catch (IOException ioe) {
+ seekableInput = new MemoryCacheSeekableStream(inputStream);
+ }
+ try {
+ this.bitsPerPixel = 8;
+ cr = decodeImage(seekableInput);
+ this.height = cr.getHeight();
+ this.width = cr.getWidth();
+ this.isTransparent = false;
+ this.softMask = null;
+ ColorModel cm = cr.getColorModel();
+
+ this.height = cr.getHeight();
+ this.width = cr.getWidth();
+ this.isTransparent = false;
+ this.softMask = null;
+
+ int transparencyType = cm.getTransparency();
+ if (cm instanceof IndexColorModel) {
+ if (transparencyType == Transparency.BITMASK) {
+ // Use 'transparent color'.
+ IndexColorModel icm = (IndexColorModel)cm;
+ int numColor = icm.getMapSize();
+ byte [] alpha = new byte[numColor];
+ icm.getAlphas(alpha);
+ for (int i = 0; i < numColor; i++) {
+ if ((alpha[i] & 0xFF) == 0) {
+ this.isTransparent = true;
+ int red = (icm.getRed (i)) & 0xFF;
+ int grn = (icm.getGreen(i)) & 0xFF;
+ int blu = (icm.getBlue (i)) & 0xFF;
+ this.transparentColor = new Color(red, grn, blu);
+ break;
+ }
+ }
+ }
+ } else {
+ cr = new Any2sRGBRed(cr);
+ }
- return this.bitmaps != null;
+ // Get our current ColorModel
+ cm = cr.getColorModel();
+ if (this.colorSpace == null) {
+ this.colorSpace = cm.getColorSpace();
+ }
+ } catch (IOException ioe) {
+ log.error("Error while loading image (Batik): " + ioe.getMessage(), ioe);
+ try {
+ seekableInput.close();
+ } catch (IOException ioex) {
+ // ignore
+ }
+ try {
+ inputStream.close();
+ } catch (IOException ioex) {
+ // ignore
+ }
+ seekableInput = null;
+ inputStream = null;
+ return false;
+ }
+ }
+ return this.height != -1;
}
/**
@@ -106,88 +177,62 @@ public abstract class BatikImage extends AbstractFopImage {
* Loads the image from the InputStream.
*/
protected void loadImage() {
- try {
- SeekableStream seekableInput;
- try { seekableInput = new FileCacheSeekableStream(inputStream);
- } catch (IOException ioe) {
- seekableInput = new MemoryCacheSeekableStream(inputStream);
- }
-
- CachableRed cr = decodeImage(seekableInput);
- ColorModel cm = cr.getColorModel();
-
- this.height = cr.getHeight();
- this.width = cr.getWidth();
- this.isTransparent = false;
- this.softMask = null;
- this.bitmapsSize = this.width * this.height * 3;
- this.bitmaps = new byte[this.bitmapsSize];
- this.bitsPerPixel = 8;
-
- int transparencyType = cm.getTransparency();
- if (cm instanceof IndexColorModel) {
- if (transparencyType == Transparency.BITMASK) {
- // Use 'transparent color'.
- IndexColorModel icm = (IndexColorModel)cm;
- int numColor = icm.getMapSize();
- byte [] alpha = new byte[numColor];
- icm.getAlphas(alpha);
- for (int i = 0; i < numColor; i++) {
- if ((alpha[i] & 0xFF) == 0) {
- this.isTransparent = true;
- int red = (icm.getRed (i)) & 0xFF;
- int grn = (icm.getGreen(i)) & 0xFF;
- int blu = (icm.getBlue (i)) & 0xFF;
- this.transparentColor = new Color(red, grn, blu);
- break;
+ if (loadDimensions()) {
+ try {
+ // Get our current ColorModel
+ ColorModel cm = cr.getColorModel();
+
+ // It has an alpha channel so generate a soft mask.
+ if (!this.isTransparent && cm.hasAlpha())
+ this.softMask = new byte[this.width * this.height];
+
+ this.bitmapsSize = this.width * this.height * 3;
+ this.bitmaps = new byte[this.bitmapsSize];
+
+ WritableRaster wr = (WritableRaster)cr.getData();
+ BufferedImage bi = new BufferedImage
+ (cm, wr.createWritableTranslatedChild(0, 0),
+ cm.isAlphaPremultiplied(), null);
+ int [] tmpMap = new int[this.width];
+ int idx = 0;
+ int sfIdx = 0;
+ for (int y = 0; y < this.height; y++) {
+ tmpMap = bi.getRGB(0, y, this.width, 1, tmpMap, 0, this.width);
+ if (softMask != null) {
+ for (int x = 0; x < this.width; x++) {
+ int pix = tmpMap[x];
+ this.softMask[sfIdx++] = (byte)(pix >>> 24);
+ this.bitmaps[idx++] = (byte)((pix >>> 16) & 0xFF);
+ this.bitmaps[idx++] = (byte)((pix >>> 8) & 0xFF);
+ this.bitmaps[idx++] = (byte)((pix) & 0xFF);
+ }
+ } else {
+ for (int x = 0; x < this.width; x++) {
+ int pix = tmpMap[x];
+ this.bitmaps[idx++] = (byte)((pix >> 16) & 0xFF);
+ this.bitmaps[idx++] = (byte)((pix >> 8) & 0xFF);
+ this.bitmaps[idx++] = (byte)((pix) & 0xFF);
+ }
}
}
- }
- } else {
- cr = new Any2sRGBRed(cr);
- }
-
- // Get our current ColorModel
- cm = cr.getColorModel();
-
- // It has an alpha channel so generate a soft mask.
- if (!this.isTransparent && cm.hasAlpha())
- this.softMask = new byte[this.width * this.height];
-
- this.colorSpace = cm.getColorSpace();
- WritableRaster wr = (WritableRaster)cr.getData();
- BufferedImage bi = new BufferedImage
- (cm, wr.createWritableTranslatedChild(0, 0),
- cm.isAlphaPremultiplied(), null);
- int [] tmpMap = new int[this.width];
- int idx = 0;
- int sfIdx = 0;
- for (int y = 0; y < this.height; y++) {
- tmpMap = bi.getRGB(0, y, this.width, 1, tmpMap, 0, this.width);
- if (softMask != null) {
- for (int x = 0; x < this.width; x++) {
- int pix = tmpMap[x];
- this.softMask[sfIdx++] = (byte)(pix >>> 24);
- this.bitmaps[idx++] = (byte)((pix >>> 16) & 0xFF);
- this.bitmaps[idx++] = (byte)((pix >>> 8) & 0xFF);
- this.bitmaps[idx++] = (byte)((pix) & 0xFF);
- }
- } else {
- for (int x = 0; x < this.width; x++) {
- int pix = tmpMap[x];
- this.bitmaps[idx++] = (byte)((pix >> 16) & 0xFF);
- this.bitmaps[idx++] = (byte)((pix >> 8) & 0xFF);
- this.bitmaps[idx++] = (byte)((pix) & 0xFF);
- }
+ } catch (Exception ex) {
+ log.error("Error while loading image (Batik): " + ex.getMessage(), ex);
+ } finally {
+ // Make sure we clean up
+ try {
+ seekableInput.close();
+ } catch (IOException ioex) {
+ // ignore
+ }
+ try {
+ inputStream.close();
+ } catch (IOException ioex) {
+ // ignore
}
+ seekableInput = null;
+ inputStream = null;
+ cr = null;
}
- } catch (Exception ex) {
- log.error("Error loading an image" , ex);
- /*throw new FopImageException("Error while loading image "
- + "" + " : "
- + ex.getClass() + " - "
- + ex.getMessage());
- */
}
}
};
diff --git a/src/java/org/apache/fop/image/BmpImage.java b/src/java/org/apache/fop/image/BmpImage.java
index 02346b7e6..3cffc4642 100644
--- a/src/java/org/apache/fop/image/BmpImage.java
+++ b/src/java/org/apache/fop/image/BmpImage.java
@@ -82,14 +82,17 @@ public class BmpImage extends AbstractFopImage {
countr++;
}
}
- } catch (IOException e) {
- log.error("Error while loading image "
- + "" + " : "
- + e.getClass() + " - "
- + e.getMessage(), e);
+ } catch (IOException ex) {
+ log.error("Error while loading image (Bmp): " + ex.getMessage(), ex);
+ try {
+ inputStream.close();
+ } catch (java.io.IOException ioe) {
+ // Ignore
+ }
+ inputStream = null;
return false;
}
- // gets h & w from headermap
+ // gets h & w from headermap
this.width = headermap[wpos]
+ headermap[wpos + 1] * 256
+ headermap[wpos + 2] * 256 * 256
@@ -140,14 +143,16 @@ public class BmpImage extends AbstractFopImage {
temp[count++] = input;
}
}
- inputStream.close();
- inputStream = null;
- } catch (IOException e) {
- log.error("Error while loading image "
- + "" + " : "
- + e.getClass() + " - "
- + e.getMessage(), e);
+ } catch (IOException ex) {
+ log.error("Error while loading image (Bmp): " + ex.getMessage(), ex);
return false;
+ } finally {
+ try {
+ inputStream.close();
+ } catch (java.io.IOException ioe) {
+ // Ignore
+ }
+ inputStream = null;
}
for (int i = 0; i < this.height; i++) {
@@ -159,9 +164,8 @@ public class BmpImage extends AbstractFopImage {
if (this.bitsPerPixel == 24 && x < this.width) {
int countr = 2;
do {
- this.bitmaps[3 * (i * this.width + x) + countr] =
- (byte)(temp[(this.height - i - 1)
- * bytes + j] & 0xFF);
+ this.bitmaps[3 * (i * this.width + x) + countr]
+ = (byte)(temp[(this.height - i - 1) * bytes + j] & 0xFF);
j++;
} while (--countr >= 0)
;
diff --git a/src/java/org/apache/fop/image/GifImage.java b/src/java/org/apache/fop/image/GifImage.java
index 5cb95747c..3cafef559 100644
--- a/src/java/org/apache/fop/image/GifImage.java
+++ b/src/java/org/apache/fop/image/GifImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@ import java.net.URLConnection;
* @see FopImage
*/
public class GifImage extends AbstractFopImage {
+
/**
* Create a new gif image.
*
@@ -52,7 +53,6 @@ public class GifImage extends AbstractFopImage {
* To decode the image a dummy URLConnection is used that
* will do the conversion.
*
- * @param ua the user agent for loading
* @return True if the load process succeeded
*/
protected boolean loadBitmap() {
@@ -83,9 +83,6 @@ public class GifImage extends AbstractFopImage {
return false;
}
- inputStream.close();
- inputStream = null;
-
ColorModel cm = consumer.getColorModel();
this.bitsPerPixel = 8;
// this.bitsPerPixel = cm.getPixelSize();
@@ -143,11 +140,15 @@ public class GifImage extends AbstractFopImage {
this.isTransparent = false;
}
} catch (Exception ex) {
- log.error("Error while loading image "
- + "" + " : "
- + ex.getClass() + " - "
- + ex.getMessage(), ex);
+ log.error("Error while loading image (Gif): " + ex.getMessage(), ex);
return false;
+ } finally {
+ try {
+ inputStream.close();
+ } catch (java.io.IOException ioe) {
+ // Ignore
+ }
+ inputStream = null;
}
// Should take care of the ColorSpace and bitsPerPixel
@@ -159,12 +160,9 @@ public class GifImage extends AbstractFopImage {
int r = (p >> 16) & 0xFF;
int g = (p >> 8) & 0xFF;
int b = (p) & 0xFF;
- this.bitmaps[3 * (i * this.width + j)] =
- (byte)(r & 0xFF);
- this.bitmaps[3 * (i * this.width + j) + 1] =
- (byte)(g & 0xFF);
- this.bitmaps[3 * (i * this.width + j) + 2] =
- (byte)(b & 0xFF);
+ this.bitmaps[3 * (i * this.width + j)] = (byte)(r & 0xFF);
+ this.bitmaps[3 * (i * this.width + j) + 1] = (byte)(g & 0xFF);
+ this.bitmaps[3 * (i * this.width + j) + 2] = (byte)(b & 0xFF);
}
}
return true;
@@ -181,18 +179,30 @@ public class GifImage extends AbstractFopImage {
inputStream = is;
}
+ /**
+ * @see java.net.URLConnection#getInputStream()
+ */
public InputStream getInputStream() throws IOException {
return inputStream;
}
+ /**
+ * @see java.net.URLConnection#connect()
+ */
public void connect() throws IOException {
// do nothing
}
+ /**
+ * @see java.net.URLConnection#getContentType()
+ */
public String getContentType() {
return "image/gif";
}
+ /**
+ * @see java.net.URLConnection#getContentLength()
+ */
public int getContentLength() {
try {
return inputStream.available();
diff --git a/src/java/org/apache/fop/image/ImageFactory.java b/src/java/org/apache/fop/image/ImageFactory.java
index f7323a1a1..a99a4926d 100644
--- a/src/java/org/apache/fop/image/ImageFactory.java
+++ b/src/java/org/apache/fop/image/ImageFactory.java
@@ -63,7 +63,7 @@ public final class ImageFactory {
ImageProvider jaiImage = new ImageProvider("JAIImage", "org.apache.fop.image.JAIImage");
ImageProvider jimiImage = new ImageProvider("JIMIImage", "org.apache.fop.image.JimiImage");
ImageProvider imageIoImage = new ImageProvider(
- "ImageIOImage", "org.apache.fop.image.ImageIoImage");
+ "ImageIOImage", "org.apache.fop.image.ImageIOImage");
ImageProvider gifImage = new ImageProvider("GIFImage", "org.apache.fop.image.GifImage");
ImageProvider jpegImage = new ImageProvider("JPEGImage", "org.apache.fop.image.JpegImage");
ImageProvider bmpImage = new ImageProvider("BMPImage", "org.apache.fop.image.BmpImage");
@@ -104,6 +104,7 @@ public final class ImageFactory {
imt = new ImageMimeType("image/tiff");
imageMimeTypes.put(imt.getMimeType(), imt);
imt.addProvider(tiffImage);
+ imt.addProvider(jaiImage);
imt = new ImageMimeType("image/svg+xml");
imageMimeTypes.put(imt.getMimeType(), imt);
diff --git a/src/java/org/apache/fop/image/JAIImage.java b/src/java/org/apache/fop/image/JAIImage.java
index 636f37a51..8daaa9fc1 100644
--- a/src/java/org/apache/fop/image/JAIImage.java
+++ b/src/java/org/apache/fop/image/JAIImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,26 +39,43 @@ import com.sun.media.jai.codec.FileCacheSeekableStream;
*/
public class JAIImage extends AbstractFopImage {
- public JAIImage(FopImage.ImageInfo imgReader) {
- super(imgReader);
+ /**
+ * Create a new JAI image.
+ *
+ * @param imgInfo the image info for this JAI image
+ */
+ public JAIImage(FopImage.ImageInfo imgInfo) {
+ super(imgInfo);
}
+ /**
+ * @see org.apache.fop.image.AbstractFopImage#loadDimensions()
+ */
+ protected boolean loadDimensions() {
+ if (this.bitmaps == null) {
+ loadImage();
+ }
+ return this.bitmaps != null;
+ }
+
+ /**
+ * Loads the image from the inputstream
+ */
protected void loadImage() {
+ com.sun.media.jai.codec.FileCacheSeekableStream seekableInput = null;
try {
- com.sun.media.jai.codec.FileCacheSeekableStream seekableInput =
- new FileCacheSeekableStream(inputStream);
+ seekableInput = new FileCacheSeekableStream(inputStream);
RenderedOp imageOp = JAI.create("stream", seekableInput);
- inputStream.close();
- inputStream = null;
this.height = imageOp.getHeight();
this.width = imageOp.getWidth();
ColorModel cm = imageOp.getColorModel();
- this.bitsPerPixel = 8;
- // this.bitsPerPixel = cm.getPixelSize();
- this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
-
+ //this.bitsPerPixel = 8;
+ this.bitsPerPixel = cm.getPixelSize();
+ //this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
+ this.colorSpace = cm.getColorSpace();
+
BufferedImage imageData = imageOp.getAsBufferedImage();
int[] tmpMap = imageData.getRGB(0, 0, this.width,
this.height, null, 0, this.width);
@@ -128,21 +145,29 @@ public class JAIImage extends AbstractFopImage {
int r = (p >> 16) & 0xFF;
int g = (p >> 8) & 0xFF;
int b = (p) & 0xFF;
- this.bitmaps[3 * (i * this.width + j)] =
- (byte)(r & 0xFF);
- this.bitmaps[3 * (i * this.width + j) + 1] =
- (byte)(g & 0xFF);
- this.bitmaps[3 * (i * this.width + j) + 2] =
- (byte)(b & 0xFF);
+ this.bitmaps[3 * (i * this.width + j)] = (byte)(r & 0xFF);
+ this.bitmaps[3 * (i * this.width + j) + 1] = (byte)(g & 0xFF);
+ this.bitmaps[3 * (i * this.width + j) + 2] = (byte)(b & 0xFF);
}
}
} catch (Exception ex) {
- /*throw new FopImageException("Error while loading image "
- + "" + " : "
- + ex.getClass() + " - "
- + ex.getMessage());
- */}
+ log.error("Error while loading image (JAI): " + ex.getMessage(), ex);
+ } finally {
+ try {
+ inputStream.close();
+ } catch (java.io.IOException ioe) {
+ // Ignore
+ }
+ inputStream = null;
+ if (seekableInput != null) {
+ try {
+ seekableInput.close();
+ } catch (java.io.IOException ioe) {
+ // Ignore
+ }
+ }
+ }
}
}
diff --git a/src/java/org/apache/fop/image/JimiImage.java b/src/java/org/apache/fop/image/JimiImage.java
index 9688fbf01..e10024bea 100644
--- a/src/java/org/apache/fop/image/JimiImage.java
+++ b/src/java/org/apache/fop/image/JimiImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,15 +37,18 @@ import com.sun.jimi.core.Jimi;
*/
public class JimiImage extends AbstractFopImage {
- public JimiImage(FopImage.ImageInfo imgReader) {
- super(imgReader);
- try {
- Class c = Class.forName("com.sun.jimi.core.Jimi");
- } catch (ClassNotFoundException e) {
- //throw new FopImageException("Jimi image library not available");
- }
+ /**
+ * Create a new Jimi image.
+ *
+ * @param imgInfo the image info for this Jimi image
+ */
+ public JimiImage(FopImage.ImageInfo imgInfo) {
+ super(imgInfo);
}
+ /**
+ * @see org.apache.fop.image.AbstractFopImage#loadDimensions()
+ */
protected boolean loadDimensions() {
if (this.bitmaps == null) {
loadImage();
@@ -65,6 +68,9 @@ public class JimiImage extends AbstractFopImage {
return this.bitmaps != null;
}
+ /**
+ * Loads the image from the inputstream
+ */
protected void loadImage() {
int[] tmpMap = null;
try {
@@ -80,9 +86,6 @@ public class JimiImage extends AbstractFopImage {
this.height = consumer.getHeight();
this.width = consumer.getWidth();
- inputStream.close();
- inputStream = null;
-
try {
tmpMap = consumer.getImage();
} catch (Exception ex) {
@@ -149,9 +152,15 @@ public class JimiImage extends AbstractFopImage {
this.isTransparent = false;
}
} catch (Throwable ex) {
- log.error("Error while loading image "
- + "", ex);
+ log.error("Error while loading image (Jimi): " + ex.getMessage(), ex);
return;
+ } finally {
+ try {
+ inputStream.close();
+ } catch (java.io.IOException ioe) {
+ // Ignore
+ }
+ inputStream = null;
}
@@ -164,12 +173,9 @@ public class JimiImage extends AbstractFopImage {
int r = (p >> 16) & 0xFF;
int g = (p >> 8) & 0xFF;
int b = (p) & 0xFF;
- this.bitmaps[3 * (i * this.width + j)] =
- (byte)(r & 0xFF);
- this.bitmaps[3 * (i * this.width + j) + 1] =
- (byte)(g & 0xFF);
- this.bitmaps[3 * (i * this.width + j) + 2] =
- (byte)(b & 0xFF);
+ this.bitmaps[3 * (i * this.width + j)] = (byte)(r & 0xFF);
+ this.bitmaps[3 * (i * this.width + j) + 1] = (byte)(g & 0xFF);
+ this.bitmaps[3 * (i * this.width + j) + 2] = (byte)(b & 0xFF);
}
}
}
diff --git a/src/java/org/apache/fop/image/JpegImage.java b/src/java/org/apache/fop/image/JpegImage.java
index a32e1f215..b3c8cb0bd 100644
--- a/src/java/org/apache/fop/image/JpegImage.java
+++ b/src/java/org/apache/fop/image/JpegImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -65,13 +65,16 @@ public class JpegImage extends AbstractFopImage {
while ((bytesRead = inputStream.read(readBuf)) != -1) {
baos.write(readBuf, 0, bytesRead);
}
- inputStream.close();
- inputStream = null;
} catch (java.io.IOException ex) {
- log.error("Error while loading image "
- + " : " + ex.getClass()
- + " - " + ex.getMessage(), ex);
+ log.error("Error while loading image (Jpeg): " + ex.getMessage(), ex);
return false;
+ } finally {
+ try {
+ inputStream.close();
+ } catch (java.io.IOException ioe) {
+ // Ignore
+ }
+ inputStream = null;
}
this.bitmaps = baos.toByteArray();
@@ -163,10 +166,8 @@ public class JpegImage extends AbstractFopImage {
byte[] align = new byte[((iccStream.size()) % 8) + 8];
try {
iccStream.write(align);
- } catch (Exception e) {
- log.error("Error while loading image "
- + " : "
- + e.getMessage(), e);
+ } catch (Exception ex) {
+ log.error("Error while aligning ICC stream: " + ex.getMessage(), ex);
return false;
}
try {
diff --git a/src/java/org/apache/fop/image/PNGImage.java b/src/java/org/apache/fop/image/PNGImage.java
index 4fd2e4acf..6235b9720 100644
--- a/src/java/org/apache/fop/image/PNGImage.java
+++ b/src/java/org/apache/fop/image/PNGImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2004 The Apache Software Foundation
+ * Copyright 2004-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/java/org/apache/fop/image/TIFFImage.java b/src/java/org/apache/fop/image/TIFFImage.java
index 9dc9b9c95..0f959c6f2 100644
--- a/src/java/org/apache/fop/image/TIFFImage.java
+++ b/src/java/org/apache/fop/image/TIFFImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2004 The Apache Software Foundation
+ * Copyright 2004-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
package org.apache.fop.image;
+import java.awt.color.ColorSpace;
import java.io.IOException;
import org.apache.batik.ext.awt.image.codec.SeekableStream;
@@ -31,6 +32,11 @@ import org.apache.batik.ext.awt.image.rendered.CachableRed;
*/
public class TIFFImage extends BatikImage {
+ private int compression = 0;
+ private int stripCount = 0;
+ private long stripOffset = 0;
+ private long stripLength = 0;
+
/**
* Constructs a new BatikImage instance.
* @param imgReader basic metadata for the image
@@ -40,6 +46,22 @@ public class TIFFImage extends BatikImage {
}
/**
+ * The compression type set in the TIFF directory
+ * @return the TIFF compression type
+ */
+ public int getCompression() {
+ return compression;
+ }
+
+ /**
+ * The number of strips in the image
+ * @return the number of strips in the image
+ */
+ public int getStripCount() {
+ return stripCount;
+ }
+
+ /**
* @see org.apache.fop.image.BatikImage#decodeImage(org.apache.batik.ext.awt.image.codec.SeekableStream)
*/
protected CachableRed decodeImage(SeekableStream stream) throws IOException {
@@ -67,7 +89,73 @@ public class TIFFImage extends BatikImage {
log.warn("Cannot determine bitmap resolution."
+ " Unimplemented resolution unit: " + resUnit);
}
+ fld = dir.getField(TIFFImageDecoder.TIFF_COMPRESSION);
+ if (fld != null) {
+ compression = fld.getAsInt(0);
+ }
+ fld = dir.getField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE);
+ if (fld != null) {
+ bitsPerPixel = fld.getAsInt(0);
+ }
+ fld = dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP);
+ if (fld == null) {
+ stripCount = 1;
+ } else {
+ stripCount = (int)(dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH)
+ / fld.getAsLong(0));
+ }
+ stripOffset = dir.getField(TIFFImageDecoder.TIFF_STRIP_OFFSETS).getAsLong(0);
+ stripLength = dir.getField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS).getAsLong(0);
+
+ if (this.bitsPerPixel == 1) {
+ this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
+ }
return img;
}
-
+
+ /**
+ * Load the original TIFF data.
+ * This loads only strip 1 of the original TIFF data.
+ *
+ * @return true if loaded false for any error
+ * @see org.apache.fop.image.AbstractFopImage#loadOriginalData()
+ */
+ protected boolean loadOriginalData() {
+ if (loadDimensions()) {
+ byte[] readBuf = new byte[(int)stripLength];
+ int bytesRead;
+
+ try {
+ this.seekableInput.reset();
+ this.seekableInput.skip(stripOffset);
+ bytesRead = seekableInput.read(readBuf);
+ if (bytesRead != stripLength) {
+ log.error("Error while loading image: length mismatch on read");
+ return false;
+ }
+
+ this.bitmaps = readBuf;
+ return true;
+ } catch (IOException ioe) {
+ log.error("Error while loading image strip 1 (TIFF): ", ioe);
+ return false;
+ } finally {
+ try {
+ this.seekableInput.close();
+ } catch (IOException ioex) {
+ // ignore
+ }
+ try {
+ this.inputStream.close();
+ } catch (IOException ioex) {
+ // ignore
+ }
+ this.seekableInput = null;
+ this.inputStream = null;
+ this.cr = null;
+ }
+ }
+ return false;
+ }
+
}
diff --git a/src/java/org/apache/fop/pdf/BitmapImage.java b/src/java/org/apache/fop/pdf/BitmapImage.java
index 5d1451929..6c8f61e5c 100644
--- a/src/java/org/apache/fop/pdf/BitmapImage.java
+++ b/src/java/org/apache/fop/pdf/BitmapImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -196,19 +196,19 @@ public class BitmapImage implements PDFImage {
}
/**
- * @see org.apache.fop.pdf.PDFImage#isDCT()
- */
- public boolean isDCT() {
- return false;
- }
-
- /**
* @see org.apache.fop.pdf.PDFImage#getFilterHint()
*/
public String getFilterHint() {
return PDFFilterList.IMAGE_FILTER;
}
+ /**
+ * @see org.apache.fop.pdf.PDFImage#getPDFFilter()
+ */
+ public PDFFilter getPDFFilter() {
+ return null;
+ }
+
}
diff --git a/src/java/org/apache/fop/pdf/CCFFilter.java b/src/java/org/apache/fop/pdf/CCFFilter.java
new file mode 100644
index 000000000..ed8960ca0
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/CCFFilter.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.pdf;
+
+/**
+ * CCF Filter class. Right now it is just used as a dummy filter flag so
+ * we can write TIFF images to the PDF. The encode method just returns the
+ * data passed to it. In the future an actual CCITT Group 4 compression should be
+ * added to the encode method so other images can be compressed.
+ *
+ */
+public class CCFFilter extends NullFilter {
+
+ private String decodeParms;
+
+ /**
+ * @see org.apache.fop.pdf.PDFFilter#getName()
+ */
+ public String getName() {
+ return "/CCITTFaxDecode";
+ }
+
+ /**
+ * @see org.apache.fop.pdf.PDFFilter#getDecodeParms()
+ */
+ public String getDecodeParms() {
+ return this.decodeParms;
+ }
+
+ /**
+ * Sets the CCF decoding parameters
+ * @param decodeParms The decoding parameters
+ */
+ public void setDecodeParms(String decodeParms) {
+ this.decodeParms = decodeParms;
+ }
+
+}
+
diff --git a/src/java/org/apache/fop/pdf/PDFFilterList.java b/src/java/org/apache/fop/pdf/PDFFilterList.java
index 499bafc06..4554ea6c6 100644
--- a/src/java/org/apache/fop/pdf/PDFFilterList.java
+++ b/src/java/org/apache/fop/pdf/PDFFilterList.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,6 +45,8 @@ public class PDFFilterList {
public static final String IMAGE_FILTER = "image";
/** Key for the filter used for JPEG images */
public static final String JPEG_FILTER = "jpeg";
+ /** Key for the filter used for TIFF images */
+ public static final String TIFF_FILTER = "tiff";
/** Key for the filter used for fonts */
public static final String FONT_FILTER = "font";
@@ -131,15 +133,16 @@ public class PDFFilterList {
}
/**
- * Checks the filter list for the DCT filter and adds it in the correct
+ * Checks the filter list for the filter and adds it in the correct
* place if necessary.
+ * @param pdfFilter the filter to check / add
*/
- public void ensureDCTFilterInPlace() {
+ public void ensureFilterInPlace(PDFFilter pdfFilter) {
if (this.filters.size() == 0) {
- addFilter(new DCTFilter());
+ addFilter(pdfFilter);
} else {
- if (!(this.filters.get(0) instanceof DCTFilter)) {
- this.filters.add(0, new DCTFilter());
+ if (!(this.filters.get(0).equals(pdfFilter))) {
+ this.filters.add(0, pdfFilter);
}
}
}
@@ -186,7 +189,9 @@ public class PDFFilterList {
PDFFilter filter = (PDFFilter)filters.get(count);
// place the names in our local vector in reverse order
names.add(0, filter.getName());
- parms.add(0, filter.getDecodeParms());
+ if (filter.getDecodeParms() != null) {
+ parms.add(0, filter.getDecodeParms());
+ }
}
// now build up the filter entries for the dictionary
@@ -197,20 +202,22 @@ public class PDFFilterList {
}
private String buildFilterEntries(List names) {
- boolean needFilterEntry = false;
+ int filterCount = 0;
StringBuffer sb = new StringBuffer(64);
- sb.append("/Filter [ ");
for (int i = 0; i < names.size(); i++) {
final String name = (String)names.get(i);
if (name.length() > 0) {
- needFilterEntry = true;
+ filterCount++;
sb.append(name);
sb.append(" ");
}
}
- if (needFilterEntry) {
- sb.append("]");
- return sb.toString();
+ if (filterCount > 0) {
+ if (filterCount > 1) {
+ return "/Filter [ " + sb.toString() + "]";
+ } else {
+ return "/Filter " + sb.toString();
+ }
} else {
return "";
}
@@ -219,7 +226,7 @@ public class PDFFilterList {
private String buildDecodeParms(List parms) {
StringBuffer sb = new StringBuffer();
boolean needParmsEntry = false;
- sb.append("/DecodeParms ");
+ sb.append("\n/DecodeParms ");
if (parms.size() > 1) {
sb.append("[ ");
diff --git a/src/java/org/apache/fop/pdf/PDFImage.java b/src/java/org/apache/fop/pdf/PDFImage.java
index 236426682..8be9c28a1 100644
--- a/src/java/org/apache/fop/pdf/PDFImage.java
+++ b/src/java/org/apache/fop/pdf/PDFImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -82,13 +82,6 @@ public interface PDFImage {
boolean isPS();
/**
- * Check if this image is a DCT encoded image (for JPEG images).
- *
- * @return true if this is a DCT image
- */
- boolean isDCT();
-
- /**
* Check if this image has a transparent color transparency.
*
* @return true if it has transparency
@@ -116,6 +109,13 @@ public interface PDFImage {
*/
String getSoftMask();
+ /**
+ * Get the PDF Filter to be applied to the image.
+ *
+ * @return the PDF Filter or null
+ */
+ PDFFilter getPDFFilter();
+
// get the image bytes, and bytes properties
/**
diff --git a/src/java/org/apache/fop/pdf/PDFXObject.java b/src/java/org/apache/fop/pdf/PDFXObject.java
index 34c73cdaf..4d6e7f380 100644
--- a/src/java/org/apache/fop/pdf/PDFXObject.java
+++ b/src/java/org/apache/fop/pdf/PDFXObject.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -174,8 +174,9 @@ public class PDFXObject extends AbstractPDFStream {
* @see org.apache.fop.pdf.AbstractPDFStream#prepareImplicitFilters()
*/
protected void prepareImplicitFilters() {
- if (pdfimage.isDCT()) {
- getFilterList().ensureDCTFilterInPlace();
+ PDFFilter pdfFilter = pdfimage.getPDFFilter();
+ if (pdfFilter != null) {
+ getFilterList().ensureFilterInPlace(pdfFilter);
}
}
diff --git a/src/java/org/apache/fop/render/pdf/FopPDFImage.java b/src/java/org/apache/fop/render/pdf/FopPDFImage.java
index 3a80bf2de..e38c9f111 100644
--- a/src/java/org/apache/fop/render/pdf/FopPDFImage.java
+++ b/src/java/org/apache/fop/render/pdf/FopPDFImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
/* $Id$ */
package org.apache.fop.render.pdf;
-
import org.apache.fop.pdf.PDFFilterList;
import org.apache.fop.pdf.PDFImage;
import org.apache.fop.pdf.PDFFilter;
@@ -32,11 +31,13 @@ import org.apache.fop.pdf.BitmapImage;
import org.apache.fop.image.FopImage;
import org.apache.fop.image.JpegImage;
import org.apache.fop.image.EPSImage;
+import org.apache.fop.image.TIFFImage;
import java.io.IOException;
import java.io.OutputStream;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
+import org.apache.fop.pdf.CCFFilter;
/**
* PDFImage implementation for the PDF renderer.
@@ -49,6 +50,8 @@ public class FopPDFImage implements PDFImage {
private String maskRef;
private String softMaskRef;
private boolean isPS = false;
+ private boolean isCCF = false;
+ private boolean isDCT = false;
private String key;
/**
@@ -77,6 +80,7 @@ public class FopPDFImage implements PDFImage {
if ("image/jpeg".equals(fopImage.getMimeType())) {
pdfFilter = new DCTFilter();
pdfFilter.setApplied(true);
+ isDCT = true;
JpegImage jpegimage = (JpegImage) fopImage;
ICC_Profile prof = jpegimage.getICCProfile();
@@ -85,8 +89,35 @@ public class FopPDFImage implements PDFImage {
pdfICCStream = doc.getFactory().makePDFICCStream();
pdfICCStream.setColorSpace(prof, pdfCS);
}
+ } else if ("image/tiff".equals(fopImage.getMimeType())
+ && fopImage instanceof TIFFImage) {
+ TIFFImage tiffImage = (TIFFImage) fopImage;
+ if (tiffImage.getStripCount() == 1) {
+ int comp = tiffImage.getCompression();
+ if (comp == 1) {
+ // Nothing to do
+ } else if (comp == 3) {
+ pdfFilter = new CCFFilter();
+ pdfFilter.setApplied(true);
+ isCCF = true;
+ } else if (comp == 4) {
+ pdfFilter = new CCFFilter();
+ pdfFilter.setApplied(true);
+ ((CCFFilter)pdfFilter).setDecodeParms("<< /K -1 /Columns "
+ + tiffImage.getWidth() + " >>");
+ isCCF = true;
+ } else if (comp == 6) {
+ pdfFilter = new DCTFilter();
+ pdfFilter.setApplied(true);
+ isDCT = true;
+ }
+ }
+ }
+ if (isPS || isDCT || isCCF) {
+ fopImage.load(FopImage.ORIGINAL_DATA);
+ } else {
+ fopImage.load(FopImage.BITMAP);
}
-
//Handle transparency mask if applicable
if (fopImage.hasSoftMask()) {
byte [] softMask = fopImage.getSoftMask();
@@ -103,20 +134,6 @@ public class FopPDFImage implements PDFImage {
}
/**
- * @see org.apache.fop.pdf.PDFImage#isPS()
- */
- public boolean isPS() {
- return isPS;
- }
-
- /**
- * @see org.apache.fop.pdf.PDFImage#isDCT()
- */
- public boolean isDCT() {
- return fopImage.getMimeType().equals("image/jpeg");
- }
-
- /**
* @see org.apache.fop.pdf.PDFImage#getWidth()
*/
public int getWidth() {
@@ -176,6 +193,20 @@ public class FopPDFImage implements PDFImage {
}
/**
+ * @see org.apache.fop.pdf.PDFImage#isPS()
+ */
+ public boolean isPS() {
+ return isPS;
+ }
+
+ /**
+ * @see org.apache.fop.pdf.PDFImage#getPDFFilter()
+ */
+ public PDFFilter getPDFFilter() {
+ return pdfFilter;
+ }
+
+ /**
* @see org.apache.fop.pdf.PDFImage#outputContents(OutputStream)
*/
public void outputContents(OutputStream out) throws IOException {
@@ -268,10 +299,12 @@ public class FopPDFImage implements PDFImage {
* @see org.apache.fop.pdf.PDFImage#getFilterHint()
*/
public String getFilterHint() {
- if (isPS()) {
+ if (isPS) {
return PDFFilterList.CONTENT_FILTER;
- } else if (fopImage.getMimeType().equals("image/jpeg")) {
+ } else if (isDCT) {
return PDFFilterList.JPEG_FILTER;
+ } else if (isCCF) {
+ return PDFFilterList.TIFF_FILTER;
} else {
return PDFFilterList.IMAGE_FILTER;
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
index c8b188242..22e32d7dd 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/* $Id: PDFRenderer.java,v 1.38 2004/04/07 14:24:17 cbowditch Exp $ */
+/* $Id$ */
package org.apache.fop.render.pdf;
@@ -161,6 +161,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
*/
protected PDFPage currentPage;
+ /** The current Transform */
protected AffineTransform currentBasicTransform;
/** drawing state */
@@ -615,9 +616,11 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
setColor(uppercol, false, null);
currentStream.add(x1 + " " + ym1 + " m " + x2 + " " + ym1 + " l S\n");
setColor(c, false, null);
- currentStream.add(x1 + " " + (ym1 + h3) + " m " + x2 + " " + (ym1 + h3) + " l S\n");
+ currentStream.add(x1 + " " + (ym1 + h3) + " m "
+ + x2 + " " + (ym1 + h3) + " l S\n");
setColor(lowercol, false, null);
- currentStream.add(x1 + " " + (ym1 + h3 + h3) + " m " + x2 + " " + (ym1 + h3 + h3) + " l S\n");
+ currentStream.add(x1 + " " + (ym1 + h3 + h3) + " m "
+ + x2 + " " + (ym1 + h3 + h3) + " l S\n");
} else {
Color leftcol = lightenColor(c, -colFactor);
Color rightcol = lightenColor(c, colFactor);
@@ -627,9 +630,11 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
setColor(leftcol, false, null);
currentStream.add(xm1 + " " + y1 + " m " + xm1 + " " + y2 + " l S\n");
setColor(c, false, null);
- currentStream.add((xm1 + w3) + " " + y1 + " m " + (xm1 + w3) + " " + y2 + " l S\n");
+ currentStream.add((xm1 + w3) + " " + y1 + " m "
+ + (xm1 + w3) + " " + y2 + " l S\n");
setColor(rightcol, false, null);
- currentStream.add((xm1 + w3 + w3) + " " + y1 + " m " + (xm1 + w3 + w3) + " " + y2 + " l S\n");
+ currentStream.add((xm1 + w3 + w3) + " " + y1 + " m "
+ + (xm1 + w3 + w3) + " " + y2 + " l S\n");
}
break;
}
@@ -1398,16 +1403,10 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
renderDocument(doc, ns, pos);
} else if ("image/eps".equals(mime)) {
- if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
- return;
- }
FopPDFImage pdfimage = new FopPDFImage(fopimage, url);
int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber();
fact.releaseImage(url, userAgent);
- } else if ("image/jpeg".equals(mime)) {
- if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
- return;
- }
+ } else if ("image/jpeg".equals(mime) || "image/tiff".equals(mime)) {
FopPDFImage pdfimage = new FopPDFImage(fopimage, url);
int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber();
fact.releaseImage(url, userAgent);
@@ -1417,9 +1416,6 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
placeImage((float) pos.getX() / 1000,
(float) pos.getY() / 1000, w, h, xobj);
} else {
- if (!fopimage.load(FopImage.BITMAP)) {
- return;
- }
FopPDFImage pdfimage = new FopPDFImage(fopimage, url);
int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber();
fact.releaseImage(url, userAgent);
diff --git a/test/layoutengine/testcases/external-graphic-tiff.xml b/test/layoutengine/testcases/external-graphic-tiff.xml
index 1d93a5d19..1b38504b0 100644
--- a/test/layoutengine/testcases/external-graphic-tiff.xml
+++ b/test/layoutengine/testcases/external-graphic-tiff.xml
@@ -24,7 +24,7 @@
<fo>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
<fo:layout-master-set>
- <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+ <fo:simple-page-master master-name="normal" page-width="8in" page-height="8in">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
@@ -38,6 +38,10 @@
<fo:block>
<fo:external-graphic src="../../resources/images/bgimg72dpi.tif"/>EOG
</fo:block>
+ <fo:block>TIFF external-graphic (CCITT group 4 encoding)</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/tiff_group4.tif"/>EOG
+ </fo:block>
<fo:block>EOF</fo:block>
</fo:flow>
</fo:page-sequence>
@@ -52,5 +56,9 @@
<eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@ipda"/>
<eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@bpd"/>
<eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@bpda"/>
+ <eval expected="550588" xpath="//flow/block[6]/lineArea/viewport/@ipd"/>
+ <eval expected="550588" xpath="//flow/block[6]/lineArea/viewport/@ipda"/>
+ <eval expected="66705" xpath="//flow/block[6]/lineArea/viewport/@bpd"/>
+ <eval expected="66705" xpath="//flow/block[6]/lineArea/viewport/@bpda"/>
</checks>
</testcase>
diff --git a/test/resources/images/tiff_group4.tif b/test/resources/images/tiff_group4.tif
new file mode 100644
index 000000000..5720e8f0c
--- /dev/null
+++ b/test/resources/images/tiff_group4.tif
Binary files differ