Browse Source

Bugfix for ICC color profile parsing in JPEG images.

Ported detection code for CMYK JPEG images generated by Adobe Photoshop from maintenance branch. Adobe inverts CMYK images.
Reenabled ICC color profile embedding for PDF.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@388460 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_92-beta
Jeremias Maerki 18 years ago
parent
commit
9cb8e3b0f3

+ 10
- 0
src/java/org/apache/fop/image/AbstractFopImage.java View File

@@ -103,6 +103,11 @@ public abstract class AbstractFopImage implements FopImage {
*/
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:
@@ -321,6 +326,11 @@ public abstract class AbstractFopImage implements FopImage {
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

+ 4
- 1
src/java/org/apache/fop/image/FopImage.java View File

@@ -1,5 +1,5 @@
/*
* 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.
@@ -141,6 +141,9 @@ public interface FopImage {
*/
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.

+ 34
- 10
src/java/org/apache/fop/image/JpegImage.java View File

@@ -1,5 +1,5 @@
/*
* 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.
@@ -19,12 +19,12 @@
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;

/**
@@ -36,6 +36,7 @@ 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.
@@ -55,7 +56,7 @@ public class JpegImage extends AbstractFopImage {
*/
protected boolean loadOriginalData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayOutputStream iccStream = new ByteArrayOutputStream();
ByteArrayOutputStream iccStream = null;
int index = 0;
boolean cont = true;

@@ -136,11 +137,29 @@ public class JpegImage extends AbstractFopImage {
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 {
@@ -157,13 +176,15 @@ public class JpegImage extends AbstractFopImage {
+ "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());
@@ -175,6 +196,9 @@ public class JpegImage extends AbstractFopImage {
log.error("ColorSpace not specified for JPEG image");
return false;
}
if (hasAPPEMarker && this.colorSpace.getType() == ColorSpace.TYPE_CMYK) {
this.invertImage = true;
}
return true;
}


+ 6
- 1
src/java/org/apache/fop/pdf/BitmapImage.java View File

@@ -172,6 +172,11 @@ public class BitmapImage implements PDFImage {
return maskRef;
}

/** @see org.apache.fop.pdf.PDFImage#isInverted() */
public boolean isInverted() {
return false;
}
/**
* @see org.apache.fop.pdf.PDFImage#outputContents(OutputStream)
*/
@@ -208,7 +213,7 @@ public class BitmapImage implements PDFImage {
public PDFFilter getPDFFilter() {
return null;
}
}



+ 4
- 1
src/java/org/apache/fop/pdf/PDFImage.java View File

@@ -1,5 +1,5 @@
/*
* 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.
@@ -109,6 +109,9 @@ public interface PDFImage {
*/
String getSoftMask();

/** @return true for CMYK images generated by Adobe Photoshop */
boolean isInverted();
/**
* Get the PDF Filter to be applied to the image.
*

+ 12
- 7
src/java/org/apache/fop/pdf/PDFXObject.java View File

@@ -131,13 +131,18 @@ public class PDFXObject extends AbstractPDFStream {
+ "\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()) {

+ 12
- 7
src/java/org/apache/fop/render/pdf/FopPDFImage.java View File

@@ -1,5 +1,5 @@
/*
* 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.
@@ -81,12 +81,6 @@ public class FopPDFImage implements PDFImage {
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;
@@ -116,6 +110,12 @@ public class FopPDFImage implements PDFImage {
} 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();
@@ -200,6 +200,11 @@ public class FopPDFImage implements PDFImage {
return softMaskRef;
}

/** @return true for CMYK images generated by Adobe Photoshop */
public boolean isInverted() {
return fopImage.isInverted();
}
/**
* @see org.apache.fop.pdf.PDFImage#isPS()
*/

+ 4
- 0
src/java/org/apache/fop/render/ps/PSGraphics2D.java View File

@@ -390,6 +390,10 @@ public class PSGraphics2D extends AbstractGraphics2D {
return this.mask;
}

public boolean isInverted() {
return false;
}
public byte[] getBitmaps() {
return this.bitmaps;
}

Loading…
Cancel
Save