/* * 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 org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSFloat; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.util.Matrix; /** * A CalRGB colour space is a CIE-based colour space with one transformation stage instead of two. * In this type of space, A, B, and C represent calibrated red, green, and blue colour values. * * @author Ben Litchfield * @author John Hewson */ public class PDCalRGB extends PDCIEDictionaryBasedColorSpace { private final PDColor initialColor = new PDColor(new float[] { 0, 0, 0 }, this); /** * Creates a new CalRGB color space. */ public PDCalRGB() { super(COSName.CALRGB); } /** * Creates a new CalRGB color space using the given COS array. * @param rgb the cos array which represents this color space */ public PDCalRGB(COSArray rgb) { super(rgb); } @Override public String getName() { return COSName.CALRGB.getName(); } @Override public int getNumberOfComponents() { return 3; } @Override public float[] getDefaultDecode(int bitsPerComponent) { return new float[] { 0, 1, 0, 1, 0, 1 }; } @Override public PDColor getInitialColor() { return initialColor; } @Override public float[] toRGB(float[] value) { if (wpX == 1 && wpY == 1 && wpZ == 1) { float a = value[0]; float b = value[1]; float c = value[2]; PDGamma gamma = getGamma(); float powAR = (float)Math.pow(a, gamma.getR()); float powBG = (float)Math.pow(b, gamma.getG()); float powCB = (float)Math.pow(c, gamma.getB()); float[] matrix = getMatrix(); float mXA = matrix[0]; float mYA = matrix[1]; float mZA = matrix[2]; float mXB = matrix[3]; float mYB = matrix[4]; float mZB = matrix[5]; float mXC = matrix[6]; float mYC = matrix[7]; float mZC = matrix[8]; float x = mXA * powAR + mXB * powBG + mXC * powCB; float y = mYA * powAR + mYB * powBG + mYC * powCB; float z = mZA * powAR + mZB * powBG + mZC * powCB; return convXYZtoRGB(x, y, z); } else { // this is a hack, we simply skip CIE calibration of the RGB value // this works only with whitepoint D65 (0.9505 1.0 1.089) // see PDFBOX-2553 return new float[] { value[0], value[1], value[2] }; } } /** * Returns the gamma value. * If none is present then the default of 1,1,1 will be returned. * @return the gamma value */ public final PDGamma getGamma() { COSArray gammaArray = (COSArray) dictionary.getDictionaryObject(COSName.GAMMA); if (gammaArray == null) { gammaArray = new COSArray(); gammaArray.add(new COSFloat(1.0f)); gammaArray.add(new COSFloat(1.0f)); gammaArray.add(new COSFloat(1.0f)); dictionary.setItem(COSName.GAMMA, gammaArray); } return new PDGamma(gammaArray); } /** * Returns the linear interpretation matrix, which is an array of nine numbers. * If the underlying dictionary contains null then the identity matrix will be returned. * @return the linear interpretation matrix */ public final float[] getMatrix() { COSArray matrix = (COSArray)dictionary.getDictionaryObject(COSName.MATRIX); if (matrix == null) { return new float[] { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; } else { return matrix.toFloatArray(); } } /** * Sets the gamma value. * @param gamma the new gamma value */ public final void setGamma(PDGamma gamma) { COSArray gammaArray = null; if(gamma != null) { gammaArray = gamma.getCOSArray(); } dictionary.setItem(COSName.GAMMA, gammaArray); } /** * Sets the linear interpretation matrix. * Passing in null will clear the matrix. * @param matrix the new linear interpretation matrix, or null */ public final void setMatrix(Matrix matrix) { COSArray matrixArray = null; if(matrix != null) { matrixArray = matrix.toCOSArray(); } dictionary.setItem(COSName.MATRIX, matrixArray); } }