*/
protected Color transparentColor = null;
+ /**
+ * Photoshop generated CMYK JPEGs are inverted.
+ */
+ protected boolean invertImage = false;
+
/**
* Constructor.
* Construct a new FopImage object and initialize its default properties:
return this.transparentColor;
}
+ /** @return true for CMYK images generated by Adobe Photoshop */
+ public boolean isInverted() {
+ return this.invertImage;
+ }
+
/**
* Return the image data (pixels, uncompressed).
* @return the image data
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
*/
byte[] getSoftMask();
+ /** @return true for CMYK images generated by Adobe Photoshop */
+ boolean isInverted();
+
/**
* Returns the decoded and uncompressed image as a array of
* width * height * [colorspace-multiplicator] pixels.
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
package org.apache.fop.image;
// Java
-import java.io.ByteArrayOutputStream;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
// FOP
import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.fop.util.CMYKColorSpace;
/**
public class JpegImage extends AbstractFopImage {
private ICC_Profile iccProfile = null;
private boolean foundICCProfile = false;
+ private boolean hasAPPEMarker = false;
/**
* Create a jpeg image with the info.
*/
protected boolean loadOriginalData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ByteArrayOutputStream iccStream = new ByteArrayOutputStream();
+ ByteArrayOutputStream iccStream = null;
int index = 0;
boolean cont = true;
this.raw[index + 2],
this.raw[index + 3]) + 2;
+ if (iccStream == null) {
+ iccStream = new ByteArrayOutputStream();
+ }
iccStream.write(this.raw,
index + 18, chunkSize - 18);
}
+ index += calcBytes(this.raw[index + 2],
+ this.raw[index + 3]) + 2;
+ // Check for Adobe APPE Marker
+ } else if ((uByte(this.raw[index]) == 0xff
+ && uByte(this.raw[index + 1]) == 0xee
+ && uByte(this.raw[index + 2]) == 0
+ && uByte(this.raw[index + 3]) == 14
+ && "Adobe".equals(new String(this.raw, index + 4, 5)))) {
+ // The reason for reading the APPE marker is that Adobe Photoshop
+ // generates CMYK JPEGs with inverted values. The correct thing
+ // to do would be to interpret the values in the marker, but for now
+ // only assume that if APPE marker is present and colorspace is CMYK,
+ // the image is inverted.
+ hasAPPEMarker = true;
+
index += calcBytes(this.raw[index + 2],
this.raw[index + 3]) + 2;
} else {
+ "JpegImage - Invalid JPEG Header.");
return false;
}
- if (iccStream.size() > 0) {
- byte[] align = new byte[((iccStream.size()) % 8) + 8];
- try {
- iccStream.write(align);
- } catch (Exception ex) {
- log.error("Error while aligning ICC stream: " + ex.getMessage(), ex);
- return false;
+ if (iccStream != null && iccStream.size() > 0) {
+ int padding = (8 - (iccStream.size() % 8)) % 8;
+ if (padding != 0) {
+ try {
+ iccStream.write(new byte[padding]);
+ } catch (Exception ex) {
+ log.error("Error while aligning ICC stream: " + ex.getMessage(), ex);
+ return false;
+ }
}
try {
iccProfile = ICC_Profile.getInstance(iccStream.toByteArray());
log.error("ColorSpace not specified for JPEG image");
return false;
}
+ if (hasAPPEMarker && this.colorSpace.getType() == ColorSpace.TYPE_CMYK) {
+ this.invertImage = true;
+ }
return true;
}
return maskRef;
}
+ /** @see org.apache.fop.pdf.PDFImage#isInverted() */
+ public boolean isInverted() {
+ return false;
+ }
+
/**
* @see org.apache.fop.pdf.PDFImage#outputContents(OutputStream)
*/
public PDFFilter getPDFFilter() {
return null;
}
-
+
}
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
*/
String getSoftMask();
+ /** @return true for CMYK images generated by Adobe Photoshop */
+ boolean isInverted();
+
/**
* Get the PDF Filter to be applied to the image.
*
+ "\n");
}
- /* PhotoShop generates CMYK values that's inverse,
- this will invert the values - too bad if it's not
- a PhotoShop image...
- */
- if (pdfimage.getColorSpace().getColorSpace()
- == PDFColorSpace.DEVICE_CMYK) {
- sb.append("/Decode [ 1.0 0.0 1.0 0.0 1.0 0.0 1.1 0.0 ]\n");
+ if (pdfimage.isInverted()) {
+ /* PhotoShop generates CMYK values that's inverse,
+ * this will invert the values - too bad if it's not
+ * a PhotoShop image...
+ */
+ if (pdfimage.getColorSpace().getColorSpace() == PDFColorSpace.DEVICE_CMYK) {
+ sb.append("/Decode [ 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 ]\n");
+ } else if (pdfimage.getColorSpace().getColorSpace() == PDFColorSpace.DEVICE_RGB) {
+ sb.append("/Decode [ 1.0 0.0 1.0 0.0 1.0 0.0 ]\n");
+ } else if (pdfimage.getColorSpace().getColorSpace() == PDFColorSpace.DEVICE_GRAY) {
+ sb.append("/Decode [ 1.0 0.0 ]\n");
+ }
}
if (pdfimage.isTransparent()) {
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 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.
pdfFilter.setApplied(true);
isDCT = true;
- ICC_Profile prof = fopImage.getICCProfile();
- PDFColorSpace pdfCS = toPDFColorSpace(fopImage.getColorSpace());
- if (prof != null) {
- pdfICCStream = doc.getFactory().makePDFICCStream();
- pdfICCStream.setColorSpace(prof, pdfCS);
- }
} else if ("image/tiff".equals(fopImage.getMimeType())
&& fopImage instanceof TIFFImage) {
TIFFImage tiffImage = (TIFFImage) fopImage;
} else {
fopImage.load(FopImage.BITMAP);
}
+ ICC_Profile prof = fopImage.getICCProfile();
+ PDFColorSpace pdfCS = toPDFColorSpace(fopImage.getColorSpace());
+ if (prof != null) {
+ pdfICCStream = doc.getFactory().makePDFICCStream();
+ pdfICCStream.setColorSpace(prof, pdfCS);
+ }
//Handle transparency mask if applicable
if (fopImage.hasSoftMask()) {
byte [] softMask = fopImage.getSoftMask();
return softMaskRef;
}
+ /** @return true for CMYK images generated by Adobe Photoshop */
+ public boolean isInverted() {
+ return fopImage.isInverted();
+ }
+
/**
* @see org.apache.fop.pdf.PDFImage#isPS()
*/
return this.mask;
}
+ public boolean isInverted() {
+ return false;
+ }
+
public byte[] getBitmaps() {
return this.bitmaps;
}