You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlgraphics.apache.org by ma...@apache.org on 2009/07/24 14:19:49 UTC
svn commit: r797427 - in /xmlgraphics/commons/trunk: ./
src/java/org/apache/xmlgraphics/image/loader/impl/
src/java/org/apache/xmlgraphics/image/loader/impl/imageio/
Author: maxberger
Date: Fri Jul 24 12:19:49 2009
New Revision: 797427
URL: http://svn.apache.org/viewvc?rev=797427&view=rev
Log:
Support loading of ICC Profiles from PNG and JPEG when used through ImageIO
Modified:
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageBuffered.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterBuffered2Rendered.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterG2D2Bitmap.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageRendered.java
xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderImageIO.java
xmlgraphics/commons/trunk/status.xml
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageBuffered.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageBuffered.java?rev=797427&r1=797426&r2=797427&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageBuffered.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageBuffered.java Fri Jul 24 12:19:49 2009
@@ -20,6 +20,7 @@
package org.apache.xmlgraphics.image.loader.impl;
import java.awt.Color;
+import java.awt.color.ICC_Profile;
import java.awt.image.BufferedImage;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
@@ -35,9 +36,10 @@
* @param info the image info object
* @param buffered the BufferedImage instance
* @param transparentColor the transparent color or null
+ * @param iccProfile an ICC color profile or null if no profile is associated
*/
- public ImageBuffered(ImageInfo info, BufferedImage buffered, Color transparentColor) {
- super(info, buffered, transparentColor);
+ public ImageBuffered(ImageInfo info, BufferedImage buffered, Color transparentColor, ICC_Profile iccProfile) {
+ super(info, buffered, transparentColor, iccProfile);
}
/** {@inheritDoc} */
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterBuffered2Rendered.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterBuffered2Rendered.java?rev=797427&r1=797426&r2=797427&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterBuffered2Rendered.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterBuffered2Rendered.java Fri Jul 24 12:19:49 2009
@@ -34,7 +34,9 @@
public Image convert(Image src, Map hints) {
checkSourceFlavor(src);
ImageBuffered buffered = (ImageBuffered)src;
- return new ImageRendered(buffered.getInfo(), buffered.getRenderedImage(), null);
+ return new ImageRendered(buffered.getInfo(), buffered
+ .getRenderedImage(), buffered.getTransparentColor(), buffered
+ .getICCProfile());
}
/** {@inheritDoc} */
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterG2D2Bitmap.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterG2D2Bitmap.java?rev=797427&r1=797426&r2=797427&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterG2D2Bitmap.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageConverterG2D2Bitmap.java Fri Jul 24 12:19:49 2009
@@ -73,7 +73,7 @@
BufferedImage bi = paintToBufferedImage(g2dImage, bitsPerPixel, withAlpha, resolution);
- ImageBuffered bufImage = new ImageBuffered(src.getInfo(), bi, null);
+ ImageBuffered bufImage = new ImageBuffered(src.getInfo(), bi, null, src.getICCProfile());
return bufImage;
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.java?rev=797427&r1=797426&r2=797427&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderInternalTIFF.java Fri Jul 24 12:19:49 2009
@@ -70,8 +70,8 @@
org.apache.xmlgraphics.image.codec.tiff.TIFFImage img
= new org.apache.xmlgraphics.image.codec.tiff.TIFFImage
(seekStream, null, 0);
-
- return new ImageRendered(info, img, null);
+ // TODO: This may ignore ICC Profiles stored in TIFF images.
+ return new ImageRendered(info, img, null, null);
}
}
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageRendered.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageRendered.java?rev=797427&r1=797426&r2=797427&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageRendered.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageRendered.java Fri Jul 24 12:19:49 2009
@@ -33,19 +33,33 @@
*/
public class ImageRendered extends AbstractImage {
- private RenderedImage red;
- private Color transparentColor;
+ private final RenderedImage red;
+ private final Color transparentColor;
+ private final ColorSpace colorSpace;
+ private final ICC_Profile iccProfile;
/**
* Main constructor.
* @param info the image info object
* @param red the RenderedImage instance
* @param transparentColor the transparent color or null
+ * @param iccProfile an ICC color profile or null if no profile is associated
*/
- public ImageRendered(ImageInfo info, RenderedImage red, Color transparentColor) {
+ public ImageRendered(ImageInfo info, RenderedImage red, Color transparentColor, ICC_Profile iccProfile) {
super(info);
this.red = red;
this.transparentColor = transparentColor;
+ this.colorSpace = red.getColorModel().getColorSpace();
+ if (iccProfile == null) {
+ if (this.colorSpace instanceof ICC_ColorSpace) {
+ ICC_ColorSpace icccs = (ICC_ColorSpace)this.colorSpace;
+ this.iccProfile = icccs.getProfile();
+ } else {
+ this.iccProfile = null;
+ }
+ } else {
+ this.iccProfile = iccProfile;
+ }
}
/** {@inheritDoc} */
@@ -68,17 +82,12 @@
/** {@inheritDoc} */
public ColorSpace getColorSpace() {
- return getRenderedImage().getColorModel().getColorSpace();
+ return this.colorSpace;
}
/** {@inheritDoc} */
public ICC_Profile getICCProfile() {
- ColorSpace cs = getColorSpace();
- if (cs instanceof ICC_ColorSpace) {
- ICC_ColorSpace icccs = (ICC_ColorSpace)cs;
- return icccs.getProfile();
- }
- return null;
+ return this.iccProfile;
}
/**
Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderImageIO.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderImageIO.java?rev=797427&r1=797426&r2=797427&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderImageIO.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/imageio/ImageLoaderImageIO.java Fri Jul 24 12:19:49 2009
@@ -20,30 +20,33 @@
package org.apache.xmlgraphics.image.loader.impl.imageio;
import java.awt.Color;
+import java.awt.color.ICC_Profile;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
+import java.util.zip.DataFormatException;
+import java.util.zip.Inflater;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageInputStream;
import javax.xml.transform.Source;
-import org.w3c.dom.Element;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
@@ -53,6 +56,7 @@
import org.apache.xmlgraphics.image.loader.impl.ImageBuffered;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
+import org.w3c.dom.Element;
/**
* An ImageLoader implementation based on ImageIO for loading bitmap images.
@@ -63,6 +67,10 @@
protected static Log log = LogFactory.getLog(ImageLoaderImageIO.class);
private ImageFlavor targetFlavor;
+
+ private static final String PNG_METADATA_NODE = "javax_imageio_png_1.0";
+
+ private static final String JPEG_METADATA_NODE = "javax_imageio_jpeg_image_1.0";
/**
* Main constructor.
@@ -156,13 +164,15 @@
throw new ImageException("No ImageIO ImageReader found .");
}
+ ICC_Profile iccProf = null;
+
ColorModel cm = imageData.getColorModel();
Color transparentColor = null;
if (cm instanceof IndexColorModel) {
//transparent color will be extracted later from the image
} else {
- //ImageIOUtil.dumpMetadataToSystemOut(iiometa);
+ ImageIOUtil.dumpMetadataToSystemOut(iiometa);
//Retrieve the transparent color from the metadata
if (iiometa != null && iiometa.isStandardMetadataFormatSupported()) {
Element metanode = (Element)iiometa.getAsTree(
@@ -187,16 +197,88 @@
}
}
}
+ iccProf = tryToExctractICCProfile(iiometa);
}
}
if (ImageFlavor.BUFFERED_IMAGE.equals(this.targetFlavor)) {
- return new ImageBuffered(info, (BufferedImage)imageData, transparentColor);
+ return new ImageBuffered(info, (BufferedImage)imageData, transparentColor, iccProf);
} else {
- return new ImageRendered(info, imageData, transparentColor);
+ return new ImageRendered(info, imageData, transparentColor, iccProf);
}
}
+ /**
+ * Extract ICC Profile from ImageIO Metadata. This method currently only
+ * supports PNG and JPEG metadata.
+ *
+ * @param iiometa
+ * The ImageIO Metadata
+ * @return an ICC Profile or null.
+ */
+ private ICC_Profile tryToExctractICCProfile(IIOMetadata iiometa) {
+ ICC_Profile iccProf = null;
+ String supportedFormats[] = iiometa.getMetadataFormatNames();
+ for (int i = 0; i < supportedFormats.length; i++) {
+ String format = supportedFormats[i];
+ Element root = (Element) iiometa.getAsTree(format);
+ if (PNG_METADATA_NODE.equals(format)) {
+ iccProf = this
+ .tryToExctractICCProfileFromPNGMetadataNode(root);
+ } else if (JPEG_METADATA_NODE.equals(format)) {
+ iccProf = this.tryToExctractICCProfileFromJPEGMetadataNode(root);
+ }
+ }
+ return iccProf;
+ }
+
+ private ICC_Profile tryToExctractICCProfileFromPNGMetadataNode(
+ Element pngNode) {
+ ICC_Profile iccProf = null;
+ Element iccpNode = ImageIOUtil.getChild(pngNode, "iCCP");
+ if (iccpNode instanceof IIOMetadataNode) {
+ IIOMetadataNode imn = (IIOMetadataNode) iccpNode;
+ byte[] prof = (byte[]) imn.getUserObject();
+ String comp = imn.getAttribute("compressionMethod");
+ if ("deflate".equalsIgnoreCase(comp)) {
+ Inflater decompresser = new Inflater();
+ decompresser.setInput(prof);
+ byte[] result = new byte[100];
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ while (!decompresser.finished()) {
+ try {
+ int resultLength = decompresser.inflate(result);
+ bos.write(result, 0, resultLength);
+ } catch (DataFormatException e) {
+ log.debug("Failed to deflate ICC Profile", e);
+ }
+ }
+ decompresser.end();
+ try {
+ iccProf = ICC_Profile.getInstance(bos.toByteArray());
+ } catch (IllegalArgumentException e) {
+ log.debug("Failed to interpret embedded ICC Profile", e);
+ iccProf = null;
+ }
+ }
+ }
+ return iccProf;
+ }
+
+ private ICC_Profile tryToExctractICCProfileFromJPEGMetadataNode(
+ Element jpgNode) {
+ ICC_Profile iccProf = null;
+ Element jfifNode = ImageIOUtil.getChild(jpgNode, "app0JFIF");
+ if (jfifNode != null) {
+ Element app2iccNode = ImageIOUtil.getChild(jfifNode, "app2ICC");
+ if (app2iccNode instanceof IIOMetadataNode) {
+ IIOMetadataNode imn = (IIOMetadataNode) app2iccNode;
+ iccProf = (ICC_Profile) imn.getUserObject();
+ }
+ }
+ return iccProf;
+ }
+
private BufferedImage getFallbackBufferedImage(ImageReader reader,
int pageIndex, ImageReadParam param) throws IOException {
//Work-around found at: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4799903
Modified: xmlgraphics/commons/trunk/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/status.xml?rev=797427&r1=797426&r2=797427&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/status.xml (original)
+++ xmlgraphics/commons/trunk/status.xml Fri Jul 24 12:19:49 2009
@@ -40,7 +40,10 @@
</contexts>
<changes>
<release version="Trunk" date="n/a">
- <action context="Code" dev="JM" type="fix">
+ <action context="Code" dev="MB" type="add">
+ Support loading of ICC Profiles from PNG and JPEG when used through ImageIO.
+ </action>
+ <action context="Code" dev="JM" type="fix">
Switched from linear RGB to sRGB for the fallback color model, in order to avoid trouble
with some images (CMYK TIFF, for example).
</action>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: commits-help@xmlgraphics.apache.org