aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2009-10-23 13:33:18 +0000
committerJeremias Maerki <jeremias@apache.org>2009-10-23 13:33:18 +0000
commit6eb07eba36213cbe885295785041033124ec257d (patch)
treec8db430deca1dda8a38fee5b41b156be50188113
parent9c7a867efc15bd1bf181bd747ae4567598ba14d0 (diff)
downloadxmlgraphics-fop-6eb07eba36213cbe885295785041033124ec257d.tar.gz
xmlgraphics-fop-6eb07eba36213cbe885295785041033124ec257d.zip
Added support for encoding CMYK bitmap images (IOCA FS45) and TIFF images as embedded objects.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@829057 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/fop/afp/AFPDataObjectFactory.java34
-rw-r--r--src/java/org/apache/fop/afp/AFPPaintingState.java23
-rw-r--r--src/java/org/apache/fop/afp/ioca/IDEStructureParameter.java151
-rw-r--r--src/java/org/apache/fop/afp/ioca/ImageContent.java104
-rw-r--r--src/java/org/apache/fop/afp/ioca/ImageSegment.java10
-rw-r--r--src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java2
-rw-r--r--src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java1
-rw-r--r--src/java/org/apache/fop/afp/modca/ImageObject.java13
-rw-r--r--src/java/org/apache/fop/render/afp/AFPCustomizable.java8
-rw-r--r--src/java/org/apache/fop/render/afp/AFPDocumentHandler.java5
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java9
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java34
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRenderer.java8
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java3
-rw-r--r--status.xml3
15 files changed, 330 insertions, 78 deletions
diff --git a/src/java/org/apache/fop/afp/AFPDataObjectFactory.java b/src/java/org/apache/fop/afp/AFPDataObjectFactory.java
index f6de7b5b4..792909b9e 100644
--- a/src/java/org/apache/fop/afp/AFPDataObjectFactory.java
+++ b/src/java/org/apache/fop/afp/AFPDataObjectFactory.java
@@ -24,6 +24,7 @@ import java.awt.geom.Rectangle2D;
import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
+import org.apache.fop.afp.ioca.IDEStructureParameter;
import org.apache.fop.afp.ioca.ImageContent;
import org.apache.fop.afp.modca.AbstractDataObject;
import org.apache.fop.afp.modca.AbstractNamedAFPObject;
@@ -113,12 +114,35 @@ public class AFPDataObjectFactory {
}
}
- if (imageObjectInfo.isColor()) {
- imageObj.setIDESize((byte) 24);
- } else {
- imageObj.setIDESize((byte) imageObjectInfo.getBitsPerPixel());
+ ImageContent content = imageObj.getImageSegment().getImageContent();
+ int bitsPerPixel = imageObjectInfo.getBitsPerPixel();
+ imageObj.setIDESize((byte) bitsPerPixel);
+ IDEStructureParameter ideStruct;
+ switch (bitsPerPixel) {
+ case 1:
+ //Skip IDE Structure Parameter
+ break;
+ case 4:
+ case 8:
+ ideStruct = content.needIDEStructureParameter();
+ ideStruct.setBitsPerComponent(new int[] {bitsPerPixel});
+ break;
+ case 24:
+ ideStruct = content.needIDEStructureParameter();
+ ideStruct.setDefaultRGBColorModel();
+ break;
+ case 32:
+ ideStruct = content.needIDEStructureParameter();
+ ideStruct.setDefaultCMYKColorModel();
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported number of bits per pixel: "
+ + bitsPerPixel);
+ }
+ if (imageObjectInfo.isSubtractive()) {
+ ideStruct = content.needIDEStructureParameter();
+ ideStruct.setSubtractive(imageObjectInfo.isSubtractive());
}
- imageObj.setSubtractive(imageObjectInfo.isSubtractive());
imageObj.setData(imageObjectInfo.getData());
diff --git a/src/java/org/apache/fop/afp/AFPPaintingState.java b/src/java/org/apache/fop/afp/AFPPaintingState.java
index 578924d67..643dcb702 100644
--- a/src/java/org/apache/fop/afp/AFPPaintingState.java
+++ b/src/java/org/apache/fop/afp/AFPPaintingState.java
@@ -46,8 +46,10 @@ implements Cloneable {
/** color image support */
private boolean colorImages = false;
- /** images are supported in this AFP environment */
+ /** true if certain image formats may be embedded unchanged in their native format. */
private boolean nativeImagesSupported = false;
+ /** true if CMYK images (requires IOCA FS45 suppport on the target platform) may be generated */
+ private boolean cmykImagesSupported;
/** default value for image depth */
private int bitsPerPixel = 8;
@@ -64,6 +66,7 @@ implements Cloneable {
/** a unit converter */
private final transient AFPUnitConverter unitConv = new AFPUnitConverter(this);
+
/**
* Sets the rotation to be used for portrait pages, valid values are 0
* (default), 90, 180, 270.
@@ -186,6 +189,24 @@ implements Cloneable {
}
/**
+ * Controls whether CMYK images (IOCA FS45) are enabled. By default, support is disabled
+ * for wider compatibility. When disabled, any CMYK image is converted to the selected
+ * color format.
+ * @param value true to enabled CMYK images
+ */
+ public void setCMYKImagesSupported(boolean value) {
+ this.cmykImagesSupported = value;
+ }
+
+ /**
+ * Indicates whether CMYK images (IOCA FS45) are enabled.
+ * @return true if IOCA FS45 is enabled
+ */
+ public boolean isCMYKImagesSupported() {
+ return this.cmykImagesSupported;
+ }
+
+ /**
* Sets the output/device resolution
*
* @param resolution
diff --git a/src/java/org/apache/fop/afp/ioca/IDEStructureParameter.java b/src/java/org/apache/fop/afp/ioca/IDEStructureParameter.java
new file mode 100644
index 000000000..8c0d0d49a
--- /dev/null
+++ b/src/java/org/apache/fop/afp/ioca/IDEStructureParameter.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp.ioca;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.fop.afp.Streamable;
+
+/**
+ * This class represents the IOCA IDE Structure parameter (X'9B').
+ */
+public class IDEStructureParameter implements Streamable {
+
+ /** The RGB color model used by the IDE Structure parameter */
+ public static final byte COLOR_MODEL_RGB = (byte)0x01;
+ /** The YCrCb color model used by the IDE Structure parameter */
+ public static final byte COLOR_MODEL_YCRCB = (byte)0x02;
+ /** The CMYK color model used by the IDE Structure parameter */
+ public static final byte COLOR_MODEL_CMYK = (byte)0x04;
+ /** The YCbCr color model used by the IDE Structure parameter */
+ public static final byte COLOR_MODEL_YCBCR = (byte)0x12;
+
+ /** additive/subtractive setting for ASFLAG */
+ private boolean subtractive = false;
+
+ /** setting for GRAYCODE flag */
+ private boolean grayCoding = false;
+
+ /** the image color model */
+ private byte colorModel = COLOR_MODEL_RGB;
+
+ /** the array with the number of bits/IDE for each component */
+ private byte[] bitsPerIDE = new byte[] {(byte)1}; //1-bit by default
+
+ /**
+ * Creates a new IDE Structure parameter. The values are initialized for a bi-level image
+ * using the RGB color model.
+ */
+ public IDEStructureParameter() {
+ //nop
+ }
+
+ /**
+ * Sets the image IDE color model.
+ *
+ * @param color the IDE color model.
+ */
+ public void setColorModel(byte color) {
+ this.colorModel = color;
+ }
+
+ /**
+ * Establishes the parameter values for the normal RGB 24bit color model.
+ */
+ public void setDefaultRGBColorModel() {
+ this.colorModel = COLOR_MODEL_RGB;
+ setUniformBitsPerComponent(3, 8);
+ }
+
+ /**
+ * Establishes the parameter values for the normal CMYK 32bit color model.
+ */
+ public void setDefaultCMYKColorModel() {
+ this.colorModel = COLOR_MODEL_CMYK;
+ setUniformBitsPerComponent(4, 8);
+ }
+
+ /**
+ * Sets
+ * @param numComponents
+ * @param bitsPerComponent
+ */
+ public void setUniformBitsPerComponent(int numComponents, int bitsPerComponent) {
+ if (bitsPerComponent < 0 || bitsPerComponent >= 256) {
+ throw new IllegalArgumentException(
+ "The number of bits per component must be between 0 and 255");
+ }
+ this.bitsPerIDE = new byte[numComponents];
+ for (int i = 0; i < numComponents; i++) {
+ this.bitsPerIDE[i] = (byte)bitsPerComponent;
+ }
+ }
+
+ /**
+ * Sets the array for the bits/IDE, one entry per component.
+ * @param bitsPerComponent the
+ */
+ public void setBitsPerComponent(int[] bitsPerComponent) {
+ int numComponents = bitsPerComponent.length;
+ this.bitsPerIDE = new byte[numComponents];
+ for (int i = 0; i < numComponents; i++) {
+ int bits = bitsPerComponent[i];
+ if (bits < 0 || bits >= 256) {
+ throw new IllegalArgumentException(
+ "The number of bits per component must be between 0 and 255");
+ }
+ this.bitsPerIDE[i] = (byte)bits;
+ }
+ }
+
+ /**
+ * Set either additive or subtractive mode (used for ASFLAG).
+ * @param subtractive true for subtractive mode, false for additive mode
+ */
+ public void setSubtractive(boolean subtractive) {
+ this.subtractive = subtractive;
+ }
+
+ /** {@inheritDoc} */
+ public void writeToStream(OutputStream os) throws IOException {
+ int length = 7 + bitsPerIDE.length;
+
+ byte flags = 0x00;
+ if (subtractive) {
+ flags |= 1 << 7;
+ }
+ if (grayCoding) {
+ flags |= 1 << 6;
+ }
+
+ DataOutputStream dout = new DataOutputStream(os);
+ dout.writeByte(0x9B); //ID
+ dout.writeByte(length - 2); //LENGTH
+ dout.writeByte(flags); //FLAGS
+ dout.writeByte(this.colorModel); //FORMAT
+ for (int i = 0; i < 3; i++) {
+ dout.writeByte(0); //RESERVED
+ }
+ dout.write(this.bitsPerIDE); //component sizes
+ }
+
+}
diff --git a/src/java/org/apache/fop/afp/ioca/ImageContent.java b/src/java/org/apache/fop/afp/ioca/ImageContent.java
index fe902b381..9c06589e0 100644
--- a/src/java/org/apache/fop/afp/ioca/ImageContent.java
+++ b/src/java/org/apache/fop/afp/ioca/ImageContent.java
@@ -56,21 +56,18 @@ public class ImageContent extends AbstractStructuredObject {
/** the image size parameter */
private ImageSizeParameter imageSizeParameter = null;
+ /** the IDE Structure parameter */
+ private IDEStructureParameter ideStructureParameter = null;
+
/** the image encoding */
private byte encoding = (byte)0x03;
- /** the image ide size */
- private byte size = 1;
+ /** the image IDE (Image Data Element, Sample) size */
+ private byte ideSize = 1;
/** the image compression */
private byte compression = (byte)0xC0;
- /** the image color model */
- private byte colorModel = (byte)0x01;
-
- /** additive/subtractive setting for ASFLAG */
- private boolean subtractive = false;
-
/** the image data */
private byte[] data;
@@ -90,6 +87,34 @@ public class ImageContent extends AbstractStructuredObject {
}
/**
+ * Sets the IDE Structure parameter.
+ * @param parameter the IDE Structure parameter
+ */
+ public void setIDEStructureParameter(IDEStructureParameter parameter) {
+ this.ideStructureParameter = parameter;
+ }
+
+ /**
+ * Returns the (optional) IDE Structure parameter
+ * @return the IDE Structure parameter or null if none is set
+ */
+ public IDEStructureParameter getIDEStructureParameter() {
+ return this.ideStructureParameter;
+ }
+
+ /**
+ * Returns the (optional) IDE Structure parameter. If none is set an instance is prepared
+ * with defaults for a bi-level image.
+ * @return the IDE Structure parameter
+ */
+ public IDEStructureParameter needIDEStructureParameter() {
+ if (this.ideStructureParameter == null) {
+ setIDEStructureParameter(new IDEStructureParameter());
+ }
+ return getIDEStructureParameter();
+ }
+
+ /**
* Sets the image encoding.
*
* @param enc The image encoding.
@@ -113,24 +138,26 @@ public class ImageContent extends AbstractStructuredObject {
* @param s The IDE size.
*/
public void setImageIDESize(byte s) {
- this.size = s;
+ this.ideSize = s;
}
/**
* Sets the image IDE color model.
*
* @param color the IDE color model.
+ * @deprecated use {@link #setIDEStructureParameter(IDEStructureParameter)} instead
*/
public void setImageIDEColorModel(byte color) {
- this.colorModel = color;
+ needIDEStructureParameter().setColorModel(color);
}
/**
* Set either additive or subtractive mode (used for ASFLAG).
* @param subtractive true for subtractive mode, false for additive mode
+ * @deprecated use {@link #setIDEStructureParameter(IDEStructureParameter)} instead
*/
public void setSubtractive(boolean subtractive) {
- this.subtractive = subtractive;
+ needIDEStructureParameter().setSubtractive(subtractive);
}
/**
@@ -155,10 +182,12 @@ public class ImageContent extends AbstractStructuredObject {
os.write(getImageIDESizeParameter());
- boolean useFS10 = (this.size == 1);
- if (!useFS10) {
- os.write(getIDEStructureParameter());
+ if (getIDEStructureParameter() != null) {
+ getIDEStructureParameter().writeToStream(os);
+ }
+ boolean useFS10 = (this.ideSize == 1);
+ if (!useFS10) {
os.write(getExternalAlgorithmParameter());
}
@@ -243,58 +272,15 @@ public class ImageContent extends AbstractStructuredObject {
* @return byte[] The data stream.
*/
private byte[] getImageIDESizeParameter() {
- if (size != 1) {
+ if (ideSize != 1) {
final byte[] ideSizeData = new byte[] {
(byte)0x96, // ID
0x01, // Length
- size};
+ ideSize};
return ideSizeData;
} else {
return new byte[0];
}
}
- /**
- * Helper method to return the external algorithm parameter.
- *
- * @return byte[] The data stream.
- */
- private byte[] getIDEStructureParameter() {
- byte flags = 0x00;
- if (subtractive) {
- flags |= 1 << 7;
- }
- if (colorModel != 0 && size == 24) {
- final byte bits = (byte)(size / 3);
- final byte[] ideStructData = new byte[] {
- (byte)0x9B, // ID
- 0x00, // Length
- flags, // FLAGS
- colorModel, // COLOR MODEL
- 0x00, // Reserved
- 0x00, // Reserved
- 0x00, // Reserved
- bits,
- bits,
- bits,
- };
- ideStructData[1] = (byte)(ideStructData.length - 2);
- return ideStructData;
- } else if (size == 1) {
- final byte[] ideStructData = new byte[] {
- (byte)0x9B, // ID
- 0x00, // Length
- flags, // FLAGS
- colorModel, // COLOR MODEL
- 0x00, // Reserved
- 0x00, // Reserved
- 0x00, // Reserved
- 0x01
- };
- ideStructData[1] = (byte)(ideStructData.length - 2);
- return ideStructData;
- }
- return new byte[0];
- }
-
}
diff --git a/src/java/org/apache/fop/afp/ioca/ImageSegment.java b/src/java/org/apache/fop/afp/ioca/ImageSegment.java
index d8ba38ec0..9965bb94a 100644
--- a/src/java/org/apache/fop/afp/ioca/ImageSegment.java
+++ b/src/java/org/apache/fop/afp/ioca/ImageSegment.java
@@ -56,7 +56,11 @@ public class ImageSegment extends AbstractNamedAFPObject {
this.factory = factory;
}
- private ImageContent getImageContent() {
+ /**
+ * Returns the image content object associated with this image segment.
+ * @return the image content
+ */
+ public ImageContent getImageContent() {
if (imageContent == null) {
this.imageContent = factory.createImageContent();
}
@@ -108,6 +112,7 @@ public class ImageSegment extends AbstractNamedAFPObject {
* Sets the image IDE color model.
*
* @param colorModel the IDE color model.
+ * @deprecated Use {@link IDEStructureParameter#setColorModel(byte)} instead.
*/
public void setIDEColorModel(byte colorModel) {
getImageContent().setImageIDEColorModel(colorModel);
@@ -116,6 +121,7 @@ public class ImageSegment extends AbstractNamedAFPObject {
/**
* Set either additive or subtractive mode (used for ASFLAG).
* @param subtractive true for subtractive mode, false for additive mode
+ * @deprecated Use {@link IDEStructureParameter#setSubtractive(boolean)} instead.
*/
public void setSubtractive(boolean subtractive) {
getImageContent().setSubtractive(subtractive);
@@ -124,7 +130,7 @@ public class ImageSegment extends AbstractNamedAFPObject {
/**
* Set the data image data.
*
- * @param data the image data
+ * @param imageData the image data
*/
public void setData(byte[] imageData) {
getImageContent().setImageData(imageData);
diff --git a/src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java b/src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java
index 0f99d6624..38c60d7b6 100644
--- a/src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java
+++ b/src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java
@@ -79,6 +79,8 @@ public class ContainerDataDescriptor extends AbstractDescriptor {
data[18] = ysize[0];
data[19] = ysize[1];
data[20] = ysize[2];
+
+ os.write(data);
}
}
diff --git a/src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java b/src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java
index 0a7b665d7..386d2f40f 100644
--- a/src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java
+++ b/src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java
@@ -31,6 +31,7 @@ public class ImageDataDescriptor extends AbstractDescriptor {
public static final byte FUNCTION_SET_FS10 = 0x0A;
public static final byte FUNCTION_SET_FS11 = 0x0B;
+ public static final byte FUNCTION_SET_FS45 = 45;
private byte functionSet = FUNCTION_SET_FS11; // FCNSET = IOCA FS 11
diff --git a/src/java/org/apache/fop/afp/modca/ImageObject.java b/src/java/org/apache/fop/afp/modca/ImageObject.java
index 65802f6ca..2f075ce33 100644
--- a/src/java/org/apache/fop/afp/modca/ImageObject.java
+++ b/src/java/org/apache/fop/afp/modca/ImageObject.java
@@ -24,9 +24,12 @@ import java.io.OutputStream;
import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.xmlgraphics.util.MimeConstants;
+
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPImageObjectInfo;
import org.apache.fop.afp.Factory;
+import org.apache.fop.afp.ioca.IDEStructureParameter;
import org.apache.fop.afp.ioca.ImageSegment;
/**
@@ -50,7 +53,11 @@ public class ImageObject extends AbstractDataObject {
super(factory, name);
}
- private ImageSegment getImageSegment() {
+ /**
+ * Returns the image segment object associated with this image object.
+ * @return the image segment
+ */
+ public ImageSegment getImageSegment() {
if (imageSegment == null) {
this.imageSegment = factory.createImageSegment();
}
@@ -71,6 +78,8 @@ public class ImageObject extends AbstractDataObject {
= factory.createImageDataDescriptor(dataWidth, dataHeight, dataWidthRes, dataHeightRes);
if (imageObjectInfo.getBitsPerPixel() == 1) {
imageDataDescriptor.setFunctionSet(ImageDataDescriptor.FUNCTION_SET_FS10);
+ } else if (MimeConstants.MIME_AFP_IOCA_FS45.equals(imageObjectInfo.getMimeType())) {
+ imageDataDescriptor.setFunctionSet(ImageDataDescriptor.FUNCTION_SET_FS45);
}
getObjectEnvironmentGroup().setDataDescriptor(imageDataDescriptor);
getObjectEnvironmentGroup().setMapImageObject(
@@ -110,6 +119,7 @@ public class ImageObject extends AbstractDataObject {
* Sets the image IDE color model.
*
* @param colorModel the IDE color model.
+ * @deprecated Use {@link IDEStructureParameter#setColorModel(byte)} instead.
*/
public void setIDEColorModel(byte colorModel) {
getImageSegment().setIDEColorModel(colorModel);
@@ -118,6 +128,7 @@ public class ImageObject extends AbstractDataObject {
/**
* Set either additive or subtractive mode (used for ASFLAG).
* @param subtractive true for subtractive mode, false for additive mode
+ * @deprecated Use {@link IDEStructureParameter#setSubtractive(boolean)} instead.
*/
public void setSubtractive(boolean subtractive) {
getImageSegment().setSubtractive(subtractive);
diff --git a/src/java/org/apache/fop/render/afp/AFPCustomizable.java b/src/java/org/apache/fop/render/afp/AFPCustomizable.java
index ed1ea443b..5f3fe6823 100644
--- a/src/java/org/apache/fop/render/afp/AFPCustomizable.java
+++ b/src/java/org/apache/fop/render/afp/AFPCustomizable.java
@@ -51,6 +51,14 @@ public interface AFPCustomizable {
void setNativeImagesSupported(boolean nativeImages);
/**
+ * Controls whether CMYK images (IOCA FS45) are enabled. By default, support is disabled
+ * for wider compatibility. When disabled, any CMYK image is converted to the selected
+ * color format.
+ * @param value true to enabled CMYK images
+ */
+ void setCMYKImagesSupported(boolean value);
+
+ /**
* Sets the shading mode for painting filled rectangles.
* @param shadingMode the shading mode
*/
diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
index 1f7a732d1..3fec25d8d 100644
--- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
@@ -357,6 +357,11 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
}
/** {@inheritDoc} */
+ public void setCMYKImagesSupported(boolean value) {
+ paintingState.setCMYKImagesSupported(value);
+ }
+
+ /** {@inheritDoc} */
public void setShadingMode(AFPShadingMode shadingMode) {
this.shadingMode = shadingMode;
}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java
index 99ede8e79..fcfc9c64c 100644
--- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java
@@ -24,6 +24,7 @@ import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.ImageRawEPS;
import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
+import org.apache.xmlgraphics.util.MimeConstants;
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.render.RenderingContext;
@@ -35,6 +36,7 @@ public class AFPImageHandlerRawStream extends AbstractAFPImageHandlerRawStream {
private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
ImageFlavor.RAW_JPEG,
+ ImageFlavor.RAW_TIFF,
ImageFlavor.RAW_EPS,
};
@@ -63,7 +65,12 @@ public class AFPImageHandlerRawStream extends AbstractAFPImageHandlerRawStream {
if (targetContext instanceof AFPRenderingContext) {
AFPRenderingContext afpContext = (AFPRenderingContext)targetContext;
return (afpContext.getPaintingState().isNativeImagesSupported())
- && (image == null || image instanceof ImageRawJPEG || image instanceof ImageRawEPS);
+ && (image == null
+ || image instanceof ImageRawJPEG
+ || image instanceof ImageRawEPS
+ || ((image instanceof ImageRawStream)
+ && (MimeConstants.MIME_TIFF.equals(
+ ((ImageRawStream)image).getMimeType()))));
}
return false;
}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
index 8f7918583..b0988e754 100644
--- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
@@ -89,7 +89,11 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
int resolution = paintingState.getResolution();
int maxPixelSize = paintingState.getBitsPerPixel();
if (paintingState.isColorImages()) {
- maxPixelSize *= 3; //RGB only at the moment
+ if (paintingState.isCMYKImagesSupported()) {
+ maxPixelSize *= 4; //CMYK is maximum
+ } else {
+ maxPixelSize *= 3; //RGB is maximum
+ }
}
RenderedImage renderedImage = imageRendered.getRenderedImage();
@@ -97,6 +101,7 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
ImageSize intrinsicSize = imageInfo.getSize();
boolean useFS10 = (maxPixelSize == 1) || BitmapImageUtil.isMonochromeImage(renderedImage);
+ int functionSet = useFS10 ? 10 : 11;
boolean usePageSegments = useFS10
&& !imageObjectInfo.getResourceInfo().getLevel().isInline();
@@ -124,11 +129,6 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
resampledDim.width, resampledDim.height, resolution);
}
}
- if (useFS10) {
- imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS10);
- } else {
- imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS11);
- }
imageObjectInfo.setDataHeightRes((int)Math.round(
effIntrinsicSize.getDpiHorizontal() * 10));
@@ -156,9 +156,9 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
byte[] imageData = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
boolean allowDirectEncoding = true;
- if (allowDirectEncoding && pixelSize <= maxPixelSize) {
+ if (allowDirectEncoding && (pixelSize <= maxPixelSize)) {
//Attempt to encode without resampling the image
- ImageEncodingHelper helper = new ImageEncodingHelper(renderedImage);
+ ImageEncodingHelper helper = new ImageEncodingHelper(renderedImage, pixelSize == 32);
ColorModel encodedColorModel = helper.getEncodedColorModel();
boolean directEncode = true;
if (helper.getEncodedColorModel().getPixelSize() > maxPixelSize) {
@@ -180,6 +180,9 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
log.trace("set subtractive mode");
imageObjectInfo.setSubtractive(true);
}
+ if (pixelSize == 32) {
+ functionSet = 45; //IOCA FS45 required for CMYK
+ }
helper.encode(baos);
imageData = baos.toByteArray();
@@ -191,6 +194,7 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
//Convert image to 24bit RGB
ImageEncodingHelper.encodeRenderedImageAsRGB(renderedImage, baos);
imageData = baos.toByteArray();
+ imageObjectInfo.setBitsPerPixel(24);
boolean colorImages = paintingState.isColorImages();
imageObjectInfo.setColor(colorImages);
@@ -212,6 +216,20 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
}
}
+ switch (functionSet) {
+ case 10:
+ imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS10);
+ break;
+ case 11:
+ imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS11);
+ break;
+ case 45:
+ imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45);
+ break;
+ default:
+ throw new IllegalStateException("Invalid IOCA function set: " + functionSet);
+ }
+
imageObjectInfo.setData(imageData);
// set object area info
diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java
index f019c6a47..250ff9624 100644
--- a/src/java/org/apache/fop/render/afp/AFPRenderer.java
+++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java
@@ -90,8 +90,8 @@ import org.apache.fop.render.afp.extensions.AFPElementMapping;
import org.apache.fop.render.afp.extensions.AFPExtensionAttachment;
import org.apache.fop.render.afp.extensions.AFPIncludeFormMap;
import org.apache.fop.render.afp.extensions.AFPInvokeMediumMap;
-import org.apache.fop.render.afp.extensions.AFPPageSetup;
import org.apache.fop.render.afp.extensions.AFPPageOverlay;
+import org.apache.fop.render.afp.extensions.AFPPageSetup;
/**
* This is an implementation of a FOP Renderer that renders areas to AFP.
@@ -444,6 +444,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer implements AFPCust
ImageFlavor.XML_DOM,
/*ImageFlavor.RAW_PNG, */ // PNG not natively supported in AFP
ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.RAW_EPS,
+ ImageFlavor.RAW_TIFF,
ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE };
private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
@@ -831,6 +832,11 @@ public class AFPRenderer extends AbstractPathOrientedRenderer implements AFPCust
}
/** {@inheritDoc} */
+ public void setCMYKImagesSupported(boolean value) {
+ paintingState.setCMYKImagesSupported(value);
+ }
+
+ /** {@inheritDoc} */
public void setShadingMode(AFPShadingMode shadingMode) {
this.shadingMode = shadingMode;
}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
index 49e51b3d1..1e15d4c72 100644
--- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
@@ -318,6 +318,9 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
String imagesMode = imagesCfg.getAttribute("mode", IMAGES_MODE_GRAYSCALE);
if (IMAGES_MODE_COLOR.equals(imagesMode)) {
customizable.setColorImages(true);
+
+ boolean cmyk = imagesCfg.getAttributeAsBoolean("cmyk", false);
+ customizable.setCMYKImagesSupported(cmyk);
} else {
customizable.setColorImages(false);
// default to 8 bits per pixel
diff --git a/status.xml b/status.xml
index 2aab61b1e..31afd446b 100644
--- a/status.xml
+++ b/status.xml
@@ -58,6 +58,9 @@
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
+ <action context="Code" dev="JM" type="add">
+ Added support for encoding CMYK bitmap images (IOCA FS45) and TIFF images as embedded objects.
+ </action>
<action context="Code" dev="AC" type="add">
Added support for xmlfile and xsltfile parameters in FOP's Ant Task.
</action>