You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlgraphics.apache.org by je...@apache.org on 2010/06/29 15:59:58 UTC

svn commit: r958970 - in /xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile: ./ NamedColorProfile.java NamedColorProfileParser.java

Author: jeremias
Date: Tue Jun 29 13:59:58 2010
New Revision: 958970

URL: http://svn.apache.org/viewvc?rev=958970&view=rev
Log:
Added a parser for ICC named color profiles.

Added:
    xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/
    xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfile.java   (with props)
    xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileParser.java   (with props)

Added: xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfile.java?rev=958970&view=auto
==============================================================================
--- xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfile.java (added)
+++ xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfile.java Tue Jun 29 13:59:58 2010
@@ -0,0 +1,106 @@
+/*
+ * 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.xmlgraphics.java2d.color.profile;
+
+import java.awt.color.ICC_Profile;
+
+import org.apache.xmlgraphics.java2d.color.NamedColorSpace;
+
+/**
+ * Simplified in-memory representation of an ICC named color profile.
+ */
+public class NamedColorProfile {
+
+    private String profileName;
+    private String copyright;
+    private NamedColorSpace[] namedColors;
+    private int renderingIntent = ICC_Profile.icPerceptual;
+
+    /**
+     * Creates a new named color profile.
+     * @param profileName the profile name
+     * @param copyright the copyright
+     * @param namedColors the array of named colors
+     */
+    public NamedColorProfile(String profileName, String copyright, NamedColorSpace[] namedColors) {
+        this.profileName = profileName;
+        this.copyright = copyright;
+        this.namedColors = namedColors;
+    }
+
+    /**
+     * Returns the color profile's rendering intent.
+     * @return the rendering intent (See {@link ICC_Profile}.ic*)
+     */
+    public int getRenderingIntent() {
+        return this.renderingIntent;
+    }
+
+    /**
+     * Returns the array of named colors.
+     * @return the array of named colors
+     */
+    public NamedColorSpace[] getNamedColors() {
+        NamedColorSpace[] copy = new NamedColorSpace[this.namedColors.length];
+        System.arraycopy(this.namedColors, 0, copy, 0, this.namedColors.length);
+        return copy;
+    }
+
+    /**
+     * Returns a named color.
+     * @param name the color name
+     * @return the named color (or null if it is not available)
+     */
+    public NamedColorSpace getNamedColor(String name) {
+        if (this.namedColors != null) {
+            for (int i = 0, c = this.namedColors.length; i < c; i++) {
+                if (this.namedColors[i].getColorName().equals(name)) {
+                    return this.namedColors[i];
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the profile name.
+     * @return the profile name
+     */
+    public String getProfileName() {
+        return this.profileName;
+    }
+
+    /**
+     * Returns the profile copyright.
+     * @return the profile copyright
+     */
+    public String getCopyright() {
+        return this.copyright;
+    }
+
+    /** {@inheritDoc} */
+    public String toString() {
+        StringBuffer sb = new StringBuffer("Named color profile: ");
+        sb.append(getProfileName());
+        sb.append(", ").append(namedColors.length).append(" colors");
+        return sb.toString();
+    }
+
+}

Propchange: xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfile.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfile.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileParser.java?rev=958970&view=auto
==============================================================================
--- xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileParser.java (added)
+++ xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileParser.java Tue Jun 29 13:59:58 2010
@@ -0,0 +1,172 @@
+/*
+ * 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.xmlgraphics.java2d.color.profile;
+
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.io.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.apache.xmlgraphics.java2d.color.CIELabColorSpace;
+import org.apache.xmlgraphics.java2d.color.NamedColorSpace;
+
+/**
+ * This class is a parser for ICC named color profiles. It uses Java's {@link ICC_Profile} class
+ * for parsing the basic structure but adds functionality to parse certain profile tags.
+ */
+public class NamedColorProfileParser {
+
+    private static final int MLUC = 0x6D6C7563; //'mluc'
+    private static final int NCL2 = 0x6E636C32; //'ncl2'
+
+    /**
+     * Indicates whether the profile is a named color profile.
+     * @param profile the color profile
+     * @return true if the profile is a named color profile, false otherwise
+     */
+    public static boolean isNamedColorProfile(ICC_Profile profile) {
+        return profile.getProfileClass() == ICC_Profile.CLASS_NAMEDCOLOR;
+    }
+
+    /**
+     * Parses a named color profile (NCP).
+     * @param profile the profile to analyze
+     * @return an object representing the parsed NCP
+     * @throws IOException if an I/O error occurs
+     */
+    public NamedColorProfile parseProfile(ICC_Profile profile) throws IOException {
+        if (!isNamedColorProfile(profile)) {
+            throw new IllegalArgumentException("Given profile is not a named color profile (NCP)");
+        }
+        String profileDescription = getProfileDescription(profile);
+        String copyright = getCopyright(profile);
+        NamedColorSpace[] ncs = readNamedColors(profile);
+        return new NamedColorProfile(profileDescription, copyright, ncs);
+    }
+
+    private String getProfileDescription(ICC_Profile profile) throws IOException {
+        byte[] tag = profile.getData(ICC_Profile.icSigProfileDescriptionTag);
+        return readSimpleString(tag);
+    }
+
+    private String getCopyright(ICC_Profile profile) throws IOException {
+        byte[] tag = profile.getData(ICC_Profile.icSigCopyrightTag);
+        return readSimpleString(tag);
+    }
+
+    private NamedColorSpace[] readNamedColors(ICC_Profile profile) throws IOException {
+        byte[] tag = profile.getData(ICC_Profile.icSigNamedColor2Tag);
+        DataInput din = new DataInputStream(new ByteArrayInputStream(tag));
+        int sig = din.readInt();
+        if (sig != NCL2) {
+            throw new UnsupportedOperationException("Unsupported structure type: "
+                    + toSignatureString(sig) + ". Expected " + toSignatureString(NCL2));
+        }
+        din.skipBytes(8);
+        int numColors = din.readInt();
+        NamedColorSpace[] result = new NamedColorSpace[numColors];
+        int numDeviceCoord = din.readInt();
+        String prefix = readAscii(din, 32);
+        String suffix = readAscii(din, 32);
+        for (int i = 0; i < numColors; i++) {
+            String name = prefix + readAscii(din, 32) + suffix;
+            int[] pcs = readUInt16Array(din, 3);
+            float[] colorvalue = new float[3];
+            for (int j = 0; j < pcs.length; j++) {
+                colorvalue[j] = ((float)pcs[j]) / 0x8000;
+            }
+
+            //device coordinates are ignored for now
+            /*int[] deviceCoord =*/ readUInt16Array(din, numDeviceCoord);
+
+            switch (profile.getPCSType()) {
+            case ColorSpace.TYPE_XYZ:
+                result[i] = new NamedColorSpace(name, colorvalue);
+                break;
+            case ColorSpace.TYPE_Lab:
+                //Not sure if this always D50 here,
+                //but the illuminant in the header is fixed to D50.
+                CIELabColorSpace labCS = new CIELabColorSpace(CIELabColorSpace.getD50WhitePoint());
+                result[i] = new NamedColorSpace(name, labCS.toColor(colorvalue, 1.0f));
+                break;
+            default:
+                throw new UnsupportedOperationException(
+                        "PCS type is not supported: " + profile.getPCSType());
+            }
+        }
+        return result;
+    }
+
+    private int[] readUInt16Array(DataInput din, int count) throws IOException {
+        if (count == 0) {
+            return null;
+        }
+        int[] result = new int[count];
+        for (int i = 0; i < count; i++) {
+            int v = din.readUnsignedShort();
+            result[i] = v;
+        }
+        return result;
+    }
+
+    private String readAscii(DataInput in, int maxLength) throws IOException {
+        byte[] data = new byte[maxLength];
+        in.readFully(data);
+        String result = new String(data, "US-ASCII");
+        int idx = result.indexOf('\0');
+        if (idx >= 0) {
+            result = result.substring(0, idx);
+        }
+        return result;
+    }
+
+    private String readSimpleString(byte[] tag) throws IOException {
+        DataInput din = new DataInputStream(new ByteArrayInputStream(tag));
+        int sig = din.readInt();
+        if (sig == MLUC) {
+            return readMLUC(din);
+        } else {
+            return null; //Unsupported tag structure type
+        }
+    }
+
+    private String readMLUC(DataInput din) throws IOException {
+        din.skipBytes(16);
+        int firstLength = din.readInt();
+        int firstOffset = din.readInt();
+        int offset = 28;
+        din.skipBytes(firstOffset - offset);
+        byte[] utf16 = new byte[firstLength];
+        din.readFully(utf16);
+        return new String(utf16, "UTF-16BE");
+    }
+
+    private String toSignatureString(int sig) {
+        StringBuffer sb = new StringBuffer();
+        sb.append((char)(sig >> 24 & 0xFF));
+        sb.append((char)(sig >> 16 & 0xFF));
+        sb.append((char)(sig >> 8 & 0xFF));
+        sb.append((char)(sig & 0xFF));
+        return sb.toString();
+    }
+
+}

Propchange: xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/commons/branches/Temp_Color/src/java/org/apache/xmlgraphics/java2d/color/profile/NamedColorProfileParser.java
------------------------------------------------------------------------------
    svn:keywords = Id



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: commits-help@xmlgraphics.apache.org