001: /*
002: * $RCSfile: ColorSpecificationBox.java,v $
003: *
004: *
005: * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * - Redistribution of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * - Redistribution in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * Neither the name of Sun Microsystems, Inc. or the names of
020: * contributors may be used to endorse or promote products derived
021: * from this software without specific prior written permission.
022: *
023: * This software is provided "AS IS," without a warranty of any
024: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
025: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
026: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
027: * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
028: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
029: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
030: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
031: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
032: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
033: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
034: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
035: * POSSIBILITY OF SUCH DAMAGES.
036: *
037: * You acknowledge that this software is not designed or intended for
038: * use in the design, construction, operation or maintenance of any
039: * nuclear facility.
040: *
041: * $Revision: 1.1 $
042: * $Date: 2005/02/11 05:01:32 $
043: * $State: Exp $
044: */
045: package com.sun.media.imageioimpl.plugins.jpeg2000;
046:
047: import java.awt.color.ICC_Profile;
048: import javax.imageio.metadata.IIOInvalidTreeException;
049: import javax.imageio.metadata.IIOMetadataNode;
050: import org.w3c.dom.Node;
051: import org.w3c.dom.NodeList;
052:
053: /** This class is defined to represent a Color Specification Box of JPEG JP2
054: * file format. A Channel Definition Box has a length, and a fixed type
055: * of "colr". Its content contains the method to define the color space,
056: * the precedence and approximation accuracy (0 for JP2 files), the
057: * enumerated color space, and the ICC color profile if any.
058: */
059: public class ColorSpecificationBox extends Box {
060: /** The enumerated color space defined in JP2 file format. */
061: public static final int ECS_sRGB = 16;
062: public static final int ECS_GRAY = 17;
063: public static final int ECS_YCC = 18;
064:
065: /** Cache the element names for this box's xml definition */
066: private static String[] elementNames = { "Method", "Precedence",
067: "ApproximationAccuracy", "EnumeratedColorSpace",
068: "ICCProfile" };
069:
070: /** This method will be called by the getNativeNodeForSimpleBox of the
071: * class Box to get the element names.
072: */
073: public static String[] getElementNames() {
074: return elementNames;
075: }
076:
077: /** The elements' values. */
078: private byte method;
079: private byte precedence;
080: private byte approximation;
081: private int ecs;
082: private ICC_Profile profile;
083:
084: /** Computes the length of this box when profile is present. */
085: private static int computeLength(byte m, ICC_Profile profile) {
086: int ret = 15;
087: if (m == 2 && profile != null) {
088: ret += profile.getData().length;
089: }
090: return ret;
091: }
092:
093: /** Creates a <code>ColorSpecificationBox</code> from the provided data
094: * elements.
095: */
096: public ColorSpecificationBox(byte m, byte p, byte a, int ecs,
097: ICC_Profile profile) {
098: super (computeLength(m, profile), 0x636F6C72, null);
099: this .method = m;
100: this .precedence = p;
101: this .approximation = a;
102: this .ecs = ecs;
103: this .profile = profile;
104: }
105:
106: /** Creates a <code>ColorSpecificationBox</code> from the provided byte
107: * array.
108: */
109: public ColorSpecificationBox(byte[] data) {
110: super (8 + data.length, 0x636F6C72, data);
111: }
112:
113: /** Constructs a <code>ColorSpecificationBox</code> based on the provided
114: * <code>org.w3c.dom.Node</code>.
115: */
116: public ColorSpecificationBox(Node node)
117: throws IIOInvalidTreeException {
118: super (node);
119: NodeList children = node.getChildNodes();
120:
121: for (int i = 0; i < children.getLength(); i++) {
122: Node child = children.item(i);
123: String name = child.getNodeName();
124:
125: if ("Method".equals(name)) {
126: method = Box.getByteElementValue(child);
127: }
128:
129: if ("Precedence".equals(name)) {
130: precedence = Box.getByteElementValue(child);
131: }
132:
133: if ("ApproximationAccuracy".equals(name)) {
134: approximation = Box.getByteElementValue(child);
135: }
136:
137: if ("EnumeratedColorSpace".equals(name)) {
138: ecs = Box.getIntElementValue(child);
139: }
140:
141: if ("ICCProfile".equals(name)) {
142: if (child instanceof IIOMetadataNode)
143: profile = (ICC_Profile) ((IIOMetadataNode) child)
144: .getUserObject();
145: else {
146: String value = node.getNodeValue();
147: if (value != null)
148: profile = ICC_Profile.getInstance(Box
149: .parseByteArray(value));
150: }
151: }
152: }
153: }
154:
155: /** Returns the method to define the color space. */
156: public byte getMethod() {
157: return method;
158: }
159:
160: /** Returns <code>Precedence</code>. */
161: public byte getPrecedence() {
162: return precedence;
163: }
164:
165: /** Returns <code>ApproximationAccuracy</code>. */
166: public byte getApproximationAccuracy() {
167: return approximation;
168: }
169:
170: /** Returns the enumerated color space. */
171: public int getEnumeratedColorSpace() {
172: return ecs;
173: }
174:
175: /** Returns the ICC color profile in this color specification box. */
176: public ICC_Profile getICCProfile() {
177: return profile;
178: }
179:
180: /** Creates an <code>IIOMetadataNode</code> from this color specification
181: * box. The format of this node is defined in the XML dtd and xsd
182: * for the JP2 image file.
183: */
184: public IIOMetadataNode getNativeNode() {
185: return getNativeNodeForSimpleBox();
186: }
187:
188: protected void parse(byte[] data) {
189: method = data[0];
190: precedence = data[1];
191: approximation = data[2];
192: if (method == 2) {
193: byte[] proData = new byte[data.length - 3];
194: System.arraycopy(data, 3, proData, 0, data.length - 3);
195: profile = ICC_Profile.getInstance(proData);
196: } else
197: ecs = ((data[3] & 0xFF) << 24) | ((data[4] & 0xFF) << 16)
198: | ((data[5] & 0xFF) << 8) | (data[6] & 0xFF);
199:
200: }
201:
202: protected void compose() {
203: if (data != null)
204: return;
205: int len = 7;
206: byte[] profileData = null;
207: if (profile != null) {
208: profileData = profile.getData();
209: len += profileData.length;
210: }
211:
212: data = new byte[len];
213:
214: data[0] = (byte) method;
215: data[1] = (byte) precedence;
216: data[2] = (byte) approximation;
217:
218: copyInt(data, 3, ecs);
219:
220: if (profile != null)
221: System.arraycopy(profileData, 0, data, 7, len - 7);
222: }
223: }
|