Package com.sun.pdfview.colorspace

Source Code of com.sun.pdfview.colorspace.CalRGBColor

/*
* $Id: CalRGBColor.java,v 1.2 2007-12-20 18:33:34 rbair Exp $
*
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

package com.sun.pdfview.colorspace;

import java.awt.color.ColorSpace;
import java.io.IOException;

import com.sun.pdfview.PDFObject;
import com.sun.pdfview.function.FunctionType0;

/**
* A ColorSpace for calibrated RGB
* @author Mike Wessler
*/
public class CalRGBColor extends ColorSpace {
    private static final float[] vonKriesM = 0.40024f, -0.22630f, 0.00000f,
                                                0.70760f1.16532f, 0.00000f,                                     
                                               -0.08081f0.04570f, 0.91822f };
    private static final float[] vonKriesMinv = { 1.859936f0.361191f, 0.000000f,
                                                 -1.129382f0.638812f, 0.000000f,                                        
                                                  0.219897f, -0.000006f, 1.089064f };
    private static final float[] xyzToSRGB = { 3.24071f, -0.969258f0.0556352f,
                                              -1.53726f1.87599f,  -0.203996f,  
                                              -0.498571f, 0.0415557f, 1.05707f };  
                                              
    private static final float[] xyzToRGB = 2.04148f, -0.969258f0.0134455f
                                              -0.564977f, 1.87599f,  -0.118373f,  
                                              -0.344713f, 0.0415557f, 1.01527f };

    float[] scale;
    float[] max;
   
    float white[]= {1f, 1f, 1f};
    float black[]= {0, 0, 0};
    float matrix[]= {1f, 0, 0, 0, 1f, 0, 0, 0, 1f};
    float gamma[]= {1f, 1f, 1f};

    static ColorSpace rgbCS= ColorSpace.getInstance(ColorSpace.CS_sRGB);
    static ColorSpace cieCS= ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
   
    /**
     * Create a new Calibrated RGB color space object, given the
     * description in a PDF dictionary.
     * @param obj a dictionary that contains an array of 3 Numbers
     * for "WhitePoint" and "BlackPoint", a Number for "Gamma", and
     * an array of 9 Numbers for "Matrix".
     */
    public CalRGBColor(PDFObject obj) throws IOException {
  // obj is a dictionary that has the following parts:
  // WhitePoint [a b c]
  // BlackPoint [a b c]
  // Gamma a
  super(CS_sRGB, 3);
       
        // find out what what is according to the CIE color space
        // note that this is not reflexive (i.e. passing this value
        // into toRGB does not get you (1.0, 1.0, 1.0) back)
        // cieWhite = cieCS.fromRGB(new float[] { 1.0f, 1.0f, 1.0f } );
     
        PDFObject ary= obj.getDictRef("WhitePoint");
  if (ary!=null) {
      for(int i=0; i<3; i++) {
    white[i]= ary.getAt(i).getFloatValue();
      }
  }
  ary= obj.getDictRef("BlackPoint");
  if (ary!=null) {
      for(int i=0; i<3; i++) {
    black[i]= ary.getAt(i).getFloatValue();
      }
  }
  ary= obj.getDictRef("Gamma");
  if (ary!=null) {
      for (int i=0; i<3; i++) {
    gamma[i]= ary.getAt(i).getFloatValue();
      }
  }
  ary= obj.getDictRef("Matrix");
  if (ary!=null) {
      for (int i=0; i<9; i++) {
    matrix[i]= ary.getAt(i).getFloatValue();
      }
  }
       
        // create a scale matrix relative to the 50 CIE color space.
        // see http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html
        // we use the Von Kries cone response domain
        float[] cieWhite = rgbCS.toCIEXYZ(new float[] { 1f, 1f, 1f });
    
        float[] sourceWhite = matrixMult(white, vonKriesM, 3);
        float[] destWhite = matrixMult(cieWhite,  vonKriesM, 3);
       
        scale = new float[] { destWhite[0] / sourceWhite[0], 0, 0,
                              0, destWhite[1] / sourceWhite[1], 0,
                              0, 0, destWhite[2] / sourceWhite[2] };
        scale = matrixMult(vonKriesM, scale, 3);
        scale = matrixMult(scale, vonKriesMinv, 3);
   
        max = matrixMult(white, scale, 3);
        max = ciexyzToSRGB(max);
    }

    /**
     * get the number of components (3)
     */
    @Override public int getNumComponents() {
  return 3;
    }

    /**
     * convert from Calibrated RGB to standard RGB
     * @param comp the Calibrated RGB values (0-1)
     * @return the RGB values (0-1)
     */
    public float[] toRGB(float comp[]) {
  if (comp.length==3) {
            // compute r', g' and b' by raising the given values to the
            // correct gamma
      float a = (float)Math.pow(comp[0], gamma[0]);
      float b = (float)Math.pow(comp[1], gamma[1]);
      float c = (float)Math.pow(comp[2], gamma[2]);
     
            // now multiply by the matrix to get X, Y and Z values
            float[] xyz = new float[] {
    matrix[0]*a + matrix[3]*b + matrix[6]*c,
    matrix[1]*a + matrix[4]*b + matrix[7]*c,
    matrix[2]*a + matrix[5]*b + matrix[8]*c};
                    
            // now scale the xyz values
            xyz = matrixMult(xyz, scale, 3);
           
            // convert to RGB
            float[] rgb = ciexyzToSRGB(xyz);
           
            // cheat -- scale based on max
            for (int i = 0; i < rgb.length; i++) {
                rgb[i] = FunctionType0.interpolate(rgb[i], 0, max[i], 0, 1);
           
                // sometimes we get off a little bit due to precision loss
                if (rgb[i] > 1.0) {
                    rgb[i] = 1.0f;
                }
            }
           
            return rgb;
  } else {
      return black;
  }
    }

    /**
     * Convert from CIEXYZ, with scale and gamma calculated to sRGB
     */
    private float[] ciexyzToSRGB(float[] xyz) {
          float[] rgb = matrixMult(xyz, xyzToSRGB, 3);
         
          for (int i = 0; i < rgb.length; i++) {
              if (rgb[i] < 0.0) {
                  rgb[i] = 0f;
              } else if (rgb[i] > 1.0) {
                  rgb[i] = 1f;
              }
             
              if (rgb[i] < 0.003928) {
                  rgb[i] *= 12.92;
              } else {
                  rgb[i] = (float) ((Math.pow(rgb[i], 1.0 / 2.4) * 1.055) - 0.055);
              }
          }
         
          //float[] rgb = cieCS.toRGB(xyz);
          return rgb;
    }
   
    /**
     * convert from RGB to Calibrated RGB.  NOT IMPLEMENTED
     */
    public float[] fromRGB(float[] rgbvalue) {
  return new float[3];
    }

    /**
     * convert from CIEXYZ to Calibrated RGB.  NOT IMPLEMENTED
     */
    public float[] fromCIEXYZ(float[] colorvalue) {
  return new float[3];
    }

    /**
     * get the type of this color space (TYPE_RGB)
     */
    @Override public int getType() {
  return TYPE_RGB;
    }

    /**
     * convert from Calibrated RGB to CIEXYZ.  NOT IMPLEMENTED
     */
    public float[] toCIEXYZ(float[] colorvalue) {
  return new float[3];
    }
   
    /**
     * Slowly multiply two matrices
     *
     * @param a the first matrix
     * @param b the second matrix
     * @param len the size of each row.  All matrix lengths must be a
     *            multiple of len.
     */
    float[] matrixMult(float[] a, float[] b, int len) {
        int rows = a.length / len;
        int cols = b.length / len;
       
        float[] out = new float[rows * cols];
       
        for (int i = 0; i < rows; i++) {
            for (int k = 0; k < cols; k++) {
                for (int j = 0; j < len; j++) {
                    out[(i * cols) + k] += a[(i * len) + j] * b[(j * cols) + k];
                }
            }
        }
       
        return out;
    }
}
TOP

Related Classes of com.sun.pdfview.colorspace.CalRGBColor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.