aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2005-08-21 16:44:00 +0000
committerJeremias Maerki <jeremias@apache.org>2005-08-21 16:44:00 +0000
commitb5fe4766be47aa3394b7d8d98422c983b246a73c (patch)
treec6643113fd815d1566ea9db6e9354f4ce27b5597
parentf5b4eeff769eafa0f2020d4766d25afc675f6142 (diff)
downloadxmlgraphics-fop-b5fe4766be47aa3394b7d8d98422c983b246a73c.tar.gz
xmlgraphics-fop-b5fe4766be47aa3394b7d8d98422c983b246a73c.zip
Bugzilla #36224:
This patch ports the 0.20.5 CCITTFaxDecode filter functionality and its support of direct embedding on certain TIFF images to the trunk. It also cleans up some of the image handling with respect to consistent closing of the input stream to avoid dangling open files. Submitted by: Manuel Mall <mm.at.arcus.com.au> Changes to the patch: Fixed a small problem with the NullFilter in the PDF library. Used tiff_group4.tiff in external-graphic-tiff.xml. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@234261 13f79535-47bb-0310-9956-ffa450edef68
-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