All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.color.ColorspaceFactory Maven / Gradle / Ivy

The newest version!
/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/java-pdf-library-support/
 *
 * (C) Copyright 1997-2013, IDRsolutions and Contributors.
 *
 * 	This file is part of JPedal
 *
     This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 *
 * ---------------
 * ColorspaceFactory.java
 * ---------------
 */
package org.jpedal.color;

import java.util.Map;

import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;

/**
 * @author markee
 * 
 *         returns the correct colorspace, decoding the values
 */
public class ColorspaceFactory {

	private ColorspaceFactory() {}

	/**
	 * used by commands which implicitly set colorspace
	 */
	final public static GenericColorSpace getColorSpaceInstance(PdfObjectReader currentPdfFile, PdfObject colorSpace, Map colorspacesObjects) {

		// see if we already have it
		String key;
		if (colorSpace.getStatus() == PdfObject.DECODED) key = colorSpace.getObjectRefAsString();
		else key = new String(colorSpace.getUnresolvedData());

		GenericColorSpace col = null;

		// cache some colorspaces for speed
		Object cachedValue = colorspacesObjects.get(key);

		if (cachedValue != null) {
			col = (GenericColorSpace) cachedValue;
			col.reset();
		}

		if (col == null) {

			col = getColorSpaceInstance(currentPdfFile, colorSpace);

			if (col.getID() == ColorSpaces.ICC) colorspacesObjects.put(key, col);

		}

		return col;
	}

	/**
	 * used by commands which implicitly set colorspace
	 */
	final public static GenericColorSpace getColorSpaceInstance(PdfObjectReader currentPdfFile, PdfObject colorSpace) {

		currentPdfFile.checkResolved(colorSpace);

		int ID = colorSpace.getParameterConstant(PdfDictionary.ColorSpace);

		// allow for CMYK in ID
		if (ID == PdfDictionary.CMYK) ID = ColorSpaces.DeviceCMYK;

		boolean isIndexed = false;
		int size = 0;
		byte[] lookup = null;

		int rawID = -1;

		/** setup colorspaces which map onto others */
		if (ID == ColorSpaces.Indexed || ID == PdfDictionary.I) {

			isIndexed = true;

			// get raw values from Indexed
			size = colorSpace.getInt(PdfDictionary.hival);
			lookup = colorSpace.getDictionary(PdfDictionary.Lookup).getDecodedStream();

			// actual colorspace
			colorSpace = colorSpace.getDictionary(PdfDictionary.Indexed);
			ID = colorSpace.getParameterConstant(PdfDictionary.ColorSpace);
			rawID = ID;

		}

		GenericColorSpace currentColorData = getColorspace(currentPdfFile, colorSpace, ID);

		/** handle CMAP as object or direct */
		if (isIndexed) {

			// ICC code will wrongly create RGB in case of indexed ICC with DeviceGray alt - here we fit this
			// (sampe file is Customers-june2011/early mockup.pdf)
			if (rawID == ColorSpaces.ICC && lookup.length < 3) currentColorData = new DeviceGrayColorSpace();

			currentColorData.setIndex(lookup, size);
		}

		currentColorData.setAlternateColorSpace(colorSpace.getParameterConstant(PdfDictionary.Alternate));

		return currentColorData;
	}

	private static GenericColorSpace getColorspace(PdfObjectReader currentPdfFile, PdfObject colorSpace, int ID) {

		// no DeviceRGB as set as default
		GenericColorSpace currentColorData = new DeviceRGBColorSpace();

		switch (ID) {
			case ColorSpaces.Separation:
				currentColorData = new SeparationColorSpace(currentPdfFile, colorSpace);
				break;

			case ColorSpaces.DeviceN:
				currentColorData = new DeviceNColorSpace(currentPdfFile, colorSpace);
				break;

			case ColorSpaces.DeviceGray:
				currentColorData = new DeviceGrayColorSpace();
				break;

			case ColorSpaces.DeviceCMYK:
				currentColorData = new DeviceCMYKColorSpace();
				break;

			case ColorSpaces.CalGray:
				currentColorData = getCalGrayColorspace(colorSpace);
				break;

			case ColorSpaces.CalRGB:
				currentColorData = getCalRGBColorspace(colorSpace);
				break;

			case ColorSpaces.Lab:
				currentColorData = getLabColorspace(colorSpace);
				break;

			case ColorSpaces.ICC:
				currentColorData = getICCColorspace(colorSpace);
				break;

			case ColorSpaces.Pattern:
				currentColorData = new PatternColorSpace(currentPdfFile);
				break;

		}

		return currentColorData;
	}

	private static GenericColorSpace getICCColorspace(PdfObject colorSpace) {

		GenericColorSpace currentColorData = new DeviceRGBColorSpace();

		// int ID;
		/**
		 * Switch ICC to alt Gray
		 */
		int alt = colorSpace.getParameterConstant(PdfDictionary.Alternate);
		if (alt == ColorSpaces.DeviceGray) {// || alt== ColorSpaces.DeviceRGB){

			// use the RGB

			// }else if(alt==ColorSpaces.DeviceCMYK){

			// currentColorData=new DeviceCMYKColorSpace();
		}
		else {
			currentColorData = new ICCColorSpace(colorSpace);
		}

		// use if issue with data
		if (alt == ColorSpaces.DeviceCMYK && currentColorData.isInvalid()) {
			currentColorData = new DeviceCMYKColorSpace();
		}

		return currentColorData;
	}

	private static GenericColorSpace getLabColorspace(PdfObject colorSpace) {

		float[] R = { -100f, 100f, -100.0f, 100.0f };
		float[] W = { 0.0f, 1.0f, 0.0f };
		float[] B = { 0.0f, 0.0f, 0.0f };

		float[] blackpointArray = colorSpace.getFloatArray(PdfDictionary.BlackPoint);
		float[] whitepointArray = colorSpace.getFloatArray(PdfDictionary.WhitePoint);
		float[] rangeArray = colorSpace.getFloatArray(PdfDictionary.Range);

		if (whitepointArray != null) W = whitepointArray;

		if (blackpointArray != null) B = blackpointArray;

		if (rangeArray != null) R = rangeArray;

		return new LabColorSpace(W, B, R);
	}

	private static GenericColorSpace getCalRGBColorspace(PdfObject colorSpace) {

		float[] W = { 0.0f, 1.0f, 0.0f };
		float[] B = { 0.0f, 0.0f, 0.0f };
		float[] G = { 1.0f, 1.0f, 1.0f };
		float[] Ma = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };

		float[] gammaArray = colorSpace.getFloatArray(PdfDictionary.Gamma);
		float[] blackpointArray = colorSpace.getFloatArray(PdfDictionary.BlackPoint);
		float[] whitepointArray = colorSpace.getFloatArray(PdfDictionary.WhitePoint);
		float[] matrixArray = colorSpace.getFloatArray(PdfDictionary.Matrix);

		if (whitepointArray != null) W = whitepointArray;

		if (blackpointArray != null) B = blackpointArray;

		if (gammaArray != null) G = gammaArray;

		if (matrixArray != null) Ma = matrixArray;

		return new CalRGBColorSpace(W, B, Ma, G);
	}

	private static GenericColorSpace getCalGrayColorspace(PdfObject colorSpace) {

		float[] W = { 0.0f, 1.0f, 0.0f };
		float[] B = { 0.0f, 0.0f, 0.0f };
		float[] G = { 1.0f, 1.0f, 1.0f };

		float[] gammaArray = null;
		float[] blackpointArray = colorSpace.getFloatArray(PdfDictionary.BlackPoint);
		float[] whitepointArray = colorSpace.getFloatArray(PdfDictionary.WhitePoint);
		float rawGamma = colorSpace.getFloatNumber(PdfDictionary.Gamma);
		if (rawGamma != -1) {
			gammaArray = new float[1];
			gammaArray[0] = rawGamma;
		}

		if (whitepointArray != null) W = whitepointArray;

		if (blackpointArray != null) B = blackpointArray;

		if (gammaArray != null) G = gammaArray;

		return new CalGrayColorSpace(W, B, G);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy