001: /*
002: * $Id: PDFColorSpace.java,v 1.2 2007/12/20 18:33:34 rbair Exp $
003: *
004: * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005: * Santa Clara, California 95054, U.S.A. All rights reserved.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020: */
021:
022: package com.sun.pdfview.colorspace;
023:
024: import java.awt.Color;
025: import java.awt.color.ColorSpace;
026: import java.awt.color.ICC_ColorSpace;
027: import java.awt.color.ICC_Profile;
028: import java.io.ByteArrayInputStream;
029: import java.io.IOException;
030: import java.util.Map;
031:
032: import com.sun.pdfview.PDFObject;
033: import com.sun.pdfview.PDFPaint;
034: import com.sun.pdfview.PDFParseException;
035: import com.sun.pdfview.function.PDFFunction;
036:
037: /**
038: * A color space that can convert a set of color components into
039: * PDFPaint.
040: * @author Mike Wessler
041: */
042: public class PDFColorSpace {
043: /** the name of the device-dependent gray color space */
044: public static final int COLORSPACE_GRAY = 0;
045: /** the name of the device-dependent RGB color space */
046: public static final int COLORSPACE_RGB = 1;
047: /** the name of the device-dependent CMYK color space */
048: public static final int COLORSPACE_CMYK = 2;
049: /** the name of the pattern color space */
050: public static final int COLORSPACE_PATTERN = 3;
051:
052: /** the device-dependent color spaces */
053: private static PDFColorSpace graySpace = new PDFColorSpace(
054: ColorSpace.getInstance(ColorSpace.CS_GRAY));
055: private static PDFColorSpace rgbSpace = new PDFColorSpace(
056: ColorSpace.getInstance(ColorSpace.CS_sRGB));
057: private static PDFColorSpace cmykSpace = new PDFColorSpace(
058: new CMYKColorSpace());
059:
060: /** the pattern space */
061: private static PDFColorSpace patternSpace = new PatternSpace();
062:
063: /** the color space */
064: ColorSpace cs;
065:
066: /**
067: * create a PDFColorSpace based on a Java ColorSpace
068: * @param cs the Java ColorSpace
069: */
070: protected PDFColorSpace(ColorSpace cs) {
071: this .cs = cs;
072: }
073:
074: /**
075: * Get a color space by name
076: *
077: * @param name the name of one of the device-dependent color spaces
078: */
079: public static PDFColorSpace getColorSpace(int name) {
080: switch (name) {
081: case COLORSPACE_GRAY:
082: return graySpace;
083: case COLORSPACE_RGB:
084: return rgbSpace;
085: case COLORSPACE_CMYK:
086: return cmykSpace;
087: case COLORSPACE_PATTERN:
088: return patternSpace;
089: default:
090: throw new IllegalArgumentException(
091: "Unknown Color Space name: " + name);
092: }
093: }
094:
095: /**
096: * Get a color space specified in a PDFObject
097: *
098: * @param csobj the PDFObject with the colorspace information
099: */
100: public static PDFColorSpace getColorSpace(PDFObject csobj,
101: Map resources) throws IOException {
102: String name;
103:
104: PDFObject colorSpaces = null;
105: if (resources != null) {
106: colorSpaces = (PDFObject) resources.get("ColorSpace");
107: }
108:
109: if (csobj.getType() == PDFObject.NAME) {
110: name = csobj.getStringValue();
111: if (name.equals("DeviceGray") || name.equals("G")) {
112: return getColorSpace(COLORSPACE_GRAY);
113: } else if (name.equals("DeviceRGB") || name.equals("RGB")) {
114: return getColorSpace(COLORSPACE_RGB);
115: } else if (name.equals("DeviceCMYK") || name.equals("CMYK")) {
116: return getColorSpace(COLORSPACE_CMYK);
117: } else if (name.equals("Pattern")) {
118: return getColorSpace(COLORSPACE_PATTERN);
119: } else if (colorSpaces != null) {
120: csobj = (PDFObject) colorSpaces.getDictRef(name);
121: }
122: }
123:
124: if (csobj == null) {
125: return null;
126: } else if (csobj.getCache() != null) {
127: return (PDFColorSpace) csobj.getCache();
128: }
129:
130: PDFColorSpace value = null;
131:
132: // csobj is [/name <<dict>>]
133: PDFObject[] ary = csobj.getArray();
134: name = ary[0].getStringValue();
135:
136: if (name.equals("CalGray")) {
137: value = new PDFColorSpace(new CalGrayColor(ary[1]));
138: } else if (name.equals("CalRGB")) {
139: value = new PDFColorSpace(new CalRGBColor(ary[1]));
140: } else if (name.equals("Lab")) {
141: value = new PDFColorSpace(new LabColor(ary[1]));
142: } else if (name.equals("ICCBased")) {
143: ByteArrayInputStream bais = new ByteArrayInputStream(ary[1]
144: .getStream());
145: ICC_Profile profile = ICC_Profile.getInstance(bais);
146: value = new PDFColorSpace(new ICC_ColorSpace(profile));
147: } else if (name.equals("Separation") || name.equals("DeviceN")) {
148: PDFColorSpace alternate = getColorSpace(ary[2], resources);
149: PDFFunction function = PDFFunction.getFunction(ary[3]);
150:
151: value = new AlternateColorSpace(alternate, function);
152: } else if (name.equals("Indexed") || name.equals("I")) {
153: PDFColorSpace refspace = getColorSpace(ary[1], resources);
154:
155: // number of indices= ary[2], data is in ary[3];
156: int count = ary[2].getIntValue();
157: value = new IndexedColor(refspace, count, ary[3]);
158: } else if (name.equals("Pattern")) {
159: if (ary.length == 1) {
160: return getColorSpace(COLORSPACE_PATTERN);
161: }
162:
163: PDFColorSpace base = getColorSpace(ary[1], resources);
164: return new PatternSpace(base);
165: } else {
166: throw new PDFParseException("Unknown color space: " + name
167: + " with " + ary[1]);
168: }
169:
170: csobj.setCache(value);
171: return value;
172: }
173:
174: /**
175: * get the number of components expected in the getPaint command
176: */
177: public int getNumComponents() {
178: return cs.getNumComponents();
179: }
180:
181: /**
182: * get the PDFPaint representing the color described by the
183: * given color components
184: * @param components the color components corresponding to the given
185: * colorspace
186: * @return a PDFPaint object representing the closest Color to the
187: * given components.
188: */
189: public PDFPaint getPaint(float[] components) {
190: float rgb[] = cs.toRGB(components);
191: return PDFPaint
192: .getColorPaint(new Color(rgb[0], rgb[1], rgb[2]));
193: }
194:
195: /**
196: * get the original Java ColorSpace.
197: */
198: public ColorSpace getColorSpace() {
199: return cs;
200: }
201: }
|