var colorLab = (function(space, values){
colorLab.js
(c) 2013 Stefan Huber, Signalwerk GmbH
colorLab may be freely distributed under the MIT license.
For all details and documentation:
http://colorlabjs.org
At the moment there ist just support for CIELAB Initialize the Class with
new colorLab('CIELAB', [2, 4, 6]);
or
new colorLab('CIELAB');
var colorLab = (function(space, values){
Save a reference to the global object
var root = this;
Current version of the library.
this.VERSION = '0.0.1';
constatnats
this.kK = 24389.0 / 27.0;
this.kE = 216.0 / 24389.0;
this._currentSpace = "none";
this._CIELAB = {};
this._CMYK = {};
this.helper = {};
this.helper.math = {
toDegrees: function(angle) {
return angle * (180 / Math.PI);
},
Converts numeric degrees to radians
toRad: function(num) {
return num * Math.PI / 180;
},
Convert from 0-1 to 0-255
to8bit : function(num)
{
return Math.round(Math.min(255, Math.max(0, (num*255))));
}
};
this.helper.convert = {
CIEXYZCIELAB : function(XYZ, RefWhite) {
var fHelper = function (t) {
if (t > root.kE) {
return Math.pow(t, 1.0 / 3.0);
} else {
return ((root.kK * t + 16.0) / 116.0);
}
};
var fx = fHelper(XYZ.X / RefWhite.X);
var fy = fHelper(XYZ.Y / RefWhite.Y);
var fz = fHelper(XYZ.Z / RefWhite.Z);
var Lab = {};
Lab.L = 116.0 * fy - 16.0;
Lab.a = 500.0 * (fx - fy);
Lab.b = 200.0 * (fy - fz);
return Lab;
},
XYZRGB : function(XYZ, RefMtx) {
(Observer = 2°, Illuminant = D65) Chromatic Adaptation to implement: http://www.brucelindbloom.com/index.html?WorkingSpaceInfo.html
var fHelper = function (t) {
if (t <= 0.0031308) {
return 12.92 * t;
} else {
return 1.055 * Math.pow(t, 1/2.4) - 0.055;
}
};
var RGB = {};
RGB.R = XYZ.X * RefMtx.m1 + XYZ.Y * RefMtx.m4 + XYZ.Z * RefMtx.m7;
RGB.G = XYZ.X * RefMtx.m2 + XYZ.Y * RefMtx.m5 + XYZ.Z * RefMtx.m8;
RGB.B = XYZ.X * RefMtx.m3 + XYZ.Y * RefMtx.m6 + XYZ.Z * RefMtx.m9;
RGB.R = fHelper(RGB.R);
RGB.G = fHelper(RGB.G);
RGB.B = fHelper(RGB.B);
return RGB;
},
XYZRGB8BIT : function(XYZ, RefMtx) {
(Observer = 2°, Illuminant = D65)
var RGB = root.helper.convert.XYZRGB(XYZ, RefMtx);
RGB.R = root.helper.math.to8bit(RGB.R);
RGB.G = root.helper.math.to8bit(RGB.G);
RGB.B = root.helper.math.to8bit(RGB.B);
return RGB;
}
};
this.CIELAB = {
init: function(L, a, b) {
root._CIELAB = {L:0,a:0,b:0};
this.L(L);
this.a(a);
this.b(b);
},
L: function(L) {
if (L === undefined) {
return root._CIELAB.L;
} else {
root._CIELAB.L = L;
}
},
a: function(a) {
if (a === undefined) {
return root._CIELAB.a;
} else {
root._CIELAB.a = a;
}
},
b: function(b) {
if (b === undefined) {
return root._CIELAB.b;
} else {
root._CIELAB.b = b;
}
},
add value to pint like add({x:1,y:2})
add: function(other) {
return this._fnTemplate(other, function(a, b) {return a + b;});
},
sub: function(other) {
return this._fnTemplate(other, function(a, b) {return a - b;});
},
mul: function(other) {
return this._fnTemplate(other, function(a, b) {return a * b;});
},
div: function(other) {
return this._fnTemplate(other, function(a, b) {return a / b;});
},
floor: function() {
return this._fnTemplate(null, function(a) {return Math.floor(a);});
},
round: function() {
return this._fnTemplate(null, function(a) {return Math.round(a);});
},
_fnTemplate: function(other, op) {
run function without an additional numeric imput like add(2)
if (typeof(other) === 'number') {
this.L( op(this.L(), other) );
this.a( op(this.a(), other) );
this.b( op(this.b(), other) );
return this;
}
run function without an additional imput like round()
if (other === null) {
this.L( op(this.L()) );
this.a( op(this.a()) );
this.b( op(this.b()) );
return this;
}
run function without an additional imput of type colorLab or objects add({L:2,a:3,b:2})
if (other.CIELAB === undefined) {
this.L( op(this.L(), other.L) );
} else {
this.L( op(this.L(), other.CIELAB.L()) );
}
if (other.CIELAB === undefined) {
this.a( op(this.a(), other.a) );
} else {
this.a( op(this.a(), other.CIELAB.a()) );
}
if (other.CIELAB === undefined) {
this.b( op(this.b(), other.b) );
} else {
this.b( op(this.b(), other.CIELAB.b()) );
}
return this;
},
http://lofi.forum.physorg.com/Convertion-from-nanometers-to-CIELAB-values_7984.html Tristimulus values
spectrum: function(spectralSet) {
with illuminant D !!!!!!! and 2° CIE1931
var XYZ = { X: 0.0, Y: 0.0, Z: 0.0};
var totalGet = 0;
for (var i = 0; i < spectralSet.length; i++) {
var currentNm = spectralSet[i].nm;
var accordingIlluminant = colorLab.illuminant.D.filter(function (el) {
return el.nm == currentNm;
});
look for the current illuminant-value
if (accordingIlluminant.length != 1) {
throw {
type: "data",
message: "there is no corresponding illumination value for current nm"
};
} else {
accordingIlluminant = accordingIlluminant[0];
}
look for the current Observer-value
var accordingObserver = colorLab.observer.CIE1931.filter(function (el) {
return el.nm == currentNm;
});
if (accordingObserver.length != 1) {
throw {
type: "data",
message: "there is no corresponding nm-Value in the observer-data"
};
} else {
accordingObserver = accordingObserver[0];
}
we need this to normalize the data afterwards
totalGet += accordingObserver.xyz[1]*accordingIlluminant.power;
sum up all values in the nm-array
XYZ.X += accordingObserver.xyz[0]*accordingIlluminant.power*spectralSet[i].value;
XYZ.Y += accordingObserver.xyz[1]*accordingIlluminant.power*spectralSet[i].value;
XYZ.Z += accordingObserver.xyz[2]*accordingIlluminant.power*spectralSet[i].value;
}
XYZ.X = XYZ.X / totalGet;
XYZ.Y = XYZ.Y / totalGet;
XYZ.Z = XYZ.Z / totalGet;
convert to CIELAB with D-Illuminant
var specLAB = root.helper.convert.CIEXYZCIELAB (
{ X: XYZ.X, Y: XYZ.Y, Z: XYZ.Z},
{ X: 0.96397188, Y: 1.0, Z: 0.824037097}
);
this.L( specLAB.L );
this.a( specLAB.a );
this.b( specLAB.b );
},
find deltaE of two colorLab Variables
CIEDE2000: function(newPoint) {
for more details see http://www.ece.rochester.edu/~gsharma/ciede2000/ http://www.ece.rochester.edu/~gsharma/ciede2000/ciede2000noteCRNA.pdf http://www.ece.rochester.edu/~gsharma/ciede2000/dataNprograms/deltaE2000.m http://en.wikipedia.org/wiki/Color_difference
weighting factors
var k_L = 1;
var k_C = 1;
var k_H = 1;
Input Lab pairs
var Lab1 = {
L: this.L(),
a: this.a(),
b: this.b()
};
var Lab2 = {
L: newPoint.CIELAB.L(),
a: newPoint.CIELAB.a(),
b: newPoint.CIELAB.b()
};
we calculate a C* to compensate later the for chroma
Lab1.C = Math.sqrt(Math.pow(Lab1.a, 2) + Math.pow(Lab1.b, 2));
Lab2.C = Math.sqrt(Math.pow(Lab2.a, 2) + Math.pow(Lab2.b, 2));
var C_avr = (Lab1.C + Lab2.C) / 2; // average of the two C
var G = 0.5 * (1 - Math.sqrt(Math.pow(C_avr, 7) / (Math.pow(C_avr, 7) + Math.pow(25, 7))));
Lab1.a_1 = (1 + G) * Lab1.a;
Lab2.a_1 = (1 + G) * Lab2.a;
Lab1.C_1 = Math.sqrt(Math.pow(Lab1.a_1, 2) + Math.pow(Lab1.b, 2));
Lab2.C_1 = Math.sqrt(Math.pow(Lab2.a_1, 2) + Math.pow(Lab2.b, 2));
if (Lab1.a_1 === 0 && Lab1.b === 0) {
Lab1.h = 0;
} else {
if (Lab1.b >= 0) {
Lab1.h = root.helper.math.toDegrees(Math.atan2(Lab1.b, Lab1.a_1));
} else {
Lab1.h = root.helper.math.toDegrees(Math.atan2(Lab1.b, Lab1.a_1)) + 360;
}
}
if (Lab2.a_1 === 0 && Lab2.b === 0) {
Lab2.h = 0;
} else {
if (Lab2.b >= 0) {
Lab2.h = root.helper.math.toDegrees(Math.atan2(Lab2.b, Lab2.a_1));
} else {
Lab2.h = root.helper.math.toDegrees(Math.atan2(Lab2.b, Lab2.a_1)) + 360;
}
}
console.log("Lab1.h",Lab1.h); console.log("Lab2.h",Lab2.h);
Now calculate the signed differences in lightness, chroma, and hue
get the delta h and delta H
var deltah;
if ( ( Lab1.C_1 * Lab2.C_1 ) === 0 ) {
deltah = 0;
} else {
if ( Math.abs( Lab2.h - Lab1.h ) <= 180 ) {
deltah = Lab2.h - Lab1.h;
} else {
if ( Lab2.h - Lab1.h > 180 ) {
deltah = Lab2.h - Lab1.h - 360;
} else {
deltah = Lab2.h - Lab1.h + 360;
}
}
}
var deltaH = 2 * Math.sqrt( Lab1.C_1 * Lab2.C_1 ) * Math.sin( root.helper.math.toRad( deltah / 2 ) );
var deltaL = Lab1.L - Lab2.L;
var deltaC = Lab2.C_1 - Lab1.C_1;
var L_ave = (Lab1.L + Lab2.L) / 2;
var C_1ave = (Lab1.C_1 + Lab2.C_1) / 2;
console.log("L_ave", L_ave); console.log("C_1ave", C_1ave);
var hDiff;
if ( ( Lab1.C_1 * Lab2.C_1 ) === 0 ) {
hDiff = Lab1.h + Lab2.h;
} else {
if ( Math.abs( Lab2.h - Lab1.h ) > 180 ) {
if ( ( Lab2.h + Lab1.h ) < 360 ) {
hDiff = Lab1.h + Lab2.h + 360;
} else {
hDiff = Lab1.h + Lab2.h - 360;
}
} else {
hDiff = Lab1.h + Lab2.h ;
}
hDiff = hDiff / 2;
}
console.log("hDiff", hDiff);
var L_aveMinus50pow2 = Math.pow((L_ave - 50), 2);
console.log("L_aveMinus50pow2", L_aveMinus50pow2);
var SL = 1 + ((0.015 * L_aveMinus50pow2) / Math.sqrt(20 + L_aveMinus50pow2));
console.log("SL", SL);
var SC = 1 + 0.045 * C_1ave;
console.log("SC", SC);
var T = 1 - 0.17 * Math.cos( root.helper.math.toRad( hDiff - 30 ) ) + 0.24 * Math.cos( root.helper.math.toRad( 2 * hDiff ) ) + 0.32 * Math.cos( root.helper.math.toRad( 3 * hDiff + 6 ) ) - 0.20 * Math.cos( root.helper.math.toRad( 4 * hDiff - 63 ) );
console.log("T", T);
var SH = 1 + 0.015 * C_1ave * T;
console.log("SH", SH);
var dTheta = 30 * Math.exp(-1 * Math.pow((hDiff - 275 ) / 25, 2));
console.log("dTheta", dTheta);
var RC = 2 * Math.sqrt(Math.pow(C_1ave, 7) / (Math.pow(C_1ave, 7) + Math.pow(25, 7)));
console.log("RC", RC);
var RT = 0 - Math.sin(root.helper.math.toRad( 2 * dTheta)) * RC;
console.log("RT", RT);
var dkL = deltaL / (k_L * SL);
var dkC = deltaC / (k_C * SC);
var dkH = deltaH / (k_H * SH);
console.log("dkL", dkL); console.log("dkC", dkC); console.log("dkH", dkH);
var CIEDE2000 = Math.sqrt(Math.pow(dkL, 2) + Math.pow(dkC, 2) + Math.pow(dkH, 2) + RT * dkC * dkH );
console.log("CIEDE2000", CIEDE2000);
return CIEDE2000;
},
toArray: function() {
return [this.L(), this.a(), this.b()];
},
plot the Lab-Values
toString: function() {
return 'L: ' + this.L() + ', a: ' + this.a() + ', b: ' + this.b();
},
shorthand for toString
print: function() {
return this.toString();
}
};
this.CMYK = {
init: function(C, M, Y, K) {
root._CMYK = {C:0,M:0,Y:0,K:0};
this.C(C);
this.M(M);
this.Y(Y);
this.K(K);
},
C: function(C) {
if (C === undefined) {
return root._CMYK.C;
} else {
root._CMYK.C = C;
}
},
M: function(M) {
if (M === undefined) {
return root._CMYK.M;
} else {
root._CMYK.M = M;
}
},
Y: function(Y) {
if (Y === undefined) {
return root._CMYK.Y;
} else {
root._CMYK.Y = Y;
}
},
K: function(K) {
if (K === undefined) {
return root._CMYK.K;
} else {
root._CMYK.K = K;
}
},
add value to pint like add({x:1,y:2})
add: function(other) {
return this._fnTemplate(other, function(a, b) {return a + b;});
},
sub: function(other) {
return this._fnTemplate(other, function(a, b) {return a - b;});
},
mul: function(other) {
return this._fnTemplate(other, function(a, b) {return a * b;});
},
div: function(other) {
return this._fnTemplate(other, function(a, b) {return a / b;});
},
floor: function() {
return this._fnTemplate(null, function(a) {return Math.floor(a);});
},
round: function() {
return this._fnTemplate(null, function(a) {return Math.round(a);});
},
_fnTemplate: function(other, op) {
run function without an additional numeric imput like add(2)
if (typeof(other) === 'number') {
this.C( op(this.C(), other) );
this.M( op(this.M(), other) );
this.Y( op(this.Y(), other) );
this.K( op(this.K(), other) );
return this;
}
run function without an additional imput like round()
if (other === null) {
this.C( op(this.C()) );
this.M( op(this.M()) );
this.Y( op(this.Y()) );
this.K( op(this.K()) );
return this;
}
run function without an additional imput of type colorLab or objects add({L:2,a:3,b:2})
if (other.CMYK === undefined) {
this.C( op(this.C(), other.C) );
} else {
this.C( op(this.C(), other.CMYK.C()) );
}
if (other.CMYK === undefined) {
this.M( op(this.M(), other.M) );
} else {
this.M( op(this.M(), other.CMYK.M()) );
}
if (other.CMYK === undefined) {
this.Y( op(this.Y(), other.Y) );
} else {
this.Y( op(this.Y(), other.CMYK.Y()) );
}
if (other.CMYK === undefined) {
this.K( op(this.K(), other.K) );
} else {
this.K( op(this.K(), other.CMYK.K()) );
}
return this;
},
toArray: function() {
return [this.C(), this.M(), this.Y(), this.K()];
},
plot the Color-Values
toString: function() {
return 'C: ' + this.C() + ', M: ' + this.M() + ', Y: ' + this.Y() + ', K: ' + this.K();
},
shorthand for toString
print: function() {
return this.toString();
}
};
if (space !== undefined) {
switch (space)
{
case 'CIELAB':
this._currentSpace = space;
if (values === undefined) {
this.CIELAB.init(0,0,0);
} else {
this.CIELAB.init(values[0], values[1], values[2]);
}
break;
case 'CMYK':
this._currentSpace = space;
if (values === undefined) {
this.CMYK.init(0,0,0,0);
} else {
this.CMYK.init(values[0], values[1], values[2], values[3]);
}
break;
default:
throw {
type: "implementation",
message: "at the moment you can just use CIELAB-Colorspce."
};
}
}
});
/*
github-page >> http://ricostacruz.com/flatdoc/
function linearInterpolation(min, max, k) {
return min + (max - min) * k;
}
http://bl.ocks.org/mbostock/4281513
http://bl.ocks.org/mbostock/3014589
dont mix colors in lab!! mix in xyz!!!
*/
D65
colorLab.XYZ2RGBMtx = {
CIED65 : {
AdobeRGB : {name: 'Adobe RGB (1998)', m1: 2.04148, m2:-0.969258, m3:0.0134455, m4:-0.564977, m5:1.87599, m6:-0.118373, m7:-0.344713, m8:0.0415557, m9:1.01527, gamma:2.2},
AppleRGB : {name: 'Apple RGB', m1: 2.95176, m2:-1.0851, m3:0.0854804, m4:-1.28951, m5:1.99084, m6:-0.269456, m7:-0.47388, m8:0.0372023, m9:1.09113, gamma:1.8},
ECIRGB : {name: 'ECI RGB', m1: 1.78276, m2:-0.959362, m3:0.0859318, m4:-0.496985, m5:1.9478, m6:-0.174467, m7:-0.26901, m8:-0.0275807, m9:1.32283, gamma:1.8},
sRGB : {name: 'sRGB', m1: 3.24071, m2:-0.969258, m3:0.0556352, m4:-1.53726, m5:1.87599, m6:-0.203996, m7:-0.498571, m8:0.0415557, m9:1.05707, gamma:2.4}
}
};
Relative spectral power distribution of CIE Standard Illuminant D65 Source: http://www.cie.co.at/publ/abst/datatables15_2004/CIE_sel_colorimetric_tables.xls
colorLab.illuminant = {
CIED65 : [
{nm: 300, power: 0.0341},
{nm: 305, power: 1.6643},
{nm: 310, power: 3.2945},
{nm: 315, power: 11.7652},
{nm: 320, power: 20.236},
{nm: 325, power: 28.6447},
{nm: 330, power: 37.0535},
{nm: 335, power: 38.5011},
{nm: 340, power: 39.9488},
{nm: 345, power: 42.4302},
{nm: 350, power: 44.9117},
{nm: 355, power: 45.775},
{nm: 360, power: 46.6383},
{nm: 365, power: 49.3637},
{nm: 370, power: 52.0891},
{nm: 375, power: 51.0323},
{nm: 380, power: 49.9755},
{nm: 385, power: 52.3118},
{nm: 390, power: 54.6482},
{nm: 395, power: 68.7015},
{nm: 400, power: 82.7549},
{nm: 405, power: 87.1204},
{nm: 410, power: 91.486},
{nm: 415, power: 92.4589},
{nm: 420, power: 93.4318},
{nm: 425, power: 90.057},
{nm: 430, power: 86.6823},
{nm: 435, power: 95.7736},
{nm: 440, power: 104.865},
{nm: 445, power: 110.936},
{nm: 450, power: 117.008},
{nm: 455, power: 117.41},
{nm: 460, power: 117.812},
{nm: 465, power: 116.336},
{nm: 470, power: 114.861},
{nm: 475, power: 115.392},
{nm: 480, power: 115.923},
{nm: 485, power: 112.367},
{nm: 490, power: 108.811},
{nm: 495, power: 109.082},
{nm: 500, power: 109.354},
{nm: 505, power: 108.578},
{nm: 510, power: 107.802},
{nm: 515, power: 106.296},
{nm: 520, power: 104.79},
{nm: 525, power: 106.239},
{nm: 530, power: 107.689},
{nm: 535, power: 106.047},
{nm: 540, power: 104.405},
{nm: 545, power: 104.225},
{nm: 550, power: 104.046},
{nm: 555, power: 102.023},
{nm: 560, power: 100},
{nm: 565, power: 98.1671},
{nm: 570, power: 96.3342},
{nm: 575, power: 96.0611},
{nm: 580, power: 95.788},
{nm: 585, power: 92.2368},
{nm: 590, power: 88.6856},
{nm: 595, power: 89.3459},
{nm: 600, power: 90.0062},
{nm: 605, power: 89.8026},
{nm: 610, power: 89.5991},
{nm: 615, power: 88.6489},
{nm: 620, power: 87.6987},
{nm: 625, power: 85.4936},
{nm: 630, power: 83.2886},
{nm: 635, power: 83.4939},
{nm: 640, power: 83.6992},
{nm: 645, power: 81.863},
{nm: 650, power: 80.0268},
{nm: 655, power: 80.1207},
{nm: 660, power: 80.2146},
{nm: 665, power: 81.2462},
{nm: 670, power: 82.2778},
{nm: 675, power: 80.281},
{nm: 680, power: 78.2842},
{nm: 685, power: 74.0027},
{nm: 690, power: 69.7213},
{nm: 695, power: 70.6652},
{nm: 700, power: 71.6091},
{nm: 705, power: 72.979},
{nm: 710, power: 74.349},
{nm: 715, power: 67.9765},
{nm: 720, power: 61.604},
{nm: 725, power: 65.7448},
{nm: 730, power: 69.8856},
{nm: 735, power: 72.4863},
{nm: 740, power: 75.087},
{nm: 745, power: 69.3398},
{nm: 750, power: 63.5927},
{nm: 755, power: 55.0054},
{nm: 760, power: 46.4182},
{nm: 765, power: 56.6118},
{nm: 770, power: 66.8054},
{nm: 775, power: 65.0941},
{nm: 780, power: 63.3828},
{nm: 785, power: 63.8434},
{nm: 790, power: 64.304},
{nm: 795, power: 61.8779},
{nm: 800, power: 59.4519},
{nm: 805, power: 55.7054},
{nm: 810, power: 51.959},
{nm: 815, power: 54.6998},
{nm: 820, power: 57.4406},
{nm: 825, power: 58.8765},
{nm: 830, power: 60.3125}
],
D : [
{nm: 340, power: 17.92},
{nm: 350, power: 20.98},
{nm: 360, power: 23.91},
{nm: 370, power: 25.89},
{nm: 380, power: 24.45},
{nm: 390, power: 29.83},
{nm: 400, power: 49.25},
{nm: 410, power: 56.45},
{nm: 420, power: 59.97},
{nm: 430, power: 57.76},
{nm: 440, power: 74.77},
{nm: 450, power: 87.19},
{nm: 460, power: 90.56},
{nm: 470, power: 91.32},
{nm: 480, power: 95.07},
{nm: 490, power: 91.93},
{nm: 500, power: 95.70},
{nm: 510, power: 96.59},
{nm: 520, power: 97.11},
{nm: 530, power: 102.09},
{nm: 540, power: 100.75},
{nm: 550, power: 102.31},
{nm: 560, power: 100.00},
{nm: 570, power: 97.74},
{nm: 580, power: 98.92},
{nm: 590, power: 93.51},
{nm: 600, power: 97.71},
{nm: 610, power: 99.29},
{nm: 620, power: 99.07},
{nm: 630, power: 95.75},
{nm: 640, power: 98.90},
{nm: 650, power: 95.71},
{nm: 660, power: 98.24},
{nm: 670, power: 103.06},
{nm: 680, power: 99.19},
{nm: 690, power: 87.43},
{nm: 700, power: 91.66},
{nm: 710, power: 92.94},
{nm: 720, power: 76.89},
{nm: 730, power: 86.56},
{nm: 740, power: 92.63},
{nm: 750, power: 78.27},
{nm: 760, power: 57.72},
{nm: 770, power: 82.97},
{nm: 780, power: 78.31},
{nm: 790, power: 79.59},
{nm: 800, power: 73.44},
{nm: 810, power: 63.95},
{nm: 820, power: 70.81},
{nm: 830, power: 74.48}
]
};
1931 2° CIE Standard Colorimetric Observer Data 1964 10 °CIE Standard Colorimetric Observer Data
colorLab.observer = {
CIE1964 : [
{nm: 380, xyz: [0.00016,0.000017,0.000705]},
{nm: 385, xyz: [0.000662,0.000072,0.002928]},
{nm: 390, xyz: [0.002362,0.000253,0.010482]},
{nm: 395, xyz: [0.007242,0.000769,0.032344]},
{nm: 400, xyz: [0.01911,0.002004,0.086011]},
{nm: 405, xyz: [0.0434,0.004509,0.19712]},
{nm: 410, xyz: [0.084736,0.008756,0.389366]},
{nm: 415, xyz: [0.140638,0.014456,0.65676]},
{nm: 420, xyz: [0.204492,0.021391,0.972542]},
{nm: 425, xyz: [0.264737,0.029497,1.2825]},
{nm: 430, xyz: [0.314679,0.038676,1.55348]},
{nm: 435, xyz: [0.357719,0.049602,1.7985]},
{nm: 440, xyz: [0.383734,0.062077,1.96728]},
{nm: 445, xyz: [0.386726,0.074704,2.0273]},
{nm: 450, xyz: [0.370702,0.089456,1.9948]},
{nm: 455, xyz: [0.342957,0.106256,1.9007]},
{nm: 460, xyz: [0.302273,0.128201,1.74537]},
{nm: 465, xyz: [0.254085,0.152761,1.5549]},
{nm: 470, xyz: [0.195618,0.18519,1.31756]},
{nm: 475, xyz: [0.132349,0.21994,1.0302]},
{nm: 480, xyz: [0.080507,0.253589,0.772125]},
{nm: 485, xyz: [0.041072,0.297665,0.57006]},
{nm: 490, xyz: [0.016172,0.339133,0.415254]},
{nm: 495, xyz: [0.005132,0.395379,0.302356]},
{nm: 500, xyz: [0.003816,0.460777,0.218502]},
{nm: 505, xyz: [0.015444,0.53136,0.159249]},
{nm: 510, xyz: [0.037465,0.606741,0.112044]},
{nm: 515, xyz: [0.071358,0.68566,0.082248]},
{nm: 520, xyz: [0.117749,0.761757,0.060709]},
{nm: 525, xyz: [0.172953,0.82333,0.04305]},
{nm: 530, xyz: [0.236491,0.875211,0.030451]},
{nm: 535, xyz: [0.304213,0.92381,0.020584]},
{nm: 540, xyz: [0.376772,0.961988,0.013676]},
{nm: 545, xyz: [0.451584,0.9822,0.007918]},
{nm: 550, xyz: [0.529826,0.991761,0.003988]},
{nm: 555, xyz: [0.616053,0.99911,0.001091]},
{nm: 560, xyz: [0.705224,0.99734,0]},
{nm: 565, xyz: [0.793832,0.98238,0]},
{nm: 570, xyz: [0.878655,0.955552,0]},
{nm: 575, xyz: [0.951162,0.915175,0]},
{nm: 580, xyz: [1.01416,0.868934,0]},
{nm: 585, xyz: [1.0743,0.825623,0]},
{nm: 590, xyz: [1.11852,0.777405,0]},
{nm: 595, xyz: [1.1343,0.720353,0]},
{nm: 600, xyz: [1.12399,0.658341,0]},
{nm: 605, xyz: [1.0891,0.593878,0]},
{nm: 610, xyz: [1.03048,0.527963,0]},
{nm: 615, xyz: [0.95074,0.461834,0]},
{nm: 620, xyz: [0.856297,0.398057,0]},
{nm: 625, xyz: [0.75493,0.339554,0]},
{nm: 630, xyz: [0.647467,0.283493,0]},
{nm: 635, xyz: [0.53511,0.228254,0]},
{nm: 640, xyz: [0.431567,0.179828,0]},
{nm: 645, xyz: [0.34369,0.140211,0]},
{nm: 650, xyz: [0.268329,0.107633,0]},
{nm: 655, xyz: [0.2043,0.081187,0]},
{nm: 660, xyz: [0.152568,0.060281,0]},
{nm: 665, xyz: [0.11221,0.044096,0]},
{nm: 670, xyz: [0.081261,0.0318,0]},
{nm: 675, xyz: [0.05793,0.022602,0]},
{nm: 680, xyz: [0.040851,0.015905,0]},
{nm: 685, xyz: [0.028623,0.01113,0]},
{nm: 690, xyz: [0.019941,0.007749,0]},
{nm: 695, xyz: [0.013842,0.005375,0]},
{nm: 700, xyz: [0.009577,0.003718,0]},
{nm: 705, xyz: [0.006605,0.002565,0]},
{nm: 710, xyz: [0.004553,0.001768,0]},
{nm: 715, xyz: [0.003145,0.001222,0]},
{nm: 720, xyz: [0.002175,0.000846,0]},
{nm: 725, xyz: [0.001506,0.000586,0]},
{nm: 730, xyz: [0.001045,0.000407,0]},
{nm: 735, xyz: [0.000727,0.000284,0]},
{nm: 740, xyz: [0.000508,0.000199,0]},
{nm: 745, xyz: [0.000356,0.00014,0]},
{nm: 750, xyz: [0.000251,0.000098,0]},
{nm: 755, xyz: [0.000178,0.00007,0]},
{nm: 760, xyz: [0.000126,0.00005,0]},
{nm: 765, xyz: [0.00009,0.000036,0]},
{nm: 770, xyz: [0.000065,0.000025,0]},
{nm: 775, xyz: [0.000046,0.000018,0]},
{nm: 780, xyz: [0.000033,0.000013,0]}
],
CIE1931 : [
{nm: 380, xyz: [0.001368,0.000039,0.00645]},
{nm: 385, xyz: [0.002236,0.000064,0.01055]},
{nm: 390, xyz: [0.004243,0.00012,0.02005]},
{nm: 395, xyz: [0.00765,0.000217,0.03621]},
{nm: 400, xyz: [0.01431,0.000396,0.06785]},
{nm: 405, xyz: [0.02319,0.00064,0.1102]},
{nm: 410, xyz: [0.04351,0.00121,0.2074]},
{nm: 415, xyz: [0.07763,0.00218,0.3713]},
{nm: 420, xyz: [0.13438,0.004,0.6456]},
{nm: 425, xyz: [0.21477,0.0073,1.03905]},
{nm: 430, xyz: [0.2839,0.0116,1.3856]},
{nm: 435, xyz: [0.3285,0.01684,1.62296]},
{nm: 440, xyz: [0.34828,0.023,1.74706]},
{nm: 445, xyz: [0.34806,0.0298,1.7826]},
{nm: 450, xyz: [0.3362,0.038,1.77211]},
{nm: 455, xyz: [0.3187,0.048,1.7441]},
{nm: 460, xyz: [0.2908,0.06,1.6692]},
{nm: 465, xyz: [0.2511,0.0739,1.5281]},
{nm: 470, xyz: [0.19536,0.09098,1.28764]},
{nm: 475, xyz: [0.1421,0.1126,1.0419]},
{nm: 480, xyz: [0.09564,0.13902,0.81295]},
{nm: 485, xyz: [0.05795,0.1693,0.6162]},
{nm: 490, xyz: [0.03201,0.20802,0.46518]},
{nm: 495, xyz: [0.0147,0.2586,0.3533]},
{nm: 500, xyz: [0.0049,0.323,0.272]},
{nm: 505, xyz: [0.0024,0.4073,0.2123]},
{nm: 510, xyz: [0.0093,0.503,0.1582]},
{nm: 515, xyz: [0.0291,0.6082,0.1117]},
{nm: 520, xyz: [0.06327,0.71,0.07825]},
{nm: 525, xyz: [0.1096,0.7932,0.05725]},
{nm: 530, xyz: [0.1655,0.862,0.04216]},
{nm: 535, xyz: [0.22575,0.91485,0.02984]},
{nm: 540, xyz: [0.2904,0.954,0.0203]},
{nm: 545, xyz: [0.3597,0.9803,0.0134]},
{nm: 550, xyz: [0.43345,0.99495,0.00875]},
{nm: 555, xyz: [0.51205,1,0.00575]},
{nm: 560, xyz: [0.5945,0.995,0.0039]},
{nm: 565, xyz: [0.6784,0.9786,0.00275]},
{nm: 570, xyz: [0.7621,0.952,0.0021]},
{nm: 575, xyz: [0.8425,0.9154,0.0018]},
{nm: 580, xyz: [0.9163,0.87,0.00165]},
{nm: 585, xyz: [0.9786,0.8163,0.0014]},
{nm: 590, xyz: [1.0263,0.757,0.0011]},
{nm: 595, xyz: [1.0567,0.6949,0.001]},
{nm: 600, xyz: [1.0622,0.631,0.0008]},
{nm: 605, xyz: [1.0456,0.5668,0.0006]},
{nm: 610, xyz: [1.0026,0.503,0.00034]},
{nm: 615, xyz: [0.9384,0.4412,0.00024]},
{nm: 620, xyz: [0.85445,0.381,0.00019]},
{nm: 625, xyz: [0.7514,0.321,0.0001]},
{nm: 630, xyz: [0.6424,0.265,0.00005]},
{nm: 635, xyz: [0.5419,0.217,0.00003]},
{nm: 640, xyz: [0.4479,0.175,0.00002]},
{nm: 645, xyz: [0.3608,0.1382,0.00001]},
{nm: 650, xyz: [0.2835,0.107,0]},
{nm: 655, xyz: [0.2187,0.0816,0]},
{nm: 660, xyz: [0.1649,0.061,0]},
{nm: 665, xyz: [0.1212,0.04458,0]},
{nm: 670, xyz: [0.0874,0.032,0]},
{nm: 675, xyz: [0.0636,0.0232,0]},
{nm: 680, xyz: [0.04677,0.017,0]},
{nm: 685, xyz: [0.0329,0.01192,0]},
{nm: 690, xyz: [0.0227,0.00821,0]},
{nm: 695, xyz: [0.01584,0.005723,0]},
{nm: 700, xyz: [0.011359,0.004102,0]},
{nm: 705, xyz: [0.008111,0.002929,0]},
{nm: 710, xyz: [0.00579,0.002091,0]},
{nm: 715, xyz: [0.004109,0.001484,0]},
{nm: 720, xyz: [0.002899,0.001047,0]},
{nm: 725, xyz: [0.002049,0.00074,0]},
{nm: 730, xyz: [0.00144,0.00052,0]},
{nm: 735, xyz: [0.001,0.000361,0]},
{nm: 740, xyz: [0.00069,0.000249,0]},
{nm: 745, xyz: [0.000476,0.000172,0]},
{nm: 750, xyz: [0.000332,0.00012,0]},
{nm: 755, xyz: [0.000235,0.000085,0]},
{nm: 760, xyz: [0.000166,0.00006,0]},
{nm: 765, xyz: [0.000117,0.000042,0]},
{nm: 770, xyz: [0.000083,0.00003,0]},
{nm: 775, xyz: [0.000059,0.000021,0]},
{nm: 780, xyz: [0.000042,0.000015,0]}
]
};
/* Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
* MIT Licensed.
*/
Inspired by base2 and Prototype
(function(){
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
The base Class implementation (does nothing)
this.Class = function(){};
Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;
Instantiate a base class (but only create the instance, don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
Copy the properties over onto the new prototype
for (var name in prop) {
Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
return function() {
var tmp = this._super;
Add a new ._super() method that is the same method but on the super-class
this._super = _super[name];
The method only need to be bound temporarily, so we remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) :
prop[name];
}
The dummy class constructor
function Class() {
All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}
Populate our constructed prototype object
Class.prototype = prototype;
Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
And make this class extendable
Class.extend = arguments.callee;
return Class;
};
})();