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)
    {<FILL_FUNCTION_BODY>}

    /**
     * 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 = dictionary.getCOSArray(COSName.GAMMA);
        if (gammaArray == null)
        {
            gammaArray = new COSArray();
            gammaArray.add(COSFloat.ONE);
            gammaArray.add(COSFloat.ONE);
            gammaArray.add(COSFloat.ONE);
            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 = dictionary.getCOSArray(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)
        {
            // We can't use matrix.toCOSArray(), as it only returns a subset of the matrix
            float[][] values = matrix.getValues();
            matrixArray = new COSArray();
            matrixArray.add(new COSFloat(values[0][0]));
            matrixArray.add(new COSFloat(values[0][1]));
            matrixArray.add(new COSFloat(values[0][2]));
            matrixArray.add(new COSFloat(values[1][0]));
            matrixArray.add(new COSFloat(values[1][1]));
            matrixArray.add(new COSFloat(values[1][2]));
            matrixArray.add(new COSFloat(values[2][0]));
            matrixArray.add(new COSFloat(values[2][1]));
            matrixArray.add(new COSFloat(values[2][2]));
        }
        dictionary.setItem(COSName.MATRIX, matrixArray);
    }
}

        if (isWhitePoint())
        {
            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] };
        }
    
<methods>public final org.apache.pdfbox.pdmodel.graphics.color.PDTristimulus getBlackPoint() ,public final org.apache.pdfbox.pdmodel.graphics.color.PDTristimulus getWhitepoint() ,public void setBlackPoint(org.apache.pdfbox.pdmodel.graphics.color.PDTristimulus) ,public void setWhitePoint(org.apache.pdfbox.pdmodel.graphics.color.PDTristimulus) <variables>private static final java.awt.color.ColorSpace CIEXYZ,protected final non-sealed org.apache.pdfbox.cos.COSDictionary dictionary,protected float wpX,protected float wpY,protected float wpZ