package com.tom_roush.pdfbox.pdmodel.graphics.color; import android.util.Log; import com.tom_roush.pdfbox.cos.COSArray; import com.tom_roush.pdfbox.cos.COSBase; import com.tom_roush.pdfbox.cos.COSName; import com.tom_roush.pdfbox.cos.COSObject; import com.tom_roush.pdfbox.pdmodel.MissingResourceException; import com.tom_roush.pdfbox.pdmodel.PDResources; import com.tom_roush.pdfbox.pdmodel.common.COSObjectable; import java.io.IOException; /** * A color space specifies how the colours of graphics objects will be painted on the page. * * @author John Hewson * @author Ben Litchfield */ public abstract class PDColorSpace implements COSObjectable { /** * Creates a color space space given a name or array. * * @param colorSpace the color space COS object * @return a new color space * @throws IOException if the color space is unknown or cannot be created */ public static PDColorSpace create(COSBase colorSpace) throws IOException { return create(colorSpace, null); } /** * Creates a color space given a name or array. * * @param colorSpace the color space COS object * @param resources the current resources. * @return a new color space * @throws MissingResourceException if the color space is missing in the resources dictionary * @throws IOException if the color space is unknown or cannot be created */ public static PDColorSpace create(COSBase colorSpace, PDResources resources) throws IOException { if (colorSpace instanceof COSObject) { return create(((COSObject) colorSpace).getObject(), resources); } else if (colorSpace instanceof COSName) { COSName name = (COSName) colorSpace; // default color spaces if (resources != null) { COSName defaultName = null; if (name.equals(COSName.DEVICECMYK) && resources.hasColorSpace(COSName.DEFAULT_CMYK)) { defaultName = COSName.DEFAULT_CMYK; } else if (name.equals(COSName.DEVICERGB) && resources.hasColorSpace(COSName.DEFAULT_RGB)) { defaultName = COSName.DEFAULT_RGB; } else if (name.equals(COSName.DEVICEGRAY) && resources.hasColorSpace(COSName.DEFAULT_GRAY)) { defaultName = COSName.DEFAULT_GRAY; } if (resources.hasColorSpace(defaultName)) { return resources.getColorSpace(defaultName); } } // built-in color spaces /*if (name == COSName.DEVICECMYK || name == COSName.CMYK) { return PDDeviceCMYK.INSTANCE; } else*/ if (name == COSName.DEVICERGB || name == COSName.RGB) { return PDDeviceRGB.INSTANCE; } else if (name == COSName.DEVICEGRAY || name == COSName.G) { return PDDeviceGray.INSTANCE; } /*else if (name == COSName.PATTERN) { return new PDPattern(resources); } */else if (resources != null) { if (!resources.hasColorSpace(name)) { throw new MissingResourceException("Missing color space: " + name.getName()); } return resources.getColorSpace(name); } else { throw new MissingResourceException("Unknown color space: " + name.getName()); } } else if (colorSpace instanceof COSArray) { COSArray array = (COSArray) colorSpace; COSName name = (COSName) array.get(0); // // // TODO cache these returned color spaces? // // if (name == COSName.CALGRAY) { // return new PDCalGray(array); // } else if (name == COSName.CALRGB) { // return new PDCalRGB(array); // } else if (name == COSName.DEVICEN) { // return new PDDeviceN(array); // } else if (name == COSName.INDEXED || name == COSName.I) { // return new PDIndexed(array); // } else if (name == COSName.SEPARATION) { // return new PDSeparation(array); // } else if (name == COSName.ICCBASED) { // return new PDICCBased(array); // } else if (name == COSName.LAB) { // return new PDLab(array); // } else if (name == COSName.PATTERN) { // if (array.size() == 1) { // return new PDPattern(resources); // } else { // return new PDPattern(resources, PDColorSpace.create(array.get(1))); // } // } else if (name == COSName.DEVICECMYK || name == COSName.CMYK || // name == COSName.DEVICERGB || name == COSName.RGB || // name == COSName.DEVICEGRAY || name == COSName.PATTERN) { // // not allowed in an array, but we sometimes encounter these regardless // return create(name, resources); // } else { // throw new IOException("Invalid color space kind: " + name); // } // throw new IOException("Invalid color space kind: " + name); Log.e("PdfBox-Android", "Invalid color space kind: " + name + ". Will try DeviceRGB instead"); return PDDeviceRGB.INSTANCE; } else { throw new IOException("Expected a name or array but got: " + colorSpace); } } // array for the given parameters protected COSArray array; /** * Returns the name of the color space. * * @return the name of the color space */ public abstract String getName(); /** * Returns the number of components in this color space * * @return the number of components in this color space */ public abstract int getNumberOfComponents(); /** * Returns the default decode array for this color space. * * @return the default decode array */ public abstract float[] getDefaultDecode(int bitsPerComponent); /** * Returns the initial color value for this color space. * * @return the initial color value for this color space */ public abstract PDColor getInitialColor(); /** * Returns the RGB equivalent of the given color value. * * @param value a color value with component values between 0 and 1 * @return an array of R,G,B value between 0 and 255 * @throws IOException if the color conversion fails */ public abstract float[] toRGB(float[] value) throws IOException; // /** // * Returns the (A)RGB equivalent of the given raster. // * @param raster the source raster // * @return an (A)RGB Bitmap // * @throws IOException if the color conversion fails // */ // public abstract Bitmap toRGBImage(WritableRaster raster) throws IOException; TODO: PdfBox-Android // /** // * Returns the (A)RGB equivalent of the given raster, using the given AWT color space // * to perform the conversion. // * // * @param raster the source raster // * @param colorSpace the AWT // * @return an (A)RGB buffered image // */ // protected Bitmap toRGBImageAWT(WritableRaster raster, ColorSpace colorSpace) // { // // // // WARNING: this method is performance sensitive, modify with care! // // // // // ICC Profile color transforms are only fast when performed using ColorConvertOp // ColorModel colorModel = new ComponentColorModel(colorSpace, // false, false, Transparency.OPAQUE, raster.getDataBuffer().getDataType()); // // BufferedImage src = new BufferedImage(colorModel, raster, false, null); // BufferedImage dest = new BufferedImage(raster.getWidth(), raster.getHeight(), // BufferedImage.TYPE_INT_RGB); // ColorConvertOp op = new ColorConvertOp(null); // op.filter(src, dest); // return dest; // } TODO: PdfBox-Android @Override public COSBase getCOSObject() { return array; } }