/*
* Copyright 2006-2017 ICEsoft Technologies Canada Corp.
*
* Licensed 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.icepdf.core.pobjects.graphics;
import org.icepdf.core.pobjects.Name;
import org.icepdf.core.util.Library;
import java.awt.*;
import java.util.HashMap;
import java.util.List;
/**
* put your documentation comment here
*/
public class Lab extends PColorSpace {
public static final Name LAB_KEY = new Name("Lab");
public static final Name WHITE_POINT_KEY = new Name("WhitePoint");
public static final Name RANGE_KEY = new Name("Range");
private float[] whitePoint = {
0.95047f, 1.0f, 1.08883f
};
private float[] blackPoint = {
0f, 0f, 0f
};
private float[] range = {
-100, 100, -100, 100
};
private float lBase;
private float lSpread;
private float aBase;
private float aSpread;
private float bBase;
private float bSpread;
private float xBase;
private float xSpread;
private float yBase;
private float ySpread;
private float zBase;
private float zSpread;
/**
* @param l
* @param h
*/
Lab(Library l, HashMap h) {
super(l, h);
List v = (java.util.List) l.getObject(h, WHITE_POINT_KEY);
if (v != null) {
whitePoint[0] = ((Number) v.get(0)).floatValue();
whitePoint[1] = ((Number) v.get(1)).floatValue();
whitePoint[2] = ((Number) v.get(2)).floatValue();
}
v = (List) l.getObject(h, RANGE_KEY);
if (v != null) {
range[0] = ((Number) v.get(0)).floatValue();
range[1] = ((Number) v.get(1)).floatValue();
range[2] = ((Number) v.get(2)).floatValue();
range[3] = ((Number) v.get(3)).floatValue();
}
lBase = 0.0f;
lSpread = 100.0f;
aBase = range[0];
aSpread = range[1] - aBase;
bBase = range[2];
bSpread = range[3] - bBase;
xBase = blackPoint[0];
xSpread = whitePoint[0] - xBase;
yBase = blackPoint[1];
ySpread = whitePoint[1] - yBase;
zBase = blackPoint[2];
zSpread = whitePoint[2] - zBase;
}
/**
* @return
*/
public int getNumComponents() {
return 3;
}
/**
* @param x
* @return
*/
private double g(double x) {
if (x < 0.2069F)
x = 0.12842 * (x - 0.13793);
else
x = x * x * x;
return x;
}
private double gg(double r) {
if (r > 0.0031308)
r = 1.055 * Math.pow(r, (1.0 / 2.4)) - 0.055;
else
r *= 12.92;
return r;
}
public void normaliseComponentsToFloats(int[] in, float[] out, float maxval) {
super.normaliseComponentsToFloats(in, out, maxval);
out[2] = lBase + (lSpread * out[2]); // L
out[1] = aBase + (aSpread * out[1]); // a
out[0] = bBase + (bSpread * out[0]); // b
}
/**
* @param f
* @return
*/
public Color getColor(float[] f, boolean fillAndStroke) {
double cie_b = f[0];
double cie_a = f[1];
double cie_L = f[2];
double var_Y = (cie_L + 16.0) / (116.0);
double var_X = var_Y + (cie_a * 0.002);
double var_Z = var_Y - (cie_b * 0.005);
double X = g(var_X);
double Y = g(var_Y);
double Z = g(var_Z);
X = xBase + X * xSpread;
Y = yBase + Y * ySpread;
Z = zBase + Z * zSpread;
X = Math.max(0, Math.min(1, X));
Y = Math.max(0, Math.min(1, Y));
Z = Math.max(0, Math.min(1, Z));
/*
* Algorithm from online
double r = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
double g = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
double b = X * 0.0557 + Y * -0.2040 + Z * 1.0570;
*/
double r = X * 3.241 + Y * -1.5374 + Z * -0.4986;
double g = X * -0.9692 + Y * 1.876 + Z * 0.0416;
double b = X * 0.0556 + Y * -0.204 + Z * 1.057;
r = gg(r);
g = gg(g);
b = gg(b);
int ir = (int) (r * 255.0);
int ig = (int) (g * 255.0);
int ib = (int) (b * 255.0);
ir = Math.max(0, Math.min(255, ir));
ig = Math.max(0, Math.min(255, ig));
ib = Math.max(0, Math.min(255, ib));
return new Color(ir, ig, ib);
}
}