/* * 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. */ package org.apache.pdfbox.pdmodel.graphics.color; import java.awt.color.ColorSpace; import java.awt.color.ICC_ColorSpace; import java.io.IOException; import java.io.OutputStream; import java.util.Map; import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSBase; import org.apache.pdfbox.cos.COSFloat; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.common.PDStream; import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace; /** * This class represents a color space in a pdf document. * * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a> * @version $Revision: 1.11 $ */ public final class PDColorSpaceFactory { /** * Private constructor for utility classes. */ private PDColorSpaceFactory() { //utility class should not be implemented } /** * This will create the correct color space given the name. * * @param colorSpace The color space object. * * @return The color space. * * @throws IOException If the color space name is unknown. */ public static PDColorSpace createColorSpace( COSBase colorSpace ) throws IOException { return createColorSpace( colorSpace, null ); } /** * This will create the correct color space given the name. * * @param colorSpace The color space object. * @param colorSpaces The ColorSpace dictionary from the current resources, if any. * * @return The color space. * * @throws IOException If the color space name is unknown. */ public static PDColorSpace createColorSpace( COSBase colorSpace, Map<String, PDColorSpace> colorSpaces ) throws IOException { PDColorSpace retval = null; if( colorSpace instanceof COSName ) { retval = createColorSpace( ((COSName)colorSpace).getName(), colorSpaces ); } else if( colorSpace instanceof COSArray ) { COSArray array = (COSArray)colorSpace; String name = ((COSName)array.getObject( 0 )).getName(); if( name.equals( PDCalGray.NAME ) ) { retval = new PDCalGray( array ); } else if( name.equals( PDDeviceRGB.NAME ) ) { retval = PDDeviceRGB.INSTANCE; } else if( name.equals( PDDeviceGray.NAME ) ) { retval = new PDDeviceGray(); } else if( name.equals( PDDeviceCMYK.NAME ) ) { retval = PDDeviceCMYK.INSTANCE; } else if( name.equals( PDCalRGB.NAME ) ) { retval = new PDCalRGB( array ); } else if( name.equals( PDDeviceN.NAME ) ) { retval = new PDDeviceN( array ); } else if( name.equals( PDIndexed.NAME ) || name.equals( PDIndexed.ABBREVIATED_NAME )) { retval = new PDIndexed( array ); } else if( name.equals( PDLab.NAME ) ) { retval = new PDLab( array ); } else if( name.equals( PDSeparation.NAME ) ) { retval = new PDSeparation( array ); } else if( name.equals( PDICCBased.NAME ) ) { retval = new PDICCBased( array ); } else if( name.equals( PDPattern.NAME ) ) { retval = new PDPattern( array ); } else { throw new IOException( "Unknown colorspace array type:" + name ); } } else { throw new IOException( "Unknown colorspace type:" + colorSpace ); } return retval; } /** * This will create the correct color space given the name. * * @param colorSpaceName The name of the colorspace. * * @return The color space. * * @throws IOException If the color space name is unknown. */ public static PDColorSpace createColorSpace( String colorSpaceName ) throws IOException { return createColorSpace(colorSpaceName, null); } /** * This will create the correct color space given the name. * * @param colorSpaceName The name of the colorspace. * @param colorSpaces The ColorSpace dictionary from the current resources, if any. * * @return The color space. * * @throws IOException If the color space name is unknown. */ public static PDColorSpace createColorSpace( String colorSpaceName, Map<String, PDColorSpace> colorSpaces ) throws IOException { PDColorSpace cs = null; if( colorSpaceName.equals( PDDeviceCMYK.NAME ) || colorSpaceName.equals( PDDeviceCMYK.ABBREVIATED_NAME ) ) { cs = PDDeviceCMYK.INSTANCE; } else if( colorSpaceName.equals( PDDeviceRGB.NAME ) || colorSpaceName.equals( PDDeviceRGB.ABBREVIATED_NAME ) ) { cs = PDDeviceRGB.INSTANCE; } else if( colorSpaceName.equals( PDDeviceGray.NAME ) || colorSpaceName.equals( PDDeviceGray.ABBREVIATED_NAME )) { cs = new PDDeviceGray(); } else if( colorSpaces != null && colorSpaces.get( colorSpaceName ) != null ) { cs = (PDColorSpace)colorSpaces.get( colorSpaceName ); } else if( colorSpaceName.equals( PDLab.NAME ) ) { cs = new PDLab(); } else if( colorSpaceName.equals( PDPattern.NAME ) ) { cs = new PDPattern(); } else { throw new IOException( "Error: Unknown colorspace '" + colorSpaceName + "'" ); } return cs; } /** * This will create the correct color space from a java colorspace. * * @param doc The doc to potentiall write information to. * @param cs The awt colorspace. * * @return The color space. * * @throws IOException If the color space name is unknown. */ public static PDColorSpace createColorSpace( PDDocument doc, ColorSpace cs ) throws IOException { PDColorSpace retval = null; if( cs.isCS_sRGB() ) { retval = PDDeviceRGB.INSTANCE; } else if( cs instanceof ICC_ColorSpace ) { ICC_ColorSpace ics = (ICC_ColorSpace)cs; PDICCBased pdCS = new PDICCBased( doc ); retval = pdCS; COSArray ranges = new COSArray(); for( int i=0; i<cs.getNumComponents(); i++ ) { ranges.add( new COSFloat( ics.getMinValue( i ) ) ); ranges.add( new COSFloat( ics.getMaxValue( i ) ) ); } PDStream iccData = pdCS.getPDStream(); OutputStream output = null; try { output = iccData.createOutputStream(); output.write( ics.getProfile().getData() ); } finally { if( output != null ) { output.close(); } } pdCS.setNumberOfComponents( cs.getNumComponents() ); } else { throw new IOException( "Not yet implemented:" + cs ); } return retval; } }