rawTherapee/rtengine/colortemp.cc

2441 lines
128 KiB
C++
Raw Blame History

/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "colortemp.h"
#include "iccmatrices.h"
#include "rtengine.h"
#include "improcfun.h"
#include "curves.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "mytime.h"
#include "sleef.c"
#include "../rtgui/options.h"
#undef CLIPD
#define CLIPD(a) ((a)>0.0?((a)<1.0?(a):1.0):0.0)
#define CLIPQQ(a) ((a)>0?((a)<250?(a):250):0)
#define MAXR(a,b) ((a) > (b) ? (a) : (b))
namespace rtengine {
using namespace procparams;
extern const Settings* settings;
static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis observer 2<>
{0.0000000,0.000000,0.000000}, {0.0000000,0.000000,0.000000}, {0.0001299,0.0003917,0.0006061},
{0.0002321,0.000006965,0.001086}, {0.0004149,0.00001239,0.001946}, {0.0007416,0.00002202,0.003846},
{0.001368,0.000039,0.006450001}, {0.002236,0.000064,0.01054999}, {0.004243,0.000120,0.02005001},
{0.007650,0.000217,0.036210}, {0.014310,0.000396,0.06785001}, {0.023190,0.000640,0.110200},
{0.043510,0.001210,0.207400}, {0.077630,0.002180,0.371300}, {0.134380,0.004000,0.645600},
{0.214770,0.007300,1.0390501}, {0.283900,0.011600,1.385600}, {0.328500,0.016840,1.622960},
{0.348280,0.023000,1.747060}, {0.348060,0.029800,1.782600}, {0.336200,0.038000,1.772110},
{0.318700,0.048000,1.744100}, {0.290800,0.060000,1.669200}, {0.251100,0.073900,1.528100},
{0.195360,0.090980,1.287640}, {0.142100,0.112600,1.041900}, {0.095640,0.139020,0.8129501},
{0.05795001,0.169300,0.616200}, {0.032010,0.208020,0.465180}, {0.014700,0.258600,0.353300},
{0.004900,0.323000,0.272000}, {0.002400,0.407300,0.212300}, {0.009300,0.503000,0.158200},
{0.029100,0.608200,0.111700}, {0.063270,0.710000,0.07824999}, {0.109600,0.793200,0.05725001},
{0.165500,0.862000,0.042160}, {0.2257499,0.9148501,0.029840}, {0.290400,0.954000,0.020300},
{0.359700,0.980300,0.013400}, {0.43344990,0.9949501,0.008749999}, {0.5120501,1.000000,0.005749999},
{0.594500,0.995000,0.003900}, {0.678400,0.978600,0.002749999}, {0.762100,0.952000,0.002100},
{0.842500,0.915400,0.001800}, {0.916300,0.870000,0.001650001}, {0.978600,0.816300,0.001400},
{1.026300,0.757000,0.001100}, {1.056700,0.694900,0.001000}, {1.062200,0.631000,0.000800},
{1.045600,0.566800,0.000600}, {1.002600,0.503000,0.000340}, {0.938400,0.441200,0.000240},
{0.8544499,0.381000,0.000190}, {0.751400,0.321000,0.000100}, {0.642400,0.265000,0.00004999999},
{0.541900,0.217000,0.000030}, {0.447900,0.175000,0.000020}, {0.360800,0.138200,0.000010},
{0.283500,0.107000,0.000000}, {0.218700,0.081600,0.000000}, {0.164900,0.061000,0.000000},
{0.121200,0.044580,0.000000}, {0.087400,0.032000,0.000000}, {0.063600,0.023200,0.000000},
{0.046770,0.017000,0.000000}, {0.032900,0.011920,0.000000}, {0.022700,0.008210,0.000000},
{0.015840,0.005723,0.000000}, {0.01135916,0.004102,0.000000}, {0.008110916,0.002929,0.000000},
{0.005790346,0.002091,0.000000}, {0.004109457,0.001484,0.000000}, {0.002899327,0.001047,0.000000},
{0.00204919,0.000740,0.000000}, {0.001439971,0.000520,0.000000}, {0.0009999493,0.0003611,0.000000},
{0.0006900786,0.0002492,0.000000}, {0.0004760213,0.0001719,0.000000}, {0.0003323011,0.000120,0.000000},
{0.0002348261,0.0000848,0.000000}, {0.0001661505,0.000060,0.000000}, {0.000117413,0.0000424,0.000000},
{0.00008307527,0.000030,0.000000}, {0.00005870652,0.0000212,0.000000}, {0.00004150994,0.00001499,0.000000},
{0.00002935326,0.0000106,0.000000}, {0.00002067383,0.0000074657,0.000000}, {0.00001455977,0.0000052578,0.000000},
{0.00001025398,0.0000037029,0.000000}, {0.000007221456,0.00000260778,0.000000}, {0.000005085868,0.0000018366,0.000000},
{0.000003581652,0.0000012934,0.000000}, {0.000002522525,0.00000091093,0.000000}, {0.000001776509,0.00000064153,0.000000},
{0.000001251141,0.00000045181,0.000000}
};
ColorTemp::ColorTemp (double t, double g, double e, Glib::ustring m) : temp(t), green(g), equal(e), method(m) {
clip (temp, green, equal);
}
void ColorTemp::clip (double &temp, double &green) {
if (temp < MINTEMP)
temp = MINTEMP;
else if (temp > MAXTEMP)
temp = MAXTEMP;
if (green < MINGREEN)
green = MINGREEN;
else if (green > MAXGREEN)
green = MAXGREEN;
}
void ColorTemp::clip (double &temp, double &green, double &equal) {
if (temp < MINTEMP)
temp = MINTEMP;
else if (temp > MAXTEMP)
temp = MAXTEMP;
if (green < MINGREEN)
green = MINGREEN;
else if (green > MAXGREEN)
green = MAXGREEN;
if(equal < MINEQUAL)
equal = MINEQUAL;
else if(equal > MAXEQUAL)
equal = MAXEQUAL;
}
ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e) {
method = "Custom";
mul2temp (mulr, mulg, mulb, equal, temp, green);
}
void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green) {
double maxtemp=double(MAXTEMP), mintemp=double(MINTEMP);
double tmpr, tmpg, tmpb;
temp=(maxtemp+mintemp)/2;
while (maxtemp-mintemp>1) {
temp2mul (temp, 1.0, equal, tmpr, tmpg, tmpb);
if (tmpb/tmpr > bmul/rmul)
maxtemp = temp;
else
mintemp = temp;
temp=(maxtemp+mintemp)/2;
}
green = (tmpg/tmpr) / (gmul/rmul);
clip (temp, green);
}
// spectral data for Daylight direct Sun: I have choose 5300K because Nikon=5200K, Olympus=5300K, Panasonic=5500K, Leica=5400K, Minolta=5100K
const double ColorTemp::Daylight5300_spect[97] = {
24.82,26.27,27.72,28.97,30.22,29.71,29.19,31.95,34.71,45.49,56.26,59.97,63.68,65.30,66.92,65.39,63.86,72.59,81.32,87.53,93.73,95.15,96.56,96.55,96.54,98.13,99.73,97.70,95.66,97.19,98.72,
98.90,99.08,98.98,98.87,101.13,103.39,102.48,101.57,102.14,102.71,101.36,100.00,98.71,97.42,97.81,98.21,95.20,92.20,93.92,95.63,96.15,96.67,96.34,96.01,94.21,92.41,93.58,94.74,93.05,91.36,92.29,
93.21,95.25,97.28,95.30,93.32,87.92,82.51,84.29,86.06,86.94,87.81,80.24,72.68,77.32,81.96,84.88,87.79,81.01,74.22,64.41,54.60,66.55,78.51,76.35,74.20,74.79,75.38,72.48,69.58,65.11,60.64,
63.88,67.13,68.85,70.57
};
//spectral data for Daylight Cloudy: I have choose 6200K because Nikon=6000K, Olympus=6000K, Panasonic=6200K, Leica=6400K, Minolta=6500K
const double ColorTemp::Cloudy6200_spect[97] = {
39.50,40.57,41.63,43.85,46.08,45.38,44.69,47.20,49.71,63.06,76.41,80.59,84.77,85.91,87.05,84.14,81.23,90.29,99.35,105.47,111.58,112.23,112.87,111.74,110.62,111.41,112.20,108.98,105.76,106.32,
106.89,106.34,105.79,104.62,103.45,105.09,106.72,105.24,103.76,103.75,103.75,101.87,100.00,98.29,96.58,96.46,96.34,92.85,89.37,90.25,91.12,91.06,90.99,90.17,89.35,87.22,85.10,85.48,85.85,
84.03,82.20,82.45,82.69,83.92,85.15,83.14,81.13,76.65,72.17,73.27,74.36,75.65,76.95,70.34,63.74,67.98,72.22,74.88,77.54,71.59,65.65,56.82,47.99,58.53,69.06,67.27,65.47,65.96,66.44,63.92,61.41,57.52,
53.63,56.47,59.31,60.80,62.29
};
//spectral data for Daylight Shade: I have choose 7600K because Nikon=8000K, Olympus=7500K, Panasonic=7500K, Leica=7500K, Minolta=7500K
const double ColorTemp::Shade7600_spect[97] = {
64.42,64.46,64.51,68.35,72.20,70.22,68.24,69.79,71.35,87.49,103.64,108.68,113.72,114.12,114.53,109.54,104.55,113.59,122.63,128.52,134.41,134.02,133.63,131.02,128.41,128.08,127.75,123.16,
118.57,117.89,117.22,115.72,114.22,111.60,108.99,109.84,110.68,108.57,106.45,105.71,104.98,102.49,100.00,97.78,95.55,94.82,94.08,90.47,86.87,86.94,87.01,86.45,85.88,84.57,83.27,80.83,78.40,78.21,
78.03,76.22,74.42,74.15,73.89,74.41,74.92,73.01,71.09,67.26,63.42,64.01,64.60,66.10,67.60,61.83,56.06,59.94,63.82,66.27,68.71,63.49,58.26,50.30,42.34,51.64,60.95,59.45,57.95,58.35,58.76,56.57,
54.38,51.00,47.62,50.10,52.58,53.88,55.19
};
//spectral data for tungsten - incandescent 2856K
const double ColorTemp::A2856_spect[97] = {
4.75,5.42,6.15,6.95,7.83,8.78,9.80,10.91,12.09,13.36,14.72,16.16,17.69,19.30,21.01,22.80,24.68,26.65,28.71,30.86,33.10,35.42,37.82,40.31,42.88,45.53,48.25,51.05,53.92,56.87,59.87,62.94,66.07,69.26,72.50,
75.80,79.14,82.53,85.95,89.42,92.91,96.44,100.00,103.58,107.18,110.80,114.43,118.07,121.72,125.38,129.03,132.68,136.33,139.97,143.60,147.21,150.81,154.39,157.95,161.48,164.99,168.47,171.92,175.34,
178.72,182.07,185.38,188.65,191.88,195.06,198.20,201.30,204.34,207.34,210.29,213.19,216.04,218.84,221.58,224.28,226.91,229.49,232.02,234.49,236.91,239.27,241.57,243.82,246.01,248.14,250.21,252.23,254.19,
256.10,257.95,259.74,261.47
};
//spectral data for fluo F1 Daylight 6430K
const double ColorTemp::FluoF1_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,1.87,2.36,2.94,3.47,5.17,19.49,6.13,6.24,7.01,7.79,8.56,43.67,16.94,10.72,11.35,11.89,12.37,12.75,13.00,13.15,13.23,13.17,13.13,12.85,12.52,
12.20,11.83,11.50,11.22,11.05,11.03,11.18,11.53,27.74,17.05,13.55,14.33,15.01,15.52,18.29,19.55,15.48,14.91,14.15,13.22,12.19,11.12,10.03,8.95,7.96,7.02,6.20,5.42,4.73,4.15,3.64,3.20,2.81,
2.47,2.18,1.93,1.72,1.67,1.43,1.29,1.19,1.08,0.96,0.88,0.81,0.77,0.75,0.73,0.68,0.69,0.64,0.68,0.69,0.61,0.52,0.43,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F2 Cool white 4230K
const double ColorTemp::FluoF2_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,1.18,1.48,1.84,2.15,3.44,15.69,3.85,3.74,4.19,4.62,5.06,34.98,11.81,6.27,6.63,6.93,7.19,7.40,7.54,7.62,7.65,7.62,7.62,7.45,7.28,7.15,7.05,7.04,7.16,7.47,8.04,8.88,10.01,24.88,16.64,14.59,16.16,17.60,18.62,21.47,22.79,19.29,18.66,17.73,16.54,15.21,13.80,12.36,10.95,9.65,8.40,7.32,6.31,5.43,4.68,4.02,3.45,
2.96,2.55,2.19,1.89,1.64,1.53,1.27,1.10,0.99,0.88,0.76,0.68,0.61,0.56,0.54,0.51,0.47,0.47,0.43,0.46,0.47,0.40,0.33,0.27,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F3 White 3450K
const double ColorTemp::FluoF3_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,0.82,1.02,1.26,1.44,2.57,14.36,2.70,2.45,2.73,3.00,3.28,31.85,9.47,4.02,4.25,4.44,4.59,4.72,4.80,4.86,4.87,4.85,4.88,4.77,4.67,4.62,4.62,4.73,4.99,5.48,6.25,
7.34,8.78,23.82,16.14,14.59,16.63,18.49,19.95,23.11,24.69,21.41,20.85,19.93,18.67,17.22,15.65,14.04,12.45,10.95,9.51,8.27,7.11,6.09,5.22,4.45,3.80,3.23,2.75,2.33,1.99,1.70,1.55,
1.27,1.09,0.96,0.83,0.71,0.62,0.54,0.49,0.46,0.43,0.39,0.39,0.35,0.38,0.39,0.33,0.28,0.21,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F4 Warm white 2940K
const double ColorTemp::FluoF4_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,0.57,0.70,0.87,0.98,2.01,13.75,1.95,1.59,1.76,1.93,2.10,30.28,8.03,2.55,2.70,2.82,2.91,2.99,3.04,3.08,3.09,3.09,3.14,3.06,3.00,2.98,3.01,
3.14,3.41,3.90,4.69,5.81,7.32,22.59,15.11,13.88,16.33,18.68,20.64,24.28,26.26,23.28,22.94,22.14,20.91,19.43,17.74,16.00,14.42,12.56,10.93,9.52,8.18,7.01,6.00,5.11,4.36,3.69,3.13,2.64,
2.24,1.91,1.70,1.39,1.18,1.03,0.88,0.74,0.64,0.54,0.49,0.46,0.42,0.37,0.37,0.33,0.35,0.36,0.31,0.26,0.19,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F5 Daylight 6350K
const double ColorTemp::FluoF5_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,1.87,2.35,2.92,3.45,5.10,18.91,6.00,6.11,6.85,7.58,8.31,40.76,16.06,10.32,10.91,11.40,11.83,12.17,12.40,12.54,12.58,12.52,12.47,12.20,11.89,
11.61,11.33,11.10,10.96,10.97,11.16,11.54,12.12,27.78,17.73,14.47,15.20,15.77,16.10,18.54,19.50,15.39,14.64,13.72,12.69,11.57,10.45,9.35,8.29,7.32,6.41,5.63,4.90,4.26,
3.72,3.25,2.83,2.49,2.19,1.93,1.71,1.52,1.43,1.26,1.13,1.05,0.96,0.85,0.78,0.72,0.68,0.67,0.65,0.61,0.62,0.59,0.62,0.64,0.55,0.47,0.40,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F6 Lite white 4150K
const double ColorTemp::FluoF6_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,1.05,1.31,1.63,1.90,3.11,14.8,3.43,3.30,3.68,4.07,4.45,32.61,10.74,5.48,5.78,6.03,6.25,6.41,6.52,6.58,6.59,6.56,6.56,6.42,6.28,6.20,6.19,6.30,6.60,7.12,7.94,9.07,10.49,25.22,17.46,15.63,17.22,18.53,
19.43,21.97,23.01,19.41,18.56,17.42,16.09,14.64,13.15,11.68,10.25,8.96,7.74,6.69,5.71,4.87,4.16,3.55,3.02,2.57,2.20,1.87,1.60,1.37,1.29,1.05,0.91,0.81,0.71,0.61,0.54,0.48,0.44,
0.43,0.40,0.37,0.38,0.35,0.39,0.41,0.33,0.26,0.21,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F7 D65 Daylight simulator 6500K
const double ColorTemp::FluoF7_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,2.56,3.18,3.84,4.53,6.15,19.37,7.37,7.05,7.71,8.41,9.15,44.14,17.52,11.35,12.00,12.58,13.08,13.45,13.71,13.88,13.95,13.93,13.82,13.64,13.43,13.25,13.08,12.93,12.78,12.60,
12.44,12.33,12.26,29.52,17.05,12.44,12.58,12.72,12.83,15.46,16.75,12.83,12.67,12.43,12.19,11.89,11.60,11.35,11.12,10.95,10.76,10.42,10.11,10.04,10.02,10.11,9.87,8.65,7.27,6.44,5.83,5.41,
5.04,4.57,4.12,3.77,3.46,3.08,2.73,2.47,2.25,2.06,1.90,1.75,1.62,1.54,1.45,1.32,1.17,0.99,0.81,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F8 D50 simulator Sylvania F40 Design 5000K
const double ColorTemp::FluoF8_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,1.21,1.5,1.81,2.13,3.17,13.08,3.83,3.45,3.86,4.42,5.09,34.1,12.42,7.68,8.60,9.46,10.24,10.84,11.33,11.71,11.98,12.17,12.28,12.32,12.35,12.44,12.55,12.68,12.77,12.72,
12.60,12.43,12.22,28.96,16.51,11.79,11.76,11.77,11.84,14.61,16.11,12.34,13.61,13.87,14.07,14.20,14.16,14.13,14.34,14.50,14.46,14.00,12.58,10.99,9.98,9.22,8.62,8.07,7.39,6.71,6.16,5.63,5.03,4.46,4.02,3.66,
3.36,3.09,2.85,2.65,2.51,2.37,2.15,1.89,1.61,1.32,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F9 Cool white deluxe 4150K
const double ColorTemp::FluoF9_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,0.9,1.12,1.36,1.60,2.59,12.8,3.05,2.56,2.86,3.30,3.82,32.62,10.77,5.84,6.57,7.25,7.86,8.35,8.75,9.06,9.31,9.48,9.61,9.68,10.04,10.26,10.48,10.63,10.76,10.96,
11.18,27.71,16.29,12.28,12.74,13.21,13.65,16.57,18.14,14.55,14.65,14.66,14.61,14.50,14.39,14.40,14.47,14.62,14.72,14.55,14.4,14.58,14.88,15.51,15.47,13.20,10.57,9.18,8.25,7.57,7.03,
6.35,5.72,5.25,4.80,4.29,3.80,3.43,3.12,2.86,2.64,2.43,2.26,2.14,2.02,1.83,1.61,1.38,1.12,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F10 Philips TL85 - 5000K
const double ColorTemp::FluoF10_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,1.11,0.63,0.62,0.57,1.48,12.16,2.12,2.70,3.74,5.14,6.75,34.39,14.86,10.4,10.76,10.11,9.27,8.29,7.29,7.91,16.64,16.73,10.44,5.94,3.34,2.35,1.88,1.59,1.47,
1.80,5.71,40.98,73.69,33.61,8.24,3.38,2.47,4.86,11.45,14.79,12.16,8.97,6.52,8.81,44.12,34.55,12.09,12.15,10.52,4.43,1.95,2.19,3.19,2.77,2.29,2.00,1.52,1.35,1.47,1.79,1.74,1.02,1.14,
3.32,4.49,2.05,0.49,0.24,0.21,0.21,0.24,0.24,0.21,0.17,0.21,0.22,0.17,0.12,0.09,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F11 Philips TL84 4150K
const double ColorTemp::FluoF11_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,0.91,0.63,0.46,0.37,1.29,12.68,1.59,1.79,2.46,3.38,4.49,33.94,12.13,6.95,7.19,7.12,6.72,6.13,5.46,4.79,5.66,14.29,14.96,8.97,4.72,2.33,1.47,1.10,0.89,0.83,1.18,4.90,39.59,
72.84,32.61,7.52,2.83,1.96,1.67,4.43,11.28,14.76,12.73,9.74,7.33,9.72,55.27,42.58,13.18,13.16,12.26,5.11,2.07,2.34,3.58,3.01,2.48,2.14,1.54,1.33,1.46,1.94,2.00,1.20,1.35,4.10,5.58,
2.51,0.57,0.27,0.23,0.21,0.24,0.24,0.20,0.24,0.32,0.26,0.16,0.12,0.09,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for fluo F12 Philips TL83 3000K
const double ColorTemp::FluoF12_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,0.96,0.64,0.45,0.33,1.19,12.48,1.12,0.94,1.08,1.37,1.78,29.05,7.90,2.65,2.71,2.65,2.49,2.33,2.10,1.91,3.01,10.83,11.88,6.88,3.43,1.49,0.92,0.71,0.60,0.63,1.10,4.56,34.4,65.40,29.48,
7.16,3.08,2.47,2.27,5.09,11.96,15.32,14.27,11.86,9.28,12.31,68.53,53.02,14.67,14.38,14.71,6.46,2.57,2.75,4.18,3.44,2.81,2.42,1.64,1.36,1.49,2.14,2.34,1.42,1.61,5.04,6.98,3.19,0.71,0.30,0.26,0.23,0.28,0.28,0.21,
0.17,0.21,0.19,0.15,0.10,0.05,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for HMI lamp studio "Osram" 4800K (for film, spectacle, studio...)
const double ColorTemp::HMI_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,9.66,11.45,13.24,14.93,16.63,17.90,19.20,20.12,21.03,23.84,26.65,26.38,26.12,26.52,27.92,31.15,34.37,34.98,35.61,35.71,35.81,34.90,34.02,34.06,34.08,34.68,35.28,34.72,34.20,33.63,
33.05,34.70,36.35,38.01,39.48,37.29,35.10,36.22,37.28,38.76,40.24,39.56,38.90,39.35,39.79,38.90,38.01,38.05,38.10,37.45,36.64,35.82,35.00,35.06,33.13,33.85,34.55,35.26,35.77,34.92,
34.09,33.40,32.72,32.08,31.45,26.83,22.23,21.50,20.79,21.41,22.03,11.01,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for GTI lamp : Graphiclite & ColorMatch for Photography 5000K
const double ColorTemp::GTI_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,3.26,4.71,6.17,12.71,19.27,20.53,21.80,19.15,16.53,28.25,39.97,48.52,57.06,43.66,30.27,30.22,30.16,31.48,32.98,34.01,35.04,35.83,36.62,37.12,37.62,37.99,38.19,38.29,38.48,
38.82,39.16,45.40,51.63,51.83,62.04,52.41,42.80,42.95,43.09,45.64,48.20,46.23,44.27,43.74,43.22,43.30,43.41,43.10,42.78,42.03,41.29,40.29,39.29,37.89,36.58,34.92,33.27,31.47,29.68,27.90,
26.13,24.55,22.98,21.42,19.86,18.40,16.92,14.46,13.99,12.36,11.73,5.86,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for JudgeIII Lamp D50
const double ColorTemp::JudgeIII_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,4.08,4.25,4.43,6.90,9.40,9.75,10.11,9.30,8.54,14.90,21.16,26.01,30.83,24.90,19.00,19.00,19.00,19.56,20.13,20.28,20.44,20.64,20.85,21.05,21.24,21.65,22.11,22.85,23.58,24.00,24.43,
27.75,31.27,33.90,36.59,30.90,25.32,25.05,24.76,26.03,27.31,25.90,24.48,23.85,23.29,23.10,22.94,23.24,23.53,24.02,24.52,23.80,23.13,24.51,25.76,27.90,29.15,24.70,20.25,16.60,12.98,11.63,10.27,9.30,8.34,
7.60,6.91,6.25,5.67,5.15,4.68,2.34,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data for Solux lamp : 3500K
const double ColorTemp::Solux3500_spect[97] = {
0.5268,0.93,1.3278,1.51,1.6987,2.65,3.6100,3.80,3.9927,6.08,8.1680,11.02,13.863,15.66,17.4600,18.78,20.130,21.43,22.749,24.02,25.290,27.40,29.504,31.77,34.031,36.35,38.672,40.55,42.426,44.15,45.865,47.37,48.879,
49.71,50.531,51.2,51.872,51.9,51.928,52.97,54.015,55.93,57.846,60.25,62.650,64.36,66.065,66.72,67.369,68.81,70.260,71.37,72.487,72.53,72.578,72.51,72.447,72.46,72.471,
72.76,73.047,74.25,75.449,76.5,77.543,78.79,80.040,80.72,81.394,82.12,82.840,83.23,83.614,83.36,83.100,82.36,81.615,80.11,78.606,75.91,73.221,69.61,66.006,62.43,58.844,56.07,53.292,
51.07,48.839,46.93,45.013,43.54,42.070,40.61,39.150,37.79,36.425
};
//spectral data for Solux lamp : 4100K
const double ColorTemp::Solux4100_spect[97] = {
0.5717,0.70,0.8286,1.16,1.522,2.01,2.384,3.45,4.57,6.46,8.4548,11.31,14.205,16.10,17.949,19.51,21.068,22.60,24.197,25.37,26.566,28.15,29.742,30.90,32.060,33.26,34.481,34.80,35.130,35.42,35.697,36.20,36.763,
37.90,39.004,40.26,41.494,43.10,44.690,45.80,46.900,47.45,47.885,47.75,47.635,47.00,46.410,46.22,46.058,46.70,47.344,48.65,50.005,51.02,52.045,53.55,55.075,55.98,56.823,
56.85,56.884,56.15,55.523,54.60,53.732,52.55,51.425,50.30,49.1830,48.76,48.273,48.22,48.169,49.92,49.915,51.90,53.099,54.95,56.852,58.45,60.090,61.67,63.2530,63.55,63.834,63.55,63.468,
62.40,61.373,59.75,58.1810,56.25,54.395,51.90,49.496,47.05,44.620
};
//spectral data for Solux lamp : near Daylight (for example "mus<75>e d'Orsay..") - 4700K
const double ColorTemp::Solux4700_spect[97] = {
0.4590,0.83,1.2011,1.53,1.8647,2.15,2.5338,3.06,3.5809,3.99,4.4137,4.82,5.2228,5.63,6.0387,6.53,6.9944,7.55,8.0266,8.475,8.9276,8.90,9.7840,10.20,10.6390,11.00,11.3600,11.75,12.1340,12.36,12.5880,12.74,12.8790,
13.07,13.2560,13.38,13.5220,13.41,13.3070,13.35,13.3990,13.37,13.3420,13.39,13.4220,13.65,13.2710,13.25,13.2330,13.12,13.0110,12.93,12.8470,12.805,12.7630,12.66,12.5760,12.563,12.5490,
12.59,12.6330,12.617,12.6010,12.616,12.6310,12.6275,12.6240,12.70,12.7710,12.776,12.7810,12.786,12.7950,12.74,12.6850,12.64,12.5950,12.55,12.5420,12.43,12.3180,12.07,11.8340,11.72,11.6190,11.55,11.5020,
11.32,11.1510,11.05,10.9530,10.80,10.6550,10.495,10.4390,10.31,10.1790
};
//spectral data for Solux lamp : near Daylight 4400K - test National Gallery
const double ColorTemp::NG_Solux4700_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,139,152,170,185,202,223,240,257,270,282,293,305,317,329,342,355,367,378,387,395,401,405,408,411,414,415,416,415,414,414,416,419,423,427,432,437,442,447,452,
456,461,467,475,483,488,490,491,490,487,485,481,477,472,466,461,455,449,442,434,427,419,411,403,395,386,377,367,359,351,343,335,327,322,316,312,306,305,301,299,299,298,
0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0
};
//spectral data for LED LSI Lumelex 2040 - test National Gallery
const double ColorTemp::NG_LEDLSI2040_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,1.5,1.2,0.5,0.7,0.6,1.6,1.7,7.0,16.6,35.5,64,106,162.5,230.5,272.2,249,213.4,214,227.6,231.9,233,235.2,241.4,253.7,270.3,288.5,306.2,322.3,337.6,352.5,367.2,381.7,395.9,409.6,416.2,423.2,429.7,435.8,442.8,
451.7,464.2,480.3,501,526.3,555.9,587.5,625.4,655.1,681.7,705.3,721.5,728.5,729,719.8,702.5,676.7,646.2,611.5,571.7,530.3,488.3,445.9,404,365.2,326.8,290.8,257.6,226.9,199.8,175.2,154.2,133.8,116.4,101.5,88.5,76.6,67.3,57.9,50.7,44.2,38.2,
0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0
};
//spectral data for LED CRS SP12 WWMR16 - test National Gallery
const double ColorTemp::NG_CRSSP12WWMR16_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,0.,0.,0.,0.,0.,0.14,0.33,1.31,3.34,7.9,17.4,36.5,72.6,145.4,260.5,359.2,365.3,303.1,256.1,221.7,193.6,185.8,191.4,207.3,232.8,257.5,285.1,310.5,333.4,351.5,368.8,383.7,398.8,411.6,424.7,435.6,447.9,459.7,471.7,
484.6,497.9,512.3,531.1,548.9,567.9,587.5,608.6,625.3,640.1,648.6,654.0,654.3,647.2,633.9,616.1,590.5,561.5,526.5,494.8,457.9,420.8,382.4,347.3,309.9,280.5,249.2,220.0,194.9,170.8,149.1,130.0,112.3,97.5,84.9,73.2,63.1,54.1,45.6,39.0,32.6,27.4,
0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0
};
//Data for flash :
// in theory, should be the spectral data of each owner flash (Nikon, Canon, Sony ...) or studio flash (Profoto. ..)
// but: 1) I did not, 2) the data vary depending on the power used ... so by default, although this is not true, I chose the values "Daylight" for temp...
// CRI for flash near of 95 - 97 !!
//spectral data for Flash daylight 5500K (Leica...)
const double ColorTemp::Flash5500_spect[97] = {
27.77,29.17,30.58,32.02,33.47,33.00,32.53,35.28,38.04,49.46,60.88,64.68,68.48,69.99,71.51,69.68,67.85,76.70,85.54,91.74,97.93,99.17,100.41,100.14,99.86,101.28,102.70,100.37,98.04,99.35,100.65,
100.66,100.67,100.32,99.97,102.08,104.20,103.15,102.09,102.53,102.96,101.48,100.00,98.61,97.22,97.49,97.76,94.60,91.44,92.94,94.44,94.80,95.16,94.70,94.25,92.36,90.48,91.42,92.36,90.63,
88.89,89.62,90.36,92.18,94.00,92.00,90.00,84.86,79.72,81.30,82.88,83.88,84.89,77.58,70.27,74.80,82.19,85.03,78.47,71.91,62.37,52.82,64.39,75.96,73.91,71.85,72.41,72.97,70.17,67.38,63.07,
58.75,61.89,65.02,66.68,68.34
};
//spectral data for Flash daylight 6000K (Canon, Pentax, Olympus,...Standard)
const double ColorTemp::Flash6000_spect[97] = {
36.00,37.18,38.36,40.36,42.35,41.77,41.19,43.79,46.40,59.24,72.09,76.15,80.22,81.47,82.71,80.12,77.52,86.54,95.56,101.70,107.85,108.66,109.46,108.57,107.68,108.65,109.61,106.63,103.65,104.42,
105.19,104.79,104.39,103.45,102.51,104.28,106.05,104.68,103.31,103.42,103.54,101.77,100.00,98.38,96.75,96.74,96.72,93.30,89.89,90.92,91.95,91.99,92.03,91.30,90.57,88.51,86.45,86.96,
87.47,85.66,83.85,84.21,84.57,85.95,87.32,85.31,83.30,78.66,74.03,75.24,76.45,77.68,78.91,72.13,65.35,69.67,73.98,76.68,79.39,73.29,67.19,58.19,49.19,59.98,70.77,68.91,67.05,67.55,68.05,
65.47,62.88,58.89,54.90,57.81,60.72,62.25,63.78
};
//spectral data for Flash daylight 6500K (Nikon, Minolta, Panasonic, Sony...)
const double ColorTemp::Flash6500_spect[97] = {
44.86,45.72,46.59,49.16,51.74,50.83,49.92,52.26,54.60,68.65,82.69,87.06,91.42,92.39,93.37,90.00,86.63,95.72,104.81,110.88,116.96,117.36,117.76,116.29,114.82,115.35,115.89,112.33,108.78,109.06,
109.33,108.56,107.78,106.28,104.78,106.23,107.68,106.04,104.40,104.22,104.04,102.02,100.00,98.17,96.34,96.06,95.79,92.24,88.69,89.35,90.02,89.81,89.61,88.66,87.71,85.51,83.30,83.51,83.72,
81.88,80.05,80.14,80.24,81.27,82.30,80.31,78.31,74.03,69.74,70.69,71.63,73.00,74.37,68.00,61.62,65.76,69.91,72.51,75.11,69.36,63.61,55.02,46.43,56.63,66.83,65.11,63.40,63.86,64.32,61.90,59.47,
55.72,51.97,54.72,57.46,58.89,60.33
};
// Data for Color ==> CRI (Color Rendering Index and Palette
// actually 20 color that must be good enough for CRI
// I think 40 color for palette (Skin, Sky, gray)
//spectral data Colorchecker24 : Red C3
const double ColorTemp::ColorchechredC3_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0478,0.0476,0.0474,0.0472,0.0470,0.0466,0.0461,0.0460,0.0459,0.0456,0.0453,0.0451,0.0449,0.0448,0.0447,0.0446,0.0445,0.0441,0.0437,0.0432,0.0427,0.0424,0.0421,0.0419,
0.0417,0.0415,0.0412,0.0412,0.0412,0.0413,0.0413,0.0415,0.0416,0.0421,0.0426,0.0436,0.0446,0.0469,0.0491,0.0549,0.0607,0.0773,0.0939,0.1376,0.1812,0.2568,0.3323,0.4070,0.4816,0.5308,
0.5800,0.6059,0.6317,0.6447,0.6577,0.6653,0.6728,0.6761,0.6793,0.6820,0.6847,0.6878,0.6909,0.6945,0.6980,0.7013,0.7046,0.7065,0.7084,0.7107,0.7129,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 : Orange A2
const double ColorTemp::ColorchechOraA2_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0520,0.0530,0.0540,0.0535,0.0530,0.0532,0.0534,0.0532,0.0529,0.0529,0.0528,0.0530,0.0532,0.0537,0.0542,0.0550,0.0557,0.0565,0.0573,0.0585,0.0597,0.0613,0.0628,0.0656,0.0683,0.0793,
0.0902,0.1085,0.1268,0.1414,0.1559,0.1645,0.1730,0.1837,0.1944,0.2184,0.2424,0.2877,0.3329,0.3923,0.4517,0.5021,0.5525,0.5739,0.5952,0.5967,0.5982,0.5962,0.5942,0.5932,0.5922,0.5927,
0.5932,0.5938,0.5944,0.5988,0.6032,0.6105,0.6178,0.6284,0.6389,0.6498,0.6607,0.6699,0.6791,0.6839,0.6886,0.6879,0.6871,0.6886,0.6901,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 :yellow D3
const double ColorTemp::ColorchechYelD3_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0476,0.0482,0.0488,0.0492,0.0496,0.0498,0.0499,0.0498,0.0496,0.0501,0.0506,0.0516,0.0526,0.0547,0.0567,0.0610,0.0652,0.0733,0.0813,0.0962,0.1110,0.1333,0.1556,0.1884,0.2211,
0.2782,0.3353,0.4023,0.4692,0.5198,0.5703,0.5976,0.6249,0.6400,0.6551,0.6667,0.6783,0.6901,0.7018,0.7095,0.7171,0.7231,0.7290,0.7329,0.7367,0.7395,0.7423,0.7447,0.7471,0.7490,0.7508,
0.7533,0.7558,0.7578,0.7598,0.7623,0.7647,0.7654,0.7661,0.7677,0.7693,0.7720,0.7746,0.7780,0.7814,0.7845,0.7876,0.7889,0.7902,0.7920,0.7938,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 : Green E2
const double ColorTemp::ColorchechGreE2_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0560,0.0583,0.0605,0.0626,0.0646,0.0650,0.0653,0.0657,0.0661,0.0669,0.0676,0.0692,0.0708,0.0737,0.0765,0.0816,0.0867,0.0956,0.1044,0.1194,0.1344,0.1581,0.1818,0.2196,0.2574,0.3166,0.3757,
0.4297,0.4837,0.5142,0.5446,0.5541,0.5636,0.5608,0.5579,0.5480,0.5381,0.5258,0.5135,0.4959,0.4783,0.4570,0.4356,0.4124,0.3891,0.3710,0.3529,0.3425,0.3320,0.3266,0.3211,0.3180,0.3149,
0.3129,0.3108,0.3123,0.3137,0.3193,0.3248,0.3335,0.3422,0.3518,0.3613,0.3693,0.3772,0.3810,0.3847,0.3838,0.3829,0.3838,0.3847,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 : Green B3
const double ColorTemp::ColorchechGreB3_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0531,0.0545,0.0559,0.0563,0.0566,0.0571,0.0576,0.0576,0.0575,0.0581,0.0586,0.0596,0.0606,0.0629,0.0652,0.0699,0.0745,0.0839,0.0932,0.1101,0.1270,0.1521,0.1771,0.2098,0.2424,
0.2789,0.3154,0.3312,0.3470,0.3431,0.3392,0.3303,0.3213,0.3089,0.2964,0.2788,0.2612,0.2442,0.2271,0.2117,0.1962,0.1815,0.1667,0.1527,0.1386,0.1284,0.1182,0.1124,0.1066,0.1035,0.1003,
0.0987,0.0971,0.0961,0.0950,0.0950,0.0950,0.0962,0.0973,0.0994,0.1014,0.1045,0.1075,0.1106,0.1137,0.1157,0.1176,0.1175,0.1173,0.1173,0.1173,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 : Cyan F3
const double ColorTemp::ColorchechCyaF3_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0813,0.1048,0.1282,0.1611,0.1940,0.2198,0.2456,0.2575,0.2693,0.2807,0.2921,0.3079,0.3237,0.3424,0.3611,0.3820,0.4029,0.4234,0.4439,0.4547,0.4654,0.4638,0.4621,0.4482,0.4342,0.4119,0.3895,
0.3656,0.3417,0.3160,0.2903,0.2654,0.2404,0.2167,0.1929,0.1720,0.1510,0.1368,0.1226,0.1138,0.1049,0.0993,0.0936,0.0890,0.0844,0.0810,0.0776,0.0759,0.0742,0.0733,0.0724,0.0723,0.0722,0.0727,
0.0732,0.0745,0.0757,0.0763,0.0768,0.0764,0.0759,0.0748,0.0736,0.0723,0.0710,0.0703,0.0696,0.0707,0.0718,0.0756,0.0793,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 : Purple D2
const double ColorTemp::ColorchechPurD2_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0854,0.1047,0.1240,0.1468,0.1696,0.1826,0.1955,0.1963,0.1970,0.1910,0.1849,0.1750,0.1651,0.1541,0.1430,0.1322,0.1213,0.1117,0.1020,0.0944,0.0868,0.0809,0.0750,0.0703,0.0655,
0.0627,0.0599,0.0583,0.0567,0.0550,0.0533,0.0525,0.0517,0.0518,0.0519,0.0523,0.0526,0.0525,0.0524,0.0520,0.0516,0.0523,0.0529,0.0560,0.0591,0.0662,0.0732,0.0828,0.0924,0.1021,
0.1117,0.1222,0.1327,0.1469,0.1610,0.1796,0.1981,0.2173,0.2365,0.2532,0.2698,0.2826,0.2953,0.3022,0.3090,0.3126,0.3161,0.3238,0.3314,0.3504,0.3694,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 : Magenta E3
const double ColorTemp::ColorchechMagE3_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1112,0.1438,0.1763,0.2294,0.2824,0.3188,0.3552,0.3623,0.3693,0.3653,0.3612,0.3510,0.3407,0.3269,0.3130,0.2981,0.2832,0.2686,0.2539,0.2385,0.2230,0.2083,0.1935,0.1818,0.1700,0.1600,0.1499,
0.1394,0.1288,0.1188,0.1088,0.1051,0.1014,0.1026,0.1038,0.1041,0.1043,0.1064,0.1085,0.1225,0.1364,0.1701,0.2037,0.2532,0.3027,0.3587,0.4147,0.4683,0.5219,0.5672,0.6124,0.6455,0.6785,0.7009,
0.7232,0.7391,0.7550,0.7629,0.7707,0.7737,0.7766,0.7778,0.7790,0.7803,0.7815,0.7835,0.7854,0.7896,0.7937,0.8026,0.8114,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 : Skin A1
//use also for palette WB
const double ColorTemp::ColorchechSkiA138_13_14_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0479,0.051,0.0553,0.058,0.0610,0.062,0.0626,0.0622,0.0619,0.0617,0.0616,0.0615,0.0614,0.0614,0.0615,0.0617,0.0618,0.0618,0.0619,0.0618,0.0618,0.062,0.0622,0.063,0.0638,0.066,0.0696,
0.073,0.0767,0.078,0.0801,0.0807,0.0817,0.0831,0.0845,0.0870,0.0902,0.0955,0.1017,0.1096,0.1175,0.1250,0.1336,0.1385,0.1435,0.1455,0.1479,0.1490,0.1514,0.1547,0.1580,0.1625,0.1675,
0.173,0.1772,0.181,0.1842,0.1846,0.1853,0.1831,0.1811,0.1788,0.1765,0.1769,0.1773,0.181,0.1834,0.1874,0.1914,0.1965,0.2018,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 : Gray C4 L=67
//use also for palette WB
const double ColorTemp::ColorchechGraC4_67_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1074,0.1380,0.1704,0.22,0.2705,0.305,0.3409,0.35,0.3601,0.3628,0.3655,0.3675,0.3698,0.371,0.3724,0.373,0.3733,0.3725,0.3715,0.3705,0.3692,
0.369,0.3689,0.368,0.3673,0.3678,0.3684,0.37,0.3711,0.3712,0.3714,0.3714,0.3714,0.371,0.3707,0.37,0.3694,0.3697,0.3703,0.3697,0.3692,0.3688,0.3685,0.3675,0.3669,0.3657,0.3647,0.3635,0.3625,0.361,
0.3596,0.3585,0.3579,0.357,0.3560,0.3555,0.3548,0.3535,0.3526,0.3513,0.3500,0.349,0.3475,0.3467,0.3460,0.3452,0.3444,0.3431,0.3421,0.3411,0.3403,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 : Skin B1
//use also for palette WB
const double ColorTemp::ColorchechSkiB166_18_18_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0962,0.114,0.1328,0.152,0.1706,0.1755,0.1877,0.189,0.1903,0.1913,0.1923,0.1946,0.1971,0.2015,0.2064,0.215,0.2245,0.239,0.2535,0.273,0.2922,0.31,0.3274,0.337,0.3473,
0.348,0.3489,0.335,0.3224,0.303,0.2835,0.275,0.2671,0.27,0.2728,0.2735,0.2741,0.279,0.2836,0.308,0.3334,0.375,0.4183,0.457,0.4950,0.516,0.5409,0.5515,0.5625,0.568,0.5731,0.5786,
0.5820,0.586,0.5902,0.596,0.6025,0.611,0.6174,0.627,0.6375,0.65,0.6626,0.677,0.6910,0.704,0.7171,0.723,0.7339,0.741,0.7475,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorchecker24 : blue sky C1
//use also for palette WB
const double ColorTemp::ColorchechBluC150_m5_m22_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1053,0.134,0.1633,0.2075,0.2518,0.283,0.3163,0.324,0.3325,0.334,0.3355,0.3352,0.3349,0.332,0.3294,0.325,0.3199,0.3127,0.3055,0.2955,0.2863,0.28,0.2737,0.267,0.2612,0.249,0.2378,0.228,0.2199,
0.218,0.2173,0.2146,0.2118,0.20,0.1884,0.178,0.1682,0.166,0.1639,0.162,0.1613,0.158,0.1550,0.1504,0.1458,0.1415,0.1375,0.135,0.1327,0.1316,0.1305,0.1304,0.1302,0.131,0.1322,0.1342,0.1362,
0.1367,0.1372,0.1356,0.1340,0.1311,0.1288,0.1253,0.1227,0.1205,0.1187,0.1195,0.1205,0.1255,0.1303,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorcheckerDC : blue sky N8
//use also for palette WB
const double ColorTemp::ColorchechDCBluN881_m7_m14_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1371,0.17,0.2029,0.291,0.3790,0.495,0.6100,0.67,0.7249,0.737,0.7501,0.7545,0.7597,0.764,0.7677,0.7685,0.7693,0.7677,0.7662,0.763,0.7593,0.753,0.7471,0.737,0.7289,0.718,0.7077,0.705,0.6819,0.666,0.6515,0.636,0.6244,
0.61,0.5948,0.577,0.5581,0.544,0.5293,0.522,0.5147,0.512,0.5091,0.506,0.5029,0.499,0.4950,0.494,0.4931,0.497,0.5007,0.508,0.5176,0.527,0.5359,0.542,0.5487,0.549,0.5494,0.544,
0.5375,0.531,0.5244,0.522,0.5207,0.524,0.5264,0.532,0.5369,0.542,0.5505,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorcheckerSG : Skin F7
//use also for palette WB
const double ColorTemp::ColorchechSGSkiF763_14_26_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,0.0508,0.64,0.0776,0.903,0.1099,0.1128,0.1256,0.128,0.1307,0.133,0.1357,0.139,0.1425,0.148,0.1523,0.159,0.1669,0.177,0.1871,0.20,0.2118,0.2235,0.2355,0.2445,0.2537,0.259,0.2655,0.268,
0.2700,0.2708,0.2716,0.2743,0.2770,0.2803,0.2827,0.283,0.2832,0.283,0.2828,0.295,0.3079,0.344,0.3803,0.4105,0.4409,0.455,0.4694,0.477,0.4851,0.4896,0.4962,0.501,0.5066,0.511,0.5160,0.521,
0.5256,0.529,0.5318,0.535,0.5383,0.541,0.5451,0.549,0.5524,0.556,0.5597,0.562,0.5650,0.568,0.5709,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorcheckerSG : Skin K2 85 11 17
//use also for palette WB
const double ColorTemp::ColorchechSGSkiK285_11_17_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1122,0.149,0.1866,0.259,0.3318,0.393,0.4547,0.469,0.4846,0.4845,0.4844,0.4838,0.4834,0.4837,0.4840,0.4847,0.4854,0.4852,0.4849,0.4842,0.4835,0.4832,0.4828,0.485,
0.4874,0.501,0.5150,0.536,0.5572,0.5685,0.5798,0.586,0.5932,0.5987,0.6142,0.6342,0.6541,0.683,0.7119,0.734,0.7571,0.769,0.7829,0.788,0.7932,0.795,0.7968,0.7973,
0.7977,0.7974,0.7969,0.797,0.7972,0.7973,0.7975,0.7983,0.7990,0.7978,0.7965,0.7957,0.7949,0.7944,0.7940,0.794,0.7941,0.7943,0.7946,0.7938,0.7930,0.7929,0.7928,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorcheck24 : White A4 L=96
//use also for palette WB
const double ColorTemp::ColorchechWhiA496_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1267,0.172,0.2179,0.317,0.4164,0.505,0.6780,0.758,0.8397,0.865,0.8911,0.897,0.9035,0.9062,0.9092,0.9124,0.9154,0.9167,0.9180,0.9187,0.9194,0.92,0.9225,0.9217,0.9209,0.921,
0.9212,0.9227,0.9242,0.9235,0.9227,0.9232,0.9238,0.9243,0.9248,0.9237,0.9227,0.9239,0.9252,0.924,0.9233,0.9238,0.9242,0.924,0.9239,0.9239,0.9239,0.924,0.9242,0.9239,
0.9237,0.925,0.9264,0.9276,0.9288,0.9298,0.9308,0.9296,0.9284,0.928,0.9276,0.928,0.9284,0.9294,0.9304,0.9316,0.9328,0.9328,0.9328,0.9337,0.9345,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data Colorcheck24 : foliage Green D1
const double ColorTemp::ColorchechGreD1_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0477,0.0492,0.0507,0.0517,0.0527,0.0532,0.0537,0.054,0.0544,0.0554,0.0563,0.0573,0.0584,0.0592,0.0601,0.0607,0.0611,0.0613,0.0619,0.626,0.0634,0.0646,0.0659,0.069,
0.0721,0.0837,0.0958,0.117,0.1386,0.156,0.1748,0.1802,0.1855,0.1795,0.1742,0.1636,0.1529,0.144,0.1351,0.13,0.1239,0.1202,0.1171,0.1138,0.1106,0.108,0.1048,0.1035,
0.1022,0.1025,0.1030,0.1041,0.1052,0.106,0.1068,0.107,0.1073,0.1066,0.1060,0.1047,0.1035,0.1028,0.1021,0.1029,0.1034,0.105,0.1069,0.1086,0.1104,0.1127,0.1150,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorchecSG : black N3 L=6
//use also for palette WB
const double ColorTemp::ColorchechSGBlaN3_6_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0066,0.0069,0.0071,0.0072,0.0074,0.0073,0.0072,0.0073,0.0074,0.0074,0.0074,0.0074,0.0074,0.0073,0.0073,0.0073,0.0073,0.0072,0.0072,0.0072,0.0072,0.0071,0.0071,0.0071,
0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0070,0.0070,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0070,
0.0070,0.0070,0.0070,0.0069,0.0069,0.0069,0.0068,0.0068,0.0068,0.0068,0.0068,0.0068,0.0067,0.0067,0.0067,0.0067,0.0066,0.0066,0.0066,0.0066,0.0066,0.0066,0.0066,0.0067,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data 468 color : gray K14 L=44
//use also for palette WB
const double ColorTemp::JDC468_GraK14_44_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.04240,0.0485,0.05500,0.0624,0.06930,0.084,0.09820,0.109,0.12160,0.127,0.13300,0.13490,0.13690,0.1379,0.13890,0.1396,0.14060,0.1407,0.14080,0.1423,0.14380,0.1488,0.15370,0.157,0.16040,
0.157,0.15360,0.1482,0.14290,0.1436,0.14470,0.1454,0.14620,0.137,0.12870,0.1205,0.11250,0.116,0.11930,0.1261,0.13350,0.1367,0.13990,0.139,0.13810,0.1371,0.13610,0.1372,0.13820,
0.1408,0.14330,0.1475,0.15170,0.1583,0.16500,0.172,0.17940,0.1836,0.18780,0.188,0.18820,0.186,0.18430,0.1801,0.17620,0.1741,0.17210,0.179,0.18420,0.1991,0.21430,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data 468 color : Blue H10 - Gamut > WidegamutRGB
const double ColorTemp::JDC468_BluH10_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.01590,0.028,0.03970,0.0697,0.09970,0.1526,0.20550,0.253,0.30110,0.3412,0.38180,0.423,0.46610,0.4683,0.51030,0.4999,0.49950,0.4785,0.45810,0.429,0.39950,0.374,0.35010,0.3135,0.29630,
0.2587,0.22070,0.182,0.14450,0.1125,0.09060,0.072,0.04810,0.033,0.01740,0.0113,0.00520,0.004,0.00290,0.0028,0.00270,0.0027,0.00270,0.0027,0.00280,0.0027,0.00270,0.0028,0.00280,
0.0029,0.00300,0.0029,0.00290,0.0029,0.0029,0.00290,0.0029,0.00290,0.0029,0.00290,0.0029,0.00290,0.0029,0.00290,0.0029,0.0031,0.00320,0.0035,0.00380,0.047,0.00560,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 35 15 17
const double ColorTemp::ColabSkin35_15_17_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0211,0.022, 0.0225,0.0234, 0.0244,0.0294, 0.0349,0.038, 0.0411,0.0425, 0.0441,0.0455, 0.0472,0.0473, 0.0475,0.0463, 0.0452,0.0435, 0.0417,0.0397, 0.0377,
0.0375, 0.0372,0.0412, 0.0452,0.052, 0.0603,0.0655, 0.0707,0.0722, 0.0736,0.0738, 0.0741,0.0737, 0.0731,0.0721, 0.0711,0.0707, 0.0704,0.071, 0.0717,
0.0782, 0.0846,0.099, 0.1159,0.1298, 0.1432,0.1497, 0.1581,0.1603, 0.1644,0.1659, 0.1673,0.1679, 0.1690,0.1696, 0.1702,0.1704, 0.1705,0.1706, 0.1707,0.1707, 0.1707,0.1707, 0.1706,0.1706, 0.1707,0.1707, 0.1706,0.1712, 0.1719,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 57 22 18
const double ColorTemp::ColabSkin57_22_18_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0647,0.0677, 0.0709,0.0754, 0.0797,0.099, 0.1181,0.1296, 0.1409,0.1469, 0.1529,0.1594, 0.1657,0.1672, 0.1683,0.1648, 0.1615,0.1561, 0.1506,0.144, 0.1375,0.136, 0.1339,
0.1437, 0.1531,0.172, 0.1911,0.2032, 0.2153,0.2171, 0.2190,0.2176, 0.2164,0.213, 0.2095,0.2048, 0.2005,0.1985, 0.1965,0.198, 0.1997,0.2196, 0.2396,0.288, 0.3362,0.378,
0.4209,0.444, 0.4671,0.477, 0.4865,0.491, 0.4955,0.498, 0.5007,0.5027, 0.5048,0.5055, 0.5061,0.5063, 0.5066,0.5065, 0.5063,0.506, 0.5057,0.5056, 0.5055,0.5056, 0.5057,0.5078, 0.5099,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 40 17 17
const double ColorTemp::ColabSkin40_17_17_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0296,0.0306, 0.0317,0.0332, 0.0346,0.042, 0.0498,0.0543, 0.0588,0.061, 0.0632,0.0624, 0.0678,0.068, 0.0682,0.0663, 0.0649,0.0625, 0.0598,0.057, 0.0540,0.0535, 0.0529,0.057,
0.0631,0.072, 0.0827,0.089, 0.0959,0.0975, 0.0994,0.0996, 0.0997,0.0988, 0.0980,0.0966, 0.0951,0.0945, 0.0939,0.0948, 0.0957,0.105, 0.1143,0.136, 0.1589,0.178, 0.1980,
0.2095, 0.2194,0.224, 0.2283,0.2302, 0.2325,0.2337, 0.2348,0.2357, 0.2366,0.2369, 0.2371,0.2372, 0.2373,0.2373, 0.2373,0.2373, 0.2372,0.2372, 0.2372,0.2372, 0.2372,0.238, 0.2389,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 91 4 14
const double ColorTemp::ColabSkin91_4_14_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1430,0.16, 0.1778,0.202, 0.2303,0.301, 0.3813,0.4245, 0.4692,0.499, 0.5287,0.5635, 0.5977,0.6175, 0.6372,0.6394, 0.6418,0.638, 0.6341,0.6228, 0.6117,0.6121, 0.6125,
0.646, 0.6807,0.742, 0.8032,0.8355, 0.8687,0.8595, 0.8510,0.828, 0.8059,0.778, 0.7490,0.721, 0.6914,0.676, 0.6608,0.657, 0.6530,0.6565, 0.7001,0.7609, 0.8219,
0.876, 0.9297,0.9598, 0.9901,1.003, 1.0156,1.021, 1.0289,1.0346, 1.0396,1.045, 1.0513,1.0538, 1.0561,1.0559, 1.0557,1.054, 1.0523,1.049, 1.0466,1.045, 1.0436,1.0445, 1.0455,1.053, 1.0605,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 87 8 8
const double ColorTemp::ColabSkin87_8_8_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1433,0.161, 0.1780,0.204, 0.2305,0.306, 0.3828,0.428, 0.4722,0.502, 0.5317,0.5645, 0.5997,0.618, 0.6366,0.6368, 0.6370,0.631, 0.6251,0.6120, 0.5994,0.596,
0.5931,0.618, 0.6420,0.705, 0.7347,0.757, 0.7785,0.765, 0.7532,0.71, 0.7062,0.677, 0.6491,0.62, 0.5922,0.577, 0.5619,0.5586, 0.5556,0.579, 0.6121,
0.684, 0.7563,0.82, 0.8837,0.918, 0.9545,0.969, 0.9843,0.992, 0.9991,1.005, 1.0104,1.016, 1.0223,1.0248, 1.0273,1.0272, 1.0271,1.025, 1.0238,1.02, 1.0182,1.017, 1.0151,1.016, 1.0171,1.024, 1.0321,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 89 8 21
const double ColorTemp::ColabSkin89_8_21_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1394,0.152, 0.1659,0.1855, 0.2052,0.266, 0.3277,0.363, 0.3988,0.422, 0.4450,0.472, 0.4984,0.512, 0.5270,0.5274, 0.5278,0.522, 0.5177,0.5065, 0.4960,0.4975,
0.4995,0.535, 0.5721,0.637, 0.7016,0.7395, 0.7786,0.7777, 0.7767,0.763, 0.7485,0.728, 0.7081,0.687, 0.6649,0.653, 0.6425,0.641, 0.6391,0.665, 0.6925,0.76,
0.8266,0.885, 0.9447,0.975, 1.0106,1.025, 1.0383,1.045, 1.0525,1.058, 1.0628,1.068, 1.0730,1.075, 1.0768,1.0768, 1.0769,1.0755, 1.0744,1.0724, 1.0704,1.069, 1.0685,1.0691, 1.0697,1.075, 1.0823,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 75 8 4
const double ColorTemp::ColabSkin75_8_4_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1030,0.116, 0.1294,0.1495, 0.1696,0.227, 0.2847,0.319, 0.3524,0.375, 0.3977,0.423, 0.4492,0.462, 0.4770,0.4768, 0.4767,0.471, 0.4675,0.458, 0.4480,0.444, 0.4408,
0.455, 0.4688,0.496, 0.5243,0.535, 0.5465,0.534, 0.5228,0.503, 0.4851,0.463, 0.4408,0.419, 0.3974,0.385, 0.3741,0.371, 0.3692,0.391, 0.4110,0.464, 0.5180,
0.565, 0.6126,0.638, 0.6651,0.676, 0.6871,0.692, 0.6979,0.702, 0.7062,0.71, 0.7151,0.717, 0.7189,0.7188, 0.7187,0.717, 0.7162,0.714, 0.7119,0.7105, 0.7095,0.7097, 0.7110,0.716, 0.7223,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 75 10 33
const double ColorTemp::ColabSkin75_10_33_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0873,0.091, 0.0967,0.103, 0.1097,0.135, 0.1617,0.177, 0.1913,0.198, 0.2086,0.218, 0.2289,0.234, 0.2383,0.2375, 0.2370,0.2335, 0.2299,0.223, 0.2180,0.222,
0.2259,0.256, 0.2860,0.338, 0.3905,0.426, 0.4613,0.47, 0.4786,0.478, 0.4772,0.471, 0.4668,0.459, 0.4522,0.449, 0.4454,0.446, 0.4467,0.464, 0.4834,0.527,
0.5727,0.609, 0.6511,0.673, 0.6946,0.703, 0.7130,0.718, 0.7224,0.725, 0.7285,0.731, 0.7337,0.7345, 0.7351,0.7353, 0.7355,0.735, 0.7348,0.7342, 0.7337,0.7336, 0.7335,0.7335, 0.7336,0.737, 0.7395,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 65 33 11
const double ColorTemp::ColabSkin65_33_11_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1067,0.113, 0.1182,0.126, 0.1346,0.165, 0.2033,0.224, 0.2448,0.259, 0.2666,0.277, 0.2891,0.291, 0.2927,0.285, 0.2783,0.268, 0.2569,0.244, 0.2323,0.225, 0.2195,
0.225, 0.2323,0.248, 0.2655,0.275, 0.2832,0.281, 0.2797,0.275, 0.2708,0.264, 0.2567,0.248, 0.2403,0.236, 0.2326,0.235, 0.2386,0.274, 0.3116,0.40, 0.4885,0.56,
0.6435,0.688, 0.7279,0.745, 0.7633,0.772, 0.7791,0.783, 0.7883,0.792, 0.7955,0.7965, 0.7978,0.7982, 0.7989,0.7985, 0.7983,0.7975, 0.7971,0.7968, 0.7966,0.7968, 0.7970,0.801, 0.8043,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 65 7 24
const double ColorTemp::ColabSkin65_7_24_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0619,0.066, 0.0710,0.077, 0.0840,0.106, 0.1288,0.142, 0.1546,0.163, 0.1706,0.179, 0.1893,0.194, 0.1989,0.1988, 0.1987,0.196, 0.1941,0.189, 0.1853,0.188, 0.1894,
0.209, 0.2282,0.262, 0.2962,0.318, 0.3402,0.343, 0.3469,0.343, 0.3407,0.334, 0.3285,0.321, 0.3140,0.31, 0.3069,0.308, 0.3066,0.319, 0.3311,0.362, 0.3918,0.418,
0.4451,0.459, 0.4747,0.481, 0.4873,0.491, 0.4937,0.496, 0.4981,0.501, 0.5022,0.503, 0.5035,0.5035, 0.5036,0.5032, 0.5029,0.5022, 0.5016,0.5013, 0.5011,0.5013, 0.5014,0.504, 0.5063,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 57 19 6
const double ColorTemp::ColabSkin57_19_6_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0662,0.071, 0.0773,0.085, 0.0939,0.115, 0.1491,0.165, 0.1821,0.192, 0.2019,0.214, 0.2236,0.228, 0.2321,0.2298, 0.2266,0.221, 0.2161,0.208, 0.2019,0.199,
0.1951,0.201, 0.2066,0.219, 0.2325,0.239, 0.2443,0.241, 0.2366,0.23, 0.2235,0.215, 0.2068,0.199, 0.1895,0.185, 0.1806,0.1811, 0.1816,0.20, 0.2197,0.267, 0.3135,
0.355, 0.3960,0.418, 0.4411,0.449, 0.4600,0.4643, 0.4687,0.471, 0.4743,0.477, 0.4792,0.48, 0.4811,0.4813, 0.4815,0.481, 0.4806,0.4798, 0.4790,0.4786, 0.4782,0.4786, 0.4788,0.481, 0.4844,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 57 4 19
const double ColorTemp::ColabSkin57_4_19_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0430,0.047, 0.0505,0.056, 0.0614,0.077, 0.0963,0.1063, 0.1164,0.123, 0.1294,0.137, 0.1448,0.149, 0.1533,0.154, 0.1544,0.153, 0.1521,0.149, 0.1463,0.148,
0.1496,0.164, 0.1780,0.202, 0.2273,0.242, 0.2585,0.26, 0.2616,0.258, 0.2550,0.2495, 0.2442,0.238, 0.2320,0.229, 0.2258,0.2253, 0.2247,0.232, 0.2394,
0.258, 0.2763,0.292, 0.3087,0.318, 0.3269,0.331, 0.3346,0.337, 0.3387,0.341, 0.3417,0.343, 0.3447,0.345, 0.3457,0.3457, 0.3457,0.3455, 0.3451,0.3445, 0.3439,0.3437, 0.3435,0.3437, 0.3438,0.346, 0.3475,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 57 10 28
const double ColorTemp::ColabSkin57_10_28_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0463,0.048, 0.0505,0.053, 0.0563,0.069, 0.0816,0.088, 0.0961,0.102, 0.1041,0.1085, 0.1135,0.1155, 0.1174,0.1168, 0.1161,0.114, 0.1118,0.1085, 0.1054,0.1074, 0.1094,0.124,
0.1406,0.168, 0.1951,0.223, 0.2325,0.238, 0.2426,0.243, 0.2432,0.242, 0.2391,0.239, 0.2326,0.231, 0.2297,0.234, 0.2309,0.242, 0.2516,0.277, 0.3017,0.324,
0.3456,0.358, 0.3700,0.375, 0.3802,0.3827, 0.3854,0.387, 0.3887,0.39, 0.3913,0.3916, 0.3920,0.3921, 0.3923,0.3921, 0.3920,0.3918, 0.3916,0.3916, 0.3915,0.3915, 0.3915,0.393, 0.3945,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 40 7 19
const double ColorTemp::ColabSkin40_7_19_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0215,0.023, 0.0240,0.026, 0.0275,0.033, 0.0409,0.044, 0.0487,0.051, 0.0532,0.056, 0.0585,0.0595, 0.0608,0.0605, 0.0602,0.059, 0.0581,0.057, 0.0549,0.0555, 0.0562,
0.061, 0.0692,0.08, 0.0922,0.099, 0.1075,0.109, 0.1107,0.11, 0.1098,0.1082, 0.1069,0.1045, 0.1031,0.102, 0.1013,0.1015, 0.1016,0.106, 0.1112,0.123, 0.1348,0.145,
0.1554,0.161, 0.1668,0.169, 0.1716,0.1728, 0.1741,0.175, 0.1756,0.1763, 0.1769,0.1771, 0.1773,0.1773, 0.1774,0.1773, 0.1772,0.177, 0.1769,0.1769, 0.1769,0.1769, 0.1769,0.1777, 0.1784,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 40 17 6
const double ColorTemp::ColabSkin40_17_6_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0314,0.033, 0.0359,0.039, 0.0427,0.054, 0.0668,0.074, 0.0812,0.085, 0.0895,0.094, 0.0985,0.10, 0.1015,0.0991, 0.0984,0.096, 0.0930,0.089, 0.0861,0.085, 0.0828,
0.085, 0.0878,0.094, 0.0995,0.103, 0.1052,0.1035, 0.1026,0.10, 0.0976,0.094, 0.0911,0.088, 0.0840,0.083, 0.0805,0.081, 0.0814,0.09, 0.1006,0.124,
0.1474,0.1685, 0.1885,0.1995, 0.2110,0.216, 0.2204,0.223, 0.2247,0.226, 0.2273,0.2284, 0.2296,0.230, 0.2304,0.2305, 0.2306,0.2305, 0.2303,0.23, 0.2297,0.2296, 0.2294,0.2295, 0.2296,0.231, 0.2321,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 40 4 11
const double ColorTemp::ColabSkin40_4_11_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0209,0.023, 0.0250,0.028, 0.0310,0.039, 0.0497,0.056, 0.0605,0.064, 0.0675,0.072, 0.0758,0.078, 0.0802,0.0803, 0.0804,0.0797, 0.0790,0.078, 0.0758,0.076, 0.0764,0.082,
0.0875,0.098, 0.1072,0.113, 0.1189,0.1187, 0.1185,0.116, 0.1141,0.111, 0.1078,0.104, 0.1012,0.099, 0.0977,0.098, 0.0971,0.101, 0.1049,0.115, 0.1245,0.133,
0.1417,0.147, 0.1513,0.153, 0.1554,0.1564, 0.1575,0.158, 0.1590,0.1598, 0.1606,0.1608, 0.1611,0.1611, 0.1611,0.1609, 0.1608,0.1604, 0.1601,0.160, 0.1598,0.1599, 0.1600,0.1609, 0.1619,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 33 6 15
const double ColorTemp::ColabSkin33_6_15_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0143,0.015, 0.0162,0.0175, 0.0189,0.023, 0.0286,0.031, 0.0342,0.036, 0.0376,0.039, 0.0415,0.0425, 0.0434,0.0432, 0.0431,0.0425, 0.0418,0.041, 0.0396,0.04,
0.0404,0.0444, 0.0488,0.056, 0.0638,0.0689, 0.0735,0.074, 0.0752,0.0745, 0.0741,0.073, 0.0717,0.070, 0.0688,0.0681, 0.0673,0.0673, 0.0674,0.0710, 0.0737,0.0810,
0.0889,0.0960, 0.1023,0.1065, 0.1098,0.1120, 0.1129,0.1135, 0.1145,0.1150, 0.1155,0.1160, 0.1164,0.1165, 0.1167,0.1167, 0.1168,0.1167, 0.1166,0.1165, 0.1164,0.1164, 0.1163,0.1163, 0.1164,0.1170, 0.1174,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 33 15 5
const double ColorTemp::ColabSkin33_15_5_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0212,0.023, 0.0243,0.0265, 0.0289,0.037, 0.0451,0.051, 0.0549,0.058, 0.0605,0.063, 0.0666,0.0675, 0.0686,0.0672, 0.0664,0.065, 0.0627,0.0061, 0.0580,0.0565, 0.0557,
0.057, 0.0590,0.063, 0.0666,0.069, 0.0703,0.0694, 0.0684,0.0666, 0.0651,0.063, 0.0607,0.0585, 0.0559,0.0545, 0.0535,0.0540, 0.0542,0.0610, 0.0672,0.0832,
0.0992,0.1132, 0.1272,0.1345, 0.1425,0.1455, 0.1489,0.1505, 0.1518,0.1527, 0.1536,0.1545, 0.1552,0.1555, 0.1557,0.1558, 0.1559,0.1558, 0.1557,0.1155, 0.1552,0.1551, 0.1550,0.1551, 0.1552,0.1560, 0.1569,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 33 10 15
const double ColorTemp::ColabSkin33_10_15_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0166,0.0175, 0.0183,0.0194, 0.0207,0.0260, 0.0306,0.033, 0.0364,0.0380, 0.0396,0.0415, 0.0431,0.0437, 0.0443,0.0438, 0.0432,0.0420, 0.0409,0.0395, 0.0380,0.0380,
0.0381,0.0415, 0.0456,0.0525, 0.0595,0.0645, 0.0686,0.0695, 0.0705,0.0702, 0.0700,0.0690, 0.0681,0.0667, 0.0655,0.065, 0.0644,0.0648, 0.0650,0.0695, 0.0739,0.0852,
0.0955,0.1040, 0.1145,0.1196, 0.1249,0.1271, 0.1293,0.1305, 0.1314,0.1322, 0.1327,0.1332, 0.1337,0.1338, 0.1340,0.1340, 0.1341,0.1340, 0.1340,0.1339, 0.1338,0.1338, 0.1338,0.1338, 0.1338,0.1345, 0.1349,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 24 5 6
const double ColorTemp::ColabSkin24_5_6_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0086,0.0095, 0.0102,0.0112, 0.0127,0.0167, 0.0203,0.0225, 0.0248,0.0265, 0.0277,0.0295, 0.0309,0.0315, 0.0325,0.0324, 0.0323,0.0319, 0.0315,0.0307, 0.0299,0.0298,
0.0297,0.0315, 0.0330,0.0365, 0.0392,0.0412, 0.0427,0.0424, 0.0421,0.0410, 0.0402,0.0390, 0.0377,0.0365, 0.0351,0.0345, 0.0337,0.0337, 0.0336,0.0356, 0.0374,0.0415,
0.0470,0.0512, 0.0554,0.0575, 0.0601,0.0610, 0.0620,0.0625, 0.0630,0.0634, 0.0637,0.0640, 0.0643,0.0645, 0.0646,0.0646, 0.0646,0.0645, 0.0644,0.0643, 0.0642,0.0642, 0.0641,0.0641, 0.0641,0.0645, 0.0649,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 26 18 18
const double ColorTemp::ColabSkin26_18_18_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0135,0.0137, 0.0138,0.0139, 0.0140,0.0163, 0.0187,0.0202, 0.0215,0.0220, 0.0224,0.0228, 0.0231,0.0227, 0.0222,0.0212, 0.0202,0.0189, 0.0174,0.0161, 0.0146,0.0143,
0.0140,0.0163, 0.0184,0.0224, 0.0268,0.0291, 0.0331,0.0348, 0.0358,0.0366, 0.0374,0.0378, 0.0380,0.0380, 0.0379,0.0380, 0.0381,0.0388, 0.0394,0.0440, 0.0490,
0.0605, 0.0720,0.0821, 0.0921,0.0976, 0.1030,0.1056, 0.1076,0.1087, 0.1097,0.1103, 0.1108,0.1111, 0.1115,0.1115, 0.1116,0.1117, 0.1118,0.1118, 0.1119,0.1119, 0.1120,0.1120, 0.1121,0.1121, 0.1120,0.1123, 0.1126,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 24 7 5
const double ColorTemp::ColabSkin24_7_5_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0093,0.0105, 0.0111,0.0125, 0.0137,0.0180, 0.0221,0.0245, 0.0270,0.0285, 0.0301,0.0316, 0.0336,0.0345, 0.0353,0.0350, 0.0349,0.0343, 0.0338,0.0329, 0.0320,0.0317, 0.0315,
0.0328, 0.0342,0.0368, 0.0397,0.0412, 0.0424,0.0420, 0.0415,0.0404, 0.0393,0.0379, 0.0366,0.0352, 0.0337,0.0330, 0.0323,0.0322, 0.0322,0.0344, 0.0367,0.0422, 0.0479,0.0529,
0.0578,0.0606, 0.0633,0.0644, 0.0656,0.0662, 0.0667,0.0670, 0.0674,0.0678, 0.0681,0.0683, 0.0684,0.0684, 0.0684,0.0683, 0.0683,0.0682, 0.0680,0.0679, 0.0678,0.0678, 0.0679,0.0683, 0.0688,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 24 4 2
const double ColorTemp::ColabSkin20_4_2_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0064,0.0074, 0.0080,0.00903, 0.0104,0.0139, 0.0174,0.0189, 0.0216,0.0222, 0.0243,0.0258, 0.0274,0.0282, 0.0291,0.0290, 0.0290,0.0288, 0.0284,0.0278, 0.0272,0.0270, 0.0267,0.0276,
0.0285,0.0302, 0.0320,0.0327, 0.0335,0.0328, 0.0321,0.0311, 0.0299,0.0280, 0.0272,0.0259, 0.0246,0.0239, 0.0232,0.0230, 0.0229,0.0243, 0.0256,0.0291, 0.0324,0.0354,
0.0385,0.0401, 0.0418,0.0425, 0.0432,0.0435, 0.0439,0.0442, 0.0444,0.0447, 0.0450,0.0451, 0.0452,0.0452, 0.0452,0.0451, 0.0450,0.0449, 0.0448,0.0447, 0.0446,0.0447, 0.0447,0.0450, 0.0454,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 98 -2 10
const double ColorTemp::ColabSkin98_m2_10_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1627,0.1870, 0.2115,0.2480, 0.2860,0.3870, 0.4878,0.5460, 0.6050,0.6460, 0.6874,0.7355, 0.7836,0.8130, 0.8424,0.8494, 0.8543,0.8520, 0.8508,0.8390, 0.8267,0.8274, 0.8280,
0.8680, 0.9076,0.9600, 1.0497,1.089, 1.1190,1.10, 1.0836,1.045, 1.0140,0.975, 0.9305,0.884, 0.8486,0.826, 0.8042,0.7980, 0.7895,0.8093, 0.8292,0.884, 0.9376,0.987,
1.0341,1.059, 1.0892,1.104, 1.1125,1.1253, 1.1255,1.131, 1.1375,1.145, 1.1520,1.155, 1.1585,1.158, 1.1574,1.1548, 1.1523,1.148, 1.1439,1.141, 1.1394,1.141, 1.1423,1.151, 1.1619,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 90 -1 20
const double ColorTemp::ColabSkin90_m1_20_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1228,0.138, 0.1532,0.175, 0.1987,0.261, 0.3279,0.365, 0.4022,0.428, 0.4537,0.4842, 0.5147,0.5337, 0.5521,0.557, 0.5611,0.5602, 0.5593,0.551, 0.5438,0.548,
0.5527,0.593, 0.6334,0.703, 0.7732,0.8135, 0.8543,0.851, 0.8474,0.829, 0.8105,0.786, 0.7613,0.736, 0.7105,0.697, 0.6835,0.679, 0.6750,0.6895, 0.7045,0.743,
0.7832,0.818, 0.8530,0.873, 0.8929,0.899, 0.9099,0.914, 0.9197,0.924, 0.9282,0.933, 0.9380,0.9395, 0.9419,0.9416, 0.9413,0.9398, 0.9382,0.9357, 0.9332,0.9322, 0.9306,0.9315, 0.9322,0.939, 0.9452,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 95 0 4
const double ColorTemp::ColabSkin95_0_4_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1614,0.1865, 0.2118,0.2495, 0.2889,0.392, 0.4969,0.557, 0.6185,0.6605, 0.7035,0.749, 0.8018,0.832, 0.8605,0.865, 0.8696,0.866, 0.8633,0.849, 0.8365,0.834,
0.8308,0.861, 0.8911,0.946, 1.0030,1.025, 1.0490,1.025, 1.0030,0.964, 0.9278,0.884, 0.8407,0.7985, 0.7565,0.734, 0.7107,0.6985, 0.6962,0.718, 0.7416,0.803,
0.8642,0.919, 0.9733,1.001, 1.0349,1.051, 1.0609,1.068, 1.0747,1.081, 1.0872,1.095, 1.1021,1.105, 1.1089,1.1085, 1.1079,1.1055, 1.1027,1.098, 1.0940,1.091, 1.0892,1.0905, 1.0923,1.102, 1.1123,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 81 2 14
const double ColorTemp::ColabSkin81_2_14_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1029,0.116, 0.1285,0.148, 0.1672,0.222, 0.2774,0.311, 0.3412,0.362, 0.3849,0.410, 0.4359,0.451, 0.4659,0.468, 0.4706,0.4685, 0.4664,0.4685, 0.4512,0.4525, 0.4536,
0.461, 0.5076,0.551, 0.6035,0.6295, 0.6559,0.6495, 0.6442,0.627, 0.6112,0.5905, 0.5691,0.537, 0.5266,0.515, 0.5039,0.501, 0.4975,0.5125, 0.5283,0.568, 0.6087,0.643,
0.6799,0.700, 0.7200,0.729, 0.7370,0.7415, 0.7461,0.750, 0.7536,0.759, 0.7620,0.764, 0.7655,0.7653, 0.7651,0.764, 0.7626,0.761, 0.7583,0.7572, 0.7561,0.7567, 0.7575,0.758, 0.7685,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 87 3 10
const double ColorTemp::ColabSkin87_3_10_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1295,0.146, 0.1639,0.190, 0.2160,0.291, 0.3626,0.405, 0.4480,0.476, 0.5066,0.541, 0.5743,0.593, 0.6136,0.616, 0.6186,0.614, 0.6119,0.601, 0.5911,0.5905,
0.5897,0.623, 0.6460,0.697, 0.7483,0.773, 0.7992,0.788, 0.7759,0.752, 0.7287,0.699, 0.6712,0.642, 0.6141,0.598, 0.5835,0.579, 0.5750,0.596, 0.6162,0.669,
0.7239,0.772, 0.8193,0.845, 0.8728,0.888, 0.8954,0.901, 0.9073,0.912, 0.9171,0.922, 0.9281,0.931, 0.9328,0.9325, 0.9323,0.931, 0.9289,0.926, 0.9232,0.9215, 0.9201,0.921, 0.9220,0.929, 0.9364,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 77 12 21
const double ColorTemp::ColabSkin77_12_21_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.1039,0.111, 0.1205,0.132, 0.1448,0.185, 0.2261,0.249, 0.2734,0.287, 0.3028,0.318, 0.3364,0.345, 0.3525,0.351, 0.3499,0.345, 0.3397,0.3295, 0.3224,0.329, 0.3234,
0.349, 0.3729,0.418, 0.4625,0.490, 0.5173,0.5185, 0.5196,0.511, 0.5045,0.492, 0.4807,0.467, 0.4543,0.447, 0.4410,0.4409, 0.4407,0.464, 0.4872,0.544, 0.6020,0.6522,
0.7029,0.731, 0.7588,0.771, 0.7823,0.787, 0.7939,0.798, 0.8017,0.805, 0.8090,0.8103, 0.8115,0.8117, 0.8118,0.8111, 0.8104,0.8193, 0.8081,0.8076, 0.8070,0.8073, 0.8077,0.812, 0.8162,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Skin 70 7 32
const double ColorTemp::ColabSkin70_7_32_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0695,0.074, 0.0777,0.084, 0.0890,0.104, 0.1321,0.144, 0.1565,0.164, 0.1713,0.1795, 0.1889,0.194, 0.1978,0.198, 0.1983,0.196, 0.1939,0.189, 0.1853,0.189,
0.1933,0.219, 0.2458,0.291, 0.3362,0.367, 0.3974,0.405, 0.4120,0.411, 0.4101,0.406, 0.4007,0.394, 0.3877,0.385, 0.3816,0.3817, 0.3819,0.395, 0.4081,0.440,
0.4721,0.498, 0.5284,0.544, 0.5598,0.566, 0.5730,0.577, 0.5801,0.5825, 0.5848,0.587, 0.5890,0.5895, 0.5901,0.5903, 0.5903,0.59, 0.5897,0.5892, 0.5887,0.5885, 0.5884,0.5885, 0.5886,0.5896, 0.5934,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Sky 60 0 -31
const double ColorTemp::ColabSky60_0_m31_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0752,0.094, 0.1121,0.141, 0.1699,0.243, 0.3150,0.357, 0.4015,0.432, 0.4631,0.497, 0.5325,0.553, 0.5730,0.574, 0.5758,0.572, 0.5695,0.559, 0.5503,0.539,
0.5284,0.5175, 0.5066,0.493, 0.4800,0.459, 0.4336,0.401, 0.3684,0.333, 0.3003,0.265, 0.2313,0.199, 0.1695,0.167, 0.1349,0.129, 0.1234,0.136, 0.1489,0.184,
0.2212,0.253, 0.2858,0.303, 0.3218,0.329, 0.3370,0.341, 0.3440,0.348, 0.3512,0.355, 0.3606,0.363, 0.3658,0.3653, 0.3649,0.3625, 0.3611,0.358, 0.3544,0.352, 0.3502,0.3512, 0.3529,0.359, 0.3660,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
//spectral data ColorLab : Sky 42 0 -24
const double ColorTemp::ColabSky42_0_m24_spect[97] = {
0.0,0.0,0.0,0.0,0.0,0.0,
0.0336,0.041, 0.0501,0.063, 0.0761,0.103, 0.1412,0.151, 0.1799,0.193, 0.2076,0.223, 0.2387,0.248, 0.2569,0.2575, 0.2581,0.256, 0.2553,0.250, 0.2466,0.2411,
0.2368,0.2318, 0.2268,0.2205, 0.2145,0.204, 0.1935,0.179, 0.1641,0.149, 0.1335,0.118, 0.1025,0.087, 0.0748,0.067, 0.0593,0.056, 0.0541,0.059, 0.0655,0.081,
0.0979,0.112, 0.1269,0.134, 0.1430,0.147, 0.1497,0.151, 0.1529,0.1545, 0.1561,0.158, 0.1603,0.1616, 0.1627,0.1625, 0.1623,0.1614, 0.1605,0.159, 0.1575,0.1567, 0.1557,0.1563, 0.1569,0.159, 0.1627,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
};
/*
* Name: XYZtoCorColorTemp.c
*
* Author: Bruce Justin Lindbloom
*
* Copyright (c) 2003 Bruce Justin Lindbloom. All rights reserved.
*
*
* Description:
* This is an implementation of Robertson's method of computing the correlated color
* temperature of an XYZ color. It can compute correlated color temperatures in the
* range [1666.7K, infinity].
*
* Reference:
* "Color Science: Concepts and Methods, Quantitative Data and Formulae", Second Edition,
* Gunter Wyszecki and W. S. Stiles, John Wiley & Sons, 1982, pp. 227, 228.
*/
//adaptation to RT by J.Desmis
#include <float.h>
/* LERP(a,b,c) = linear interpolation macro, is 'a' when c == 0.0 and 'b' when c == 1.0 */
#define LERP(a,b,c) (((b) - (a)) * (c) + (a))
int ColorTemp::XYZtoCorColorTemp(double x0, double y0, double z0, double &temp)
{
typedef struct UVT {
double u;
double v;
double t;
} UVT;
double rt[31] = { /* reciprocal temperature (K) */
DBL_MIN, 10.0e-6, 20.0e-6, 30.0e-6, 40.0e-6, 50.0e-6,
60.0e-6, 70.0e-6, 80.0e-6, 90.0e-6, 100.0e-6, 125.0e-6,
150.0e-6, 175.0e-6, 200.0e-6, 225.0e-6, 250.0e-6, 275.0e-6,
300.0e-6, 325.0e-6, 350.0e-6, 375.0e-6, 400.0e-6, 425.0e-6,
450.0e-6, 475.0e-6, 500.0e-6, 525.0e-6, 550.0e-6, 575.0e-6,
600.0e-6
};
UVT uvt[31] = {
{0.18006, 0.26352, -0.24341},
{0.18066, 0.26589, -0.25479},
{0.18133, 0.26846, -0.26876},
{0.18208, 0.27119, -0.28539},
{0.18293, 0.27407, -0.30470},
{0.18388, 0.27709, -0.32675},
{0.18494, 0.28021, -0.35156},
{0.18611, 0.28342, -0.37915},
{0.18740, 0.28668, -0.40955},
{0.18880, 0.28997, -0.44278},
{0.19032, 0.29326, -0.47888},
{0.19462, 0.30141, -0.58204},
{0.19962, 0.30921, -0.70471},
{0.20525, 0.31647, -0.84901},
{0.21142, 0.32312, -1.0182},
{0.21807, 0.32909, -1.2168},
{0.22511, 0.33439, -1.4512},
{0.23247, 0.33904, -1.7298},
{0.24010, 0.34308, -2.0637},
{0.24792, 0.34655, -2.4681},
{0.25591, 0.34951, -2.9641},
{0.26400, 0.35200, -3.5814},
{0.27218, 0.35407, -4.3633},
{0.28039, 0.35577, -5.3762},
{0.28863, 0.35714, -6.7262},
{0.29685, 0.35823, -8.5955},
{0.30505, 0.35907, -11.324},
{0.31320, 0.35968, -15.628},
{0.32129, 0.36011, -23.325},
{0.32931, 0.36038, -40.770},
{0.33724, 0.36051, -116.45}
};
double us, vs, p, di, dm;
int i;
if ((x0 < 1.0e-20) && (y0 < 1.0e-20) && (z0 < 1.0e-20))
return -1; /* protect against possible divide-by-zero failure */
us = (4.0 * x0) / (x0 + 15.0 * y0 + 3.0 * z0);
vs = (6.0 * y0) / (x0 + 15.0 * y0 + 3.0 * z0);
dm = 0.0;
for (i = 0; i < 31; i++) {
di = (vs - uvt[i].v) - uvt[i].t * (us - uvt[i].u);
if ((i > 0) && (((di < 0.0) && (dm >= 0.0)) || ((di >= 0.0) && (dm < 0.0))))
break; /* found lines bounding (us, vs) : i-1 and i */
dm = di;
}
if (i == 31)
return(-1); /* bad XYZ input, color temp would be less than minimum of 1666.7 degrees, or too far towards blue */
di = di / sqrt(1.0 + uvt[i ].t * uvt[i ].t);
dm = dm / sqrt(1.0 + uvt[i - 1].t * uvt[i - 1].t);
p = dm / (dm - di); /* p = interpolation parameter, 0.0 : i-1, 1.0 : i */
p = 1.0 / (LERP(rt[i - 1], rt[i], p));
temp = p;
return 0; /* success */
}
void ColorTemp::curvecolor(double satind, double satval, double &sres, double parsat) {
if (satind >=0.0) {
sres = (1.-(satind)/100.)*satval+(satind)/100.*(1.-SQR(SQR(1.-min(satval,1.0))));
if (sres>parsat) sres=parsat;
if (sres<0.) sres=0.;
} else {
if (satind < -0.1)
sres = satval*(1.+(satind)/100.);
}
}
void ColorTemp::curvecolorfloat(float satind, float satval, float &sres, float parsat) {
if (satind >=0.0f) {
sres = (1.-(satind)/100.f)*satval+(satind)/100.f*(1.f-SQR(SQR(1.f-min(satval,1.0f))));
if (sres>parsat) sres=parsat;
if (sres<0.f) sres=0.f;
} else {
if (satind < -0.1f)
sres = satval*(1.f+(satind)/100.f);
}
}
void ColorTemp::curveJ (double br, double contr, int db, LUTf & outCurve, LUTu & histogram ) {
LUTf dcurve(65536,0);
int skip=1;
// check if brightness curve is needed
if (br>0.00001 || br<-0.00001) {
std::vector<double> brightcurvePoints;
brightcurvePoints.resize(9);
brightcurvePoints.at(0) = double(DCT_NURBS);
brightcurvePoints.at(1) = 0.; // black point. Value in [0 ; 1] range
brightcurvePoints.at(2) = 0.; // black point. Value in [0 ; 1] range
if (br>0) {
brightcurvePoints.at(3) = 0.1; // toe point
brightcurvePoints.at(4) = 0.1+br/150.0; //value at toe point
brightcurvePoints.at(5) = 0.7; // shoulder point
brightcurvePoints.at(6) = min(1.0,0.7+br/300.0); //value at shoulder point
} else {
brightcurvePoints.at(3) = 0.1-br/150.0; // toe point
brightcurvePoints.at(4) = 0.1; // value at toe point
brightcurvePoints.at(5) = min(1.0,0.7-br/300.0); // shoulder point
brightcurvePoints.at(6) = 0.7; // value at shoulder point
}
brightcurvePoints.at(7) = 1.; // white point
brightcurvePoints.at(8) = 1.; // value at white point
DiagonalCurve* brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip);
// Applying brightness curve
for (int i=0; i<32768; i++) {
// change to [0,1] range
float val = (float)i / 32767.0;
// apply brightness curve
val = brightcurve->getVal (val);
// store result in a temporary array
dcurve[i] = CLIPD(val);
}
delete brightcurve;
}
else {
// for (int i=0; i<32768; i++) { // L values range up to 32767, higher values are for highlight overflow
for (int i=0; i<(32768*db); i++) { // L values range up to 32767, higher values are for highlight overflow
// set the identity curve in the temporary array
dcurve[i] = (float)i / (db*32768.0f);
}
}
if (contr>0.00001 || contr<-0.00001) {
// compute mean luminance of the image with the curve applied
int sum = 0;
float avg = 0;
//float sqavg = 0;
for (int i=0; i<32768; i++) {
avg += dcurve[i] * histogram[i];//approximation for average : usage of L (lab) instead of J
sum += histogram[i];
}
avg /= sum;
std::vector<double> contrastcurvePoints;
contrastcurvePoints.resize(9);
contrastcurvePoints.at(0) = double(DCT_NURBS);
contrastcurvePoints.at(1) = 0.; // black point. Value in [0 ; 1] range
contrastcurvePoints.at(2) = 0.; // black point. Value in [0 ; 1] range
contrastcurvePoints.at(3) = avg-avg*(0.6-contr/250.0); // toe point
contrastcurvePoints.at(4) = avg-avg*(0.6+contr/250.0); // value at toe point
contrastcurvePoints.at(5) = avg+(1-avg)*(0.6-contr/250.0); // shoulder point
contrastcurvePoints.at(6) = avg+(1-avg)*(0.6+contr/250.0); // value at shoulder point
contrastcurvePoints.at(7) = 1.; // white point
contrastcurvePoints.at(8) = 1.; // value at white point
DiagonalCurve* contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS/skip);
// apply contrast enhancement
for (int i=0; i<(32768*db); i++) {
dcurve[i] = contrastcurve->getVal (dcurve[i]);
}
delete contrastcurve;
}
// for (int i=0; i<32768; i++) outCurve[i] = 32768.0*dcurve[i];
for (int i=0; i<(db*32768); i++) outCurve[i] = db*32768.0*dcurve[i];
}
void ColorTemp::curveJfloat (float br, float contr, int db, LUTf & outCurve, LUTu & histogram ) {
LUTf dcurve(65536,0);
int skip=1;
// check if brightness curve is needed
if (br>0.00001f || br<-0.00001f) {
std::vector<double> brightcurvePoints;
brightcurvePoints.resize(9);
brightcurvePoints.at(0) = double(DCT_NURBS);
brightcurvePoints.at(1) = 0.f; // black point. Value in [0 ; 1] range
brightcurvePoints.at(2) = 0.f; // black point. Value in [0 ; 1] range
if (br>0) {
brightcurvePoints.at(3) = 0.1f; // toe point
brightcurvePoints.at(4) = 0.1f+br/150.0f; //value at toe point
brightcurvePoints.at(5) = 0.7f; // shoulder point
brightcurvePoints.at(6) = min(1.0f,0.7f+br/300.0f); //value at shoulder point
} else {
brightcurvePoints.at(3) = 0.1f-br/150.0f; // toe point
brightcurvePoints.at(4) = 0.1f; // value at toe point
brightcurvePoints.at(5) = min(1.0f,0.7f-br/300.0f); // shoulder point
brightcurvePoints.at(6) = 0.7f; // value at shoulder point
}
brightcurvePoints.at(7) = 1.f; // white point
brightcurvePoints.at(8) = 1.f; // value at white point
DiagonalCurve* brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip);
// Applying brightness curve
for (int i=0; i<32768; i++) {
// change to [0,1] range
float val = (float)i / 32767.0f;
// apply brightness curve
val = brightcurve->getVal (val);
// store result in a temporary array
dcurve[i] = CLIPD(val);
}
delete brightcurve;
}
else {
// for (int i=0; i<32768; i++) { // L values range up to 32767, higher values are for highlight overflow
for (int i=0; i<(32768*db); i++) { // L values range up to 32767, higher values are for highlight overflow
// set the identity curve in the temporary array
dcurve[i] = (float)i / (db*32768.0f);
}
}
if (contr>0.00001f || contr<-0.00001f) {
// compute mean luminance of the image with the curve applied
int sum = 0;
float avg = 0;
//float sqavg = 0;
for (int i=0; i<32768; i++) {
avg += dcurve[i] * histogram[i];//approximation for average : usage of L (lab) instead of J
sum += histogram[i];
}
avg /= sum;
//printf("avg=%f\n",avg);
std::vector<double> contrastcurvePoints;
contrastcurvePoints.resize(9);
contrastcurvePoints.at(0) = double(DCT_NURBS);
contrastcurvePoints.at(1) = 0.f; // black point. Value in [0 ; 1] range
contrastcurvePoints.at(2) = 0.f; // black point. Value in [0 ; 1] range
contrastcurvePoints.at(3) = avg-avg*(0.6f-contr/250.0f); // toe point
contrastcurvePoints.at(4) = avg-avg*(0.6f+contr/250.0f); // value at toe point
contrastcurvePoints.at(5) = avg+(1-avg)*(0.6f-contr/250.0f); // shoulder point
contrastcurvePoints.at(6) = avg+(1-avg)*(0.6f+contr/250.0f); // value at shoulder point
contrastcurvePoints.at(7) = 1.f; // white point
contrastcurvePoints.at(8) = 1.f; // value at white point
DiagonalCurve* contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS/skip);
// apply contrast enhancement
for (int i=0; i<(32768*db); i++) {
dcurve[i] = contrastcurve->getVal (dcurve[i]);
}
delete contrastcurve;
}
// for (int i=0; i<32768; i++) outCurve[i] = 32768.0*dcurve[i];
for (int i=0; i<(db*32768); i++) outCurve[i] = db*32768.0f*dcurve[i];
}
void ColorTemp::cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00,double &CAM02BB01,double &CAM02BB02,double &CAM02BB10,double &CAM02BB11,double &CAM02BB12,double &CAM02BB20,double &CAM02BB21,double &CAM02BB22, double adap ) {
// CIECAT02 - J.Desmis January 2012 review September 2012
const double whiteD50p[3]={0.9646019585,1.0,0.8244507152};//calculate with these tools
double cam_dest[3]={0.,0.,0.};
double cam_orig[3]={0.,0.,0.};
const double CAT02[3][3] = {{0.7328, 0.4296, -0.1624},//CAT02 2002
{-0.7036, 1.6975, 0.0061},
{0.0030, 0.0136, 0.9834}};
const double INVCAT02[3][3] = {{1.09612382083551, -0.278869000218287, 0.182745179382773}, //Inverse CAT02
{0.454369041975359, 0.4735331543070412, 0.0720978037172291},
{-0.009627608738442936, -0.00569803121611342, 1.01532563995454}};
double inv_white_orig[3][3]={{0., 0., 0.},
{0., 0., 0.},
{0., 0., 0.}};
double intermed[3][3]={{0., 0., 0.},
{0., 0., 0.},
{0., 0., 0.}};
double intermed_2[3][3]={{0., 0., 0.},
{0., 0., 0.},
{0., 0., 0.}};
double CAM02[3][3]= {{0., 0., 0.},
{0., 0., 0.},
{0., 0., 0.}};
double D=adap;
//white destination Wd : RT use always D50
cam_dest[0]=CAT02[0][0]*whiteD50p[0]+CAT02[0][1]*whiteD50p[1]+CAT02[0][2]*whiteD50p[2];//Cone reponse RoD
cam_dest[1]=CAT02[1][0]*whiteD50p[0]+CAT02[1][1]*whiteD50p[1]+CAT02[1][2]*whiteD50p[2];//GaD
cam_dest[2]=CAT02[2][0]*whiteD50p[0]+CAT02[2][1]*whiteD50p[1]+CAT02[2][2]*whiteD50p[2];//BeD
//origin white Ws : A, D65, custom, etc.
cam_orig[0]=CAT02[0][0]*Xw+CAT02[0][1]*Yw+CAT02[0][2]*Zw;//Cone reponse RoS
cam_orig[1]=CAT02[1][0]*Xw+CAT02[1][1]*Yw+CAT02[1][2]*Zw;
cam_orig[2]=CAT02[2][0]*Xw+CAT02[2][1]*Yw+CAT02[2][2]*Zw;
//inverse white
inv_white_orig[0][0]=1./cam_orig[0];// 1/RoS
inv_white_orig[1][1]=1./cam_orig[1];// 1/GaS
inv_white_orig[2][2]=1./cam_orig[2];// 1/BeS
//intermediates computation
for(int i=0; i< 3;i++)
for(int j=0; j<3 ; j++)
intermed[i][j]=inv_white_orig[i][i]*CAT02[i][j];
for(int i=0; i< 3;i++)
for(int j=0; j<3 ; j++)
intermed_2[i][j]=cam_dest[i]*intermed[i][j];
//and CAM02
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
for(int k=0; k<3; k++)
CAM02[i][j]+=INVCAT02[i][k]*intermed_2[k][j];
//adaptation jdc : slightly different from CIECAM02 : Rc=(Yw(D/Rw)+(1-D))*R , but it's work ! true at 0 and 1
CAM02[1][1]=(CAM02[1][1]-1.0)*D + 1.0;
CAM02[0][0]=(CAM02[0][0]-1.0)*D + 1.0;
CAM02[2][2]=(CAM02[2][2]-1.0)*D + 1.0;
CAM02[0][1]*=D;
CAM02[0][2]*=D;
CAM02[1][0]*=D;
CAM02[1][2]*=D;
CAM02[2][0]*=D;
CAM02[2][1]*=D;
//CAT02 matrix with D adaptation
CAM02BB00=CAM02[0][0];CAM02BB01=CAM02[0][1];CAM02BB02=CAM02[0][2];
CAM02BB10=CAM02[1][0];CAM02BB11=CAM02[1][1];CAM02BB12=CAM02[1][2];
CAM02BB20=CAM02[2][0];CAM02BB21=CAM02[2][1];CAM02BB22=CAM02[2][2];
}
void ColorTemp::temp2mulxyz (double tem, double gree, Glib::ustring method ,double &Xxyz, double &Zxyz) {
double xD, yD, x_D, y_D, interm;
double x, y, z;
if (method == "Daylight" ) spectrum_to_xyz_preset(Daylight5300_spect, x, y, z);
else if(method == "Cloudy" ) spectrum_to_xyz_preset(Cloudy6200_spect, x, y, z);
else if(method == "Shade" ) spectrum_to_xyz_preset(Shade7600_spect, x, y, z);
else if(method == "Tungsten" ) spectrum_to_xyz_preset(A2856_spect, x, y, z);
else if(method == "Fluo F1" ) spectrum_to_xyz_preset(FluoF1_spect, x, y, z);
else if(method == "Fluo F2" ) spectrum_to_xyz_preset(FluoF2_spect, x, y, z);
else if(method == "Fluo F3" ) spectrum_to_xyz_preset(FluoF3_spect, x, y, z);
else if(method == "Fluo F4" ) spectrum_to_xyz_preset(FluoF4_spect, x, y, z);
else if(method == "Fluo F5" ) spectrum_to_xyz_preset(FluoF5_spect, x, y, z);
else if(method == "Fluo F6" ) spectrum_to_xyz_preset(FluoF6_spect, x, y, z);
else if(method == "Fluo F7" ) spectrum_to_xyz_preset(FluoF7_spect, x, y, z);
else if(method == "Fluo F8" ) spectrum_to_xyz_preset(FluoF8_spect, x, y, z);
else if(method == "Fluo F9" ) spectrum_to_xyz_preset(FluoF9_spect, x, y, z);
else if(method == "Fluo F10" ) spectrum_to_xyz_preset(FluoF10_spect, x, y, z);
else if(method == "Fluo F11" ) spectrum_to_xyz_preset(FluoF11_spect, x, y, z);
else if(method == "Fluo F12" ) spectrum_to_xyz_preset(FluoF12_spect, x, y, z);
else if(method == "HMI Lamp" ) spectrum_to_xyz_preset(HMI_spect, x, y, z);
else if(method == "GTI Lamp" ) spectrum_to_xyz_preset(GTI_spect, x, y, z);
else if(method == "JudgeIII Lamp" ) spectrum_to_xyz_preset(JudgeIII_spect, x, y, z);
else if(method == "Solux Lamp 3500K" ) spectrum_to_xyz_preset(Solux3500_spect, x, y, z);
else if(method == "Solux Lamp 4100K" ) spectrum_to_xyz_preset(Solux4100_spect, x, y, z);
else if(method == "Solux Lamp 4700K" ) spectrum_to_xyz_preset(Solux4700_spect, x, y, z);
else if(method == "NG Solux Lamp 4700K" ) spectrum_to_xyz_preset(NG_Solux4700_spect, x, y, z);
else if(method == "LED LSI Lumelex 2040") spectrum_to_xyz_preset(NG_LEDLSI2040_spect, x, y, z);
else if(method == "LED CRS SP12 WWMR16" ) spectrum_to_xyz_preset(NG_CRSSP12WWMR16_spect, x, y, z);
else if(method == "Flash 5500K" ) spectrum_to_xyz_preset(Flash5500_spect, x, y, z);
else if(method == "Flash 6000K" ) spectrum_to_xyz_preset(Flash6000_spect, x, y, z);
else if(method == "Flash 6500K" ) spectrum_to_xyz_preset(Flash6500_spect, x, y, z);
else {
// otherwise we use the Temp+Green generic solution
if (tem <= 4000) {
// if temperature is between 2000K and 4000K we use blackbody, because there will be no Daylight reference below 4000K...
// of course, the previous version of RT used the "magical" but wrong formula of U.Fuchs (Ufraw).
spectrum_to_xyz_blackbody(0., 0., tem, x, y, z);
}
else {
// from 4000K up to 25000K: using the D illuminant (daylight) which is standard
double m1, m2;
if (tem<=7000)
x_D = -4.6070e9/(tem*tem*tem) + 2.9678e6/(tem*tem) + 0.09911e3/tem + 0.244063;
else if (tem <=25000)
x_D = -2.0064e9/(tem*tem*tem) + 1.9018e6/(tem*tem) + 0.24748e3/tem + 0.237040;
else if (tem >25000)
x_D = -2.0064e9/(tem*tem*tem) + 1.9018e6/(tem*tem) + 0.24748e3/tem + 0.237040 - ((tem-25000)/25000)*0.025;//Jacques empirical adjustemnt for very high temp (underwater !)
y_D = -3.0*x_D*x_D + 2.87*x_D - 0.275;
//calculate D -daylight in function of s0, s1, s2 and temp ==> x_D y_D
//S(lamda)=So(lambda)+m1*s1(lambda)+m2*s2(lambda)
interm=(0.0241+0.2562*x_D-0.734*y_D);
m1=(-1.3515-1.7703*x_D+5.9114*y_D)/interm;
m2=(0.03-31.4424*x_D+30.0717*y_D)/interm;
spectrum_to_xyz_daylight(m1, m2, 0., x, y, z);
xD=x;yD=y;
}
}
xD=x; yD=y;
double X = xD/yD;
double Z = (1.0-xD-yD)/yD;
Xxyz=X;
Zxyz=Z;
//printf("Xxyz=%f Zxyz=%f\n",Xxyz,Zxyz);
}
void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul) {
clip (temp, green, equal);
//printf("temp=%d green=%.3f equal=%.3f\n", (int)temp, (float) green, (float) equal);
//variables for CRI and display Lab, and palette
bool CRI_type=false;
double xD, yD, x_D, y_D, interm;
double m1, m2;
double xp,yp;
double x, y, z, xx, yy, zz;
double Xchk[50],Ychk[50],Zchk[50]; //50 : I think it's a good limit for number of color : for CRI and Palette
double Xcam02[50],Ycam02[50],Zcam02[50];
double Xcam02pal[50],Ycam02pal[50],Zcam02pal[50];
double XchkLamp[50],YchkLamp[50],ZchkLamp[50];
double Xcam02Lamp[50],Ycam02Lamp[50],Zcam02Lamp[50];
double Xpal[50],Ypal[50],Zpal[50];
double tempw;
const double epsilon=0.008856;//Lab
const double whiteD50[3]={0.9646019585,1.0,0.8244507152};//calculate with this tool : spect 5nm
double CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22;//for CIECAT02
double xr[50],yr[50],zr[50];
double fx[50],fy[50],fz[50];
double Llamp[50],alamp[50],blamp[50];
double Lbb[50],abb[50],bbb[50];
double Lpal[50],apal[50],bpal[50];
int palet=-1;
bool palette=true;
// double tempalet; // correlated temperature
// We first test for specially handled methods
if (method == "Daylight" ) {spectrum_to_xyz_preset(Daylight5300_spect, x, y, z);palet=0; /*tempalet=5300;*/ }
else if(method == "Cloudy" ) {spectrum_to_xyz_preset(Cloudy6200_spect, x, y, z);palet=1; /*tempalet=6200;*/ }
else if(method == "Shade" ) {spectrum_to_xyz_preset(Shade7600_spect, x, y, z);palet=2; /*tempalet=7600;*/ }
else if(method == "Tungsten" ) {spectrum_to_xyz_preset(A2856_spect, x, y, z);palet=3; /*tempalet=2856;*/ }
else if(method == "Fluo F1" ) {spectrum_to_xyz_preset(FluoF1_spect, x, y, z);palet=4; /*tempalet=6430;*/ }
else if(method == "Fluo F2" ) {spectrum_to_xyz_preset(FluoF2_spect, x, y, z);palet=5; /*tempalet=4230;*/ }
else if(method == "Fluo F3" ) {spectrum_to_xyz_preset(FluoF3_spect, x, y, z);palet=6; /*tempalet=3450;*/ }
else if(method == "Fluo F4" ) {spectrum_to_xyz_preset(FluoF4_spect, x, y, z);palet=7; /*tempalet=2940;*/ }
else if(method == "Fluo F5" ) {spectrum_to_xyz_preset(FluoF5_spect, x, y, z);palet=8; /*tempalet=6350;*/ }
else if(method == "Fluo F6" ) {spectrum_to_xyz_preset(FluoF6_spect, x, y, z);palet=9; /*tempalet=4150;*/ }
else if(method == "Fluo F7" ) {spectrum_to_xyz_preset(FluoF7_spect, x, y, z);palet=10; /*tempalet=6500;*/ }
else if(method == "Fluo F8" ) {spectrum_to_xyz_preset(FluoF8_spect, x, y, z);palet=11; /*tempalet=5020;*/ }
else if(method == "Fluo F9" ) {spectrum_to_xyz_preset(FluoF9_spect, x, y, z);palet=12; /*tempalet=4330;*/ }
else if(method == "Fluo F10" ) {spectrum_to_xyz_preset(FluoF10_spect, x, y, z);palet=13; /*tempalet=5300;*/ }
else if(method == "Fluo F11" ) {spectrum_to_xyz_preset(FluoF11_spect, x, y, z);palet=14; /*tempalet=4000;*/ }
else if(method == "Fluo F12" ) {spectrum_to_xyz_preset(FluoF12_spect, x, y, z);palet=15; /*tempalet=3000;*/ }
else if(method == "HMI Lamp" ) {spectrum_to_xyz_preset(HMI_spect, x, y, z);palet=16; /*tempalet=4760;*/ }
else if(method == "GTI Lamp" ) {spectrum_to_xyz_preset(GTI_spect, x, y, z);palet=17; /*tempalet=5000;*/ }
else if(method == "JudgeIII Lamp" ) {spectrum_to_xyz_preset(JudgeIII_spect, x, y, z);palet=18; /*tempalet=5100;*/ }
else if(method == "Solux Lamp 3500K" ) {spectrum_to_xyz_preset(Solux3500_spect, x, y, z);palet=19; /*tempalet=3480;*/ }
else if(method == "Solux Lamp 4100K" ) {spectrum_to_xyz_preset(Solux4100_spect, x, y, z);palet=20; /*tempalet=3930;*/ }
else if(method == "Solux Lamp 4700K" ) {spectrum_to_xyz_preset(Solux4700_spect, x, y, z);palet=21; /*tempalet=4700;*/ }
else if(method == "NG Solux Lamp 4700K" ) {spectrum_to_xyz_preset(NG_Solux4700_spect, x, y, z);palet=22; /*tempalet=4480;*/ }
else if(method == "LED LSI Lumelex 2040") {spectrum_to_xyz_preset(NG_LEDLSI2040_spect, x, y, z);palet=23; /*tempalet=2970;*/ }
else if(method == "LED CRS SP12 WWMR16" ) {spectrum_to_xyz_preset(NG_CRSSP12WWMR16_spect, x, y, z);palet=24; /*tempalet=3050;*/ }
else if(method == "Flash 5500K" ) {spectrum_to_xyz_preset(Flash5500_spect, x, y, z);palet=25; /*tempalet=5500;*/ }
else if(method == "Flash 6000K" ) {spectrum_to_xyz_preset(Flash6000_spect, x, y, z);palet=26; /*tempalet=6000;*/ }
else if(method == "Flash 6500K" ) {spectrum_to_xyz_preset(Flash6500_spect, x, y, z);palet=27; /*tempalet=6500;*/ }
else {
// otherwise we use the Temp+Green generic solution
if (temp <= 4000) {
// if temperature is between 2000K and 4000K we use blackbody, because there will be no Daylight reference below 4000K...
// of course, the previous version of RT used the "magical" but wrong formula of U.Fuchs (Ufraw).
spectrum_to_xyz_blackbody(0., 0., temp, x, y, z);palet=28;
}
else {
// from 4000K up to 25000K: using the D illuminant (daylight) which is standard
palet=29;
if (temp<=7000)
x_D = -4.6070e9/(temp*temp*temp) + 2.9678e6/(temp*temp) + 0.09911e3/temp + 0.244063;
else if (temp <=25000)
x_D = -2.0064e9/(temp*temp*temp) + 1.9018e6/(temp*temp) + 0.24748e3/temp + 0.237040;
else if (temp >25000) // above 25000 it's unknown..then I have modified to adjust for underwater
x_D = -2.0064e9/(temp*temp*temp) + 1.9018e6/(temp*temp) + 0.24748e3/temp + 0.237040 - ((temp-25000)/25000)*0.025;//Jacques empirical adjustemnt for very high temp (underwater !)
y_D = (-3.0*x_D*x_D + 2.87*x_D - 0.275);//modify blue / red action
//calculate D -daylight in function of s0, s1, s2 and temp ==> x_D y_D
//S(lamda)=So(lambda)+m1*s1(lambda)+m2*s2(lambda)
interm=(0.0241+0.2562*x_D-0.734*y_D);
m1=(-1.3515-1.7703*x_D+5.9114*y_D)/interm;
m2=(0.03-31.4424*x_D+30.0717*y_D)/interm;
spectrum_to_xyz_daylight(m1, m2, 0., x, y, z);
xD=x;yD=y;
}
}
xD=x; yD=y;
float adj=1.f;
if(equal < 0.9999 || equal > 1.0001 ){
adj=(100.f+( 1000.f-(1000.f*(float)equal) )/20.f)/100.f;
}
//printf("adj=%f\n",adj);
double Xwb = xD/yD;
double Ywb = 1.0;
double Zwb = (1.0-xD-yD)/yD;
double correl_temp;
if (settings->verbose) {
// double u=4*xD/(-2*xD+12*yD+3);
// double v=6*yD/(-2*xD+12*yD+3);
// printf("xD=%f yD=%f u=%f v=%f\n",xD,yD,u,v);
if(settings->CRI_color != 0)
printf("xD=%f yD=%f === Xwb=%f Ywb=%f Zwb=%f\n",xD,yD,Xwb,Ywb,Zwb);
}
/*if (isRaw) {
rmul = sRGB_xyz[0][0]*X + sRGB_xyz[0][1]*Y + sRGB_xyz[0][2]*Z;
gmul = sRGB_xyz[1][0]*X + sRGB_xyz[1][1]*Y + sRGB_xyz[1][2]*Z;
bmul = sRGB_xyz[2][0]*X + sRGB_xyz[2][1]*Y + sRGB_xyz[2][2]*Z;
} else {*/
//recalculate channels multipliers with new values of XYZ tue to whitebalance
rmul = sRGBd65_xyz[0][0]*Xwb*adj + sRGBd65_xyz[0][1]*Ywb + sRGBd65_xyz[0][2]*Zwb/adj; // Jacques' empirical modification 5/2013
gmul = sRGBd65_xyz[1][0]*Xwb + sRGBd65_xyz[1][1]*Ywb + sRGBd65_xyz[1][2]*Zwb;
bmul = sRGBd65_xyz[2][0]*Xwb*adj + sRGBd65_xyz[2][1]*Ywb + sRGBd65_xyz[2][2]*Zwb/adj;
//};
gmul /= green;
//printf("rmul=%f gmul=%f bmul=%f\n",rmul, gmul, bmul);
double max = rmul;
if (gmul>max) max = gmul;
if (bmul>max) max = bmul;
rmul /= max;
gmul /= max;
bmul /= max;
if(palette) // palette of color : 32 skin, 4 grey, 4 blue sky
//calculate L a b in function of color and illuminant
//J.Desmis january 2012
{
double x_x,y_y,z_z;
// illuminants
const double* spect_illummax[] = {
Daylight5300_spect,Cloudy6200_spect,Shade7600_spect,A2856_spect,FluoF1_spect,FluoF2_spect,FluoF3_spect,FluoF4_spect,FluoF5_spect,FluoF6_spect,FluoF7_spect,
FluoF8_spect,FluoF9_spect,FluoF10_spect,FluoF11_spect,FluoF12_spect,HMI_spect,GTI_spect,JudgeIII_spect,Solux3500_spect,Solux4100_spect,Solux4700_spect,NG_Solux4700_spect,NG_CRSSP12WWMR16_spect,NG_CRSSP12WWMR16_spect,
Flash5500_spect,Flash6000_spect,Flash6500_spect
};
// color
const double* spec_colorpalet[] = {
ColabSkin98_m2_10_spect, ColabSkin95_0_4_spect,ColabSkin91_4_14_spect, ColabSkin90_m1_20_spect,
ColorchechSGSkiK285_11_17_spect,ColabSkin87_8_8_spect,ColabSkin87_3_10_spect,ColabSkin89_8_21_spect,
ColabSkin70_7_32_spect,ColabSkin77_12_21_spect,ColabSkin75_8_4_spect,ColabSkin75_10_33_spect,
ColorchechSkiB166_18_18_spect,ColabSkin65_7_24_spect,ColorchechSGSkiF763_14_26_spect,ColabSkin65_33_11_spect,
ColabSkin57_19_6_spect,ColabSkin57_4_19_spect,ColabSkin57_10_28_spect,ColabSkin57_22_18_spect,
ColabSkin40_17_17_spect,ColabSkin40_7_19_spect,ColabSkin40_4_11_spect,ColabSkin40_17_6_spect,
ColorchechSkiA138_13_14_spect,ColabSkin33_6_15_spect,ColabSkin35_15_17_spect,ColabSkin33_15_5_spect,
ColabSkin26_18_18_spect,ColabSkin24_7_5_spect,ColabSkin24_5_6_spect,ColabSkin20_4_2_spect,
ColabSky42_0_m24_spect,ColorchechBluC150_m5_m22_spect,ColorchechWhiA496_spect, ColorchechSGBlaN3_6_spect,
JDC468_GraK14_44_spect,ColorchechGraC4_67_spect,ColabSky60_0_m31_spect,ColorchechDCBluN881_m7_m14_spect
//ColabSkin33_10_15_spect,
//ColabSkin81_2_14_spect,
};
int N_col = sizeof(spec_colorpalet)/sizeof(spec_colorpalet[0]);//number of color
if(palet < 28) {
for(int i=0;i<N_col;i++) {
spectrum_to_color_xyz_preset(spec_colorpalet[i], spect_illummax[palet], x_x,y_y,z_z);
Xpal[i]=x_x;Ypal[i]=y_y;Zpal[i]=z_z;
}
}
else if(palet>=28) {
if(temp<4000) {
for(int i=0;i<N_col;i++) {
spectrum_to_color_xyz_blackbody(spec_colorpalet[i], 0.,0.,temp,x_x,y_y,z_z);
Xpal[i]=x_x;Ypal[i]=y_y;Zpal[i]=z_z;
}
}
else {
double m11p, m22p;
m11p=m1;m22p=m2;
for(int i=0;i<N_col;i++) {// calculate XYZ palette for illuminant and color
spectrum_to_color_xyz_daylight(spec_colorpalet[i], m11p,m22p,temp,x_x,y_y,z_z);
Xpal[i]=x_x;Ypal[i]=y_y;Zpal[i]=z_z;
}
}
}
xp=xD;yp=yD;
double Xwbpal = xp/yp;//white balance
double Ywbpal = 1.0;
double Zwbpal = (1.0-xp-yp)/yp;
//chromatic adaptation CIECAT02 at temp
double adap=1.0;
cieCAT02(Xwbpal, Ywbpal, Zwbpal, CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22,adap);
//here new value of X,Y,Z with chromatic CAM02 adaptation
for(int i=0;i<N_col;i++) {
Xcam02pal[i]=CAM02BB00* Xpal[i] +CAM02BB01* Ypal[i] + CAM02BB02* Zpal[i] ;
Ycam02pal[i]=CAM02BB10* Xpal[i] +CAM02BB11* Ypal[i] + CAM02BB12* Zpal[i] ;
Zcam02pal[i]=CAM02BB20* Xpal[i] +CAM02BB21* Ypal[i] + CAM02BB22* Zpal[i] ;
//printf("CoulXYZ %i X %f Y %f Z %f\n", i, Xpal[i],Ypal[i],Zpal[i]);
//printf("CoulCAM %i X %f Y %f Z %f\n", i, Xcam02pal[i],Ycam02pal[i],Zcam02pal[i]);
}
//Calculate Lab
for(int i=0;i<N_col;i++) {
xr[i]=Xcam02pal[i]/whiteD50[0];
yr[i]=Ycam02pal[i]/whiteD50[1];
zr[i]=Zcam02pal[i]/whiteD50[2];
// xr, yr , zr > epsilon
if(xr[i]> epsilon) fx[i]=pow(xr[i],0.333);else fx[i]=(903.3*xr[i]+16.0)/116.0;
if(yr[i]> epsilon) fy[i]=pow(yr[i],0.333);else fy[i]=(903.3*yr[i]+16.0)/116.0;
if(zr[i]> epsilon) fz[i]=pow(zr[i],0.333);else fz[i]=(903.3*zr[i]+16.0)/116.0;
}
//Lab values in function of color and illuminant
//these values can be compared to preview values when using white-balance (skin / sky / BW)
for(int i=0;i<N_col;i++) {
Lpal[i]=116.0*fy[i]-16.0;
apal[i]=500.0*(fx[i]-fy[i]);
bpal[i]=200.0*(fy[i]-fz[i]);
}
// uncomment to display Lab values
//for(int i=0;i<N_col;i++) {
// printf("Lpal=%2.2f apal=%2.2f bpal=%2.2f\n", Lpal[i],apal[i],bpal[i]);
if(settings->CRI_color != 0) printf("Lpal=%2.2f apal=%2.2f bpal=%2.2f\n", Lpal[0],apal[0],bpal[0]);//sample
//}
} //end palette
// begin CRI_RT : color rendering index RT - adaptation of CRI by J.Desmis
// CRI = 100 for Blackbody and Daylight
// calculate from spectral data values X, Y, Z , for color of colorchecker24 , SG, DC, JDC_468
//only for lamp different of tungstene
//first calcul with illuminant (choice)
// and calcul with : blackbody at equivalent temp of lamp
if(settings->CRI_color != 0) //activate if CRi_color !=0
// CRI_color-1 = dispaly Lab values of color CRI_color -1
{
int illum;
int numero_color=settings->CRI_color - 1;
//spectral data illuminant (actually 21): only those necessary (lamp, fluorescent, LED) others CRI=100 (not Flash...)
const double* spect_illum[] = {
Daylight5300_spect,Cloudy6200_spect,Shade7600_spect,A2856_spect,FluoF1_spect,FluoF2_spect,FluoF3_spect,
FluoF4_spect,FluoF5_spect,FluoF6_spect,FluoF7_spect,FluoF8_spect,FluoF9_spect,FluoF10_spect,FluoF11_spect,
FluoF12_spect,HMI_spect,GTI_spect,JudgeIII_spect,Solux3500_spect,Solux4100_spect,Solux4700_spect,
NG_Solux4700_spect,NG_CRSSP12WWMR16_spect,NG_CRSSP12WWMR16_spect
};
const double* spec_color[] = {
ColorchechredC3_spect, ColorchechOraA2_spect,ColorchechYelD3_spect,ColorchechGreE2_spect,ColorchechGreB3_spect,
ColorchechCyaF3_spect, ColorchechPurD2_spect,ColorchechMagE3_spect,ColorchechSkiA138_13_14_spect,ColorchechGraC4_67_spect,
ColorchechSkiB166_18_18_spect,ColorchechBluC150_m5_m22_spect,ColorchechDCBluN881_m7_m14_spect,ColorchechSGSkiF763_14_26_spect,
ColorchechSGSkiK285_11_17_spect,ColorchechWhiA496_spect, ColorchechGreD1_spect, ColorchechSGBlaN3_6_spect,
JDC468_GraK14_44_spect,JDC468_BluH10_spect
};
int N_c = sizeof(spec_color)/sizeof(spec_color[0]);//number of color
if (method == "Fluo F1") {CRI_type=true; tempw=6430; illum=1;}
else if (method == "Fluo F2") {CRI_type=true; tempw=4230; illum=2;}
else if (method == "Fluo F3") {CRI_type=true; tempw=3450; illum=3;}
else if (method == "Fluo F4") {CRI_type=true; tempw=2940; illum=4;}
else if (method == "Fluo F5") {CRI_type=true; tempw=6350; illum=5;}
else if (method == "Fluo F6") {CRI_type=true; tempw=4150; illum=6;}
else if (method == "Fluo F7") {CRI_type=true; tempw=6500; illum=7;}
else if (method == "Fluo F8") {CRI_type=true; tempw=5020; illum=8;}
else if (method == "Fluo F9") {CRI_type=true; tempw=4330; illum=9;}
else if (method == "Fluo F10") {CRI_type=true; tempw=5300; illum=10;}
else if (method == "Fluo F11") {CRI_type=true; tempw=4000; illum=11;}
else if (method == "Fluo F12") {CRI_type=true; tempw=3000; illum=12;}
else if (method == "HMI Lamp") {CRI_type=true; tempw=4760; illum=13;}
else if (method == "GTI Lamp") {CRI_type=true; tempw=5000; illum=14;}
else if (method == "JudgeIII Lamp") {CRI_type=true; tempw=5100; illum=15;}
else if (method == "Solux Lamp 3500K") {CRI_type=true; tempw=3480; illum=16;}
else if (method == "Solux Lamp 4100K") {CRI_type=true; tempw=3930; illum=17;}
else if (method == "Solux Lamp 4700K" ) {CRI_type=true; tempw=4700; illum=18;}
else if (method == "NG Solux Lamp 4700K") {CRI_type=true; tempw=4480; illum=19;}
else if (method == "LED LSI Lumelex 2040") {CRI_type=true; tempw=2970; illum=20;}
else if (method == "LED CRS SP12 WWMR16") {CRI_type=true; tempw=3050; illum=21;}
else {CRI_type=false;}
if (CRI_type) {
float DeltaE[50], DeltaEs[8];
float quadCRI=0.0f,quadCRIs=0.0f;
float CRI_RT=0.0, CRI[50];
float CRI_RTs=0.0, CRIs[8];
for(int i=0;i<N_c;i++) {
spectrum_to_color_xyz_preset(spec_color[i],spect_illum[illum+3], xx,yy,zz);
XchkLamp[i]=xx;YchkLamp[i]=yy;ZchkLamp[i]=zz;
}
//calculate XYZ for each color : for Blackbody and Daylight at tempw
if(tempw<4000) {
for(int i=0;i<N_c;i++) {
spectrum_to_color_xyz_blackbody(spec_color[i],0.,0.,tempw,xx,yy,zz);
Xchk[i]=xx;Ychk[i]=yy;Zchk[i]=zz;
}
spectrum_to_xyz_blackbody(0., 0., tempw, x, y, z);//for white point
}
else // after 6600K (arbitrary) I use daylight...because ...but there is no lamp...
{
double m11, m22, x_DD,y_DD, interm2, yDD;
if (tempw<=7000)
x_DD = -4.6070e9/(tempw*tempw*tempw) + 2.9678e6/(tempw*tempw) + 0.09911e3/tempw + 0.244063;
else
x_DD = -2.0064e9/(tempw*tempw*tempw) + 1.9018e6/(tempw*tempw) + 0.24748e3/tempw + 0.237040;
y_DD = -3.0*x_DD*x_DD + 2.87*x_DD - 0.275;
//calculate D -daylight in function of s0, s1, s2 and temp ==> x_D y_D
//S(lamda)=So(lambda)+m1*s1(lambda)+m2*s2(lambda)
interm2=(0.0241+0.2562*x_DD-0.734*y_DD);
m11=(-1.3515-1.7703*x_DD+5.9114*y_DD)/interm2;
m22=(0.03-31.4424*x_DD+30.0717*y_DD)/interm2;
for(int i=0;i<N_c;i++) {
spectrum_to_color_xyz_daylight(spec_color[i],m11,m22,tempw,xx,yy,zz);
Xchk[i]=xx;Ychk[i]=yy;Zchk[i]=zz;
}
spectrum_to_xyz_daylight(m11, m22, 0., x, y, z);
}
XYZtoCorColorTemp(Xwb, Ywb, Zwb, correl_temp);
if (settings->verbose) {
printf("Correlated temperature (lamp)=%i\n", (int) correl_temp); //use only for lamp...otherwise It give an information!!
}
double Xwb_bb = x/y;//white balance for blackbody
double Ywb_bb = 1.0;
double Zwb_bb = (1.0-x-y)/y;
//calculate Matrix CAM02 : better than Von Kries and Bradford==> for Lamp
double adap=1.0;
cieCAT02(Xwb, Ywb, Zwb, CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22,adap);
//here new value of X,Y,Z for lamp with chromatic CAM02 adaptation
for(int i=0;i<N_c;i++) {
Xcam02Lamp[i]=CAM02BB00* XchkLamp[i] +CAM02BB01* YchkLamp[i] + CAM02BB02* ZchkLamp[i] ;
Ycam02Lamp[i]=CAM02BB10* XchkLamp[i] +CAM02BB11* YchkLamp[i] + CAM02BB12* ZchkLamp[i] ;
Zcam02Lamp[i]=CAM02BB20* XchkLamp[i] +CAM02BB21* YchkLamp[i] + CAM02BB22* ZchkLamp[i] ;
}
//now calculate CAM02 for Blackbody (or Daylight) at tempx
cieCAT02(Xwb_bb, Ywb_bb, Zwb_bb, CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22,adap);
//here new value of X,Y,Z for blackbody with chromatic CAM02 adaptation
for(int i=0;i<N_c;i++) {
Xcam02[i]=CAM02BB00* Xchk[i] +CAM02BB01* Ychk[i] + CAM02BB02* Zchk[i] ;
Ycam02[i]=CAM02BB10* Xchk[i] +CAM02BB11* Ychk[i] + CAM02BB12* Zchk[i] ;
Zcam02[i]=CAM02BB20* Xchk[i] +CAM02BB21* Ychk[i] + CAM02BB22* Zchk[i] ;
// printf("CoulXYZ %i X %f Y %f Z %f\n", i, Xchk[i],Ychk[i],Zchk[i]);
// printf("CoulCAM %i X %f Y %f Z %f\n", i, Xcam02[i],Ycam02[i],Zcam02[i]);
}
//now conversion to Lab
// Lamp
for(int i=0;i<N_c;i++) {
xr[i]=Xcam02Lamp[i]/whiteD50[0];
yr[i]=Ycam02Lamp[i]/whiteD50[1];
zr[i]=Zcam02Lamp[i]/whiteD50[2];
// xr, yr , zr > epsilon
if(xr[i]> epsilon) fx[i]=pow(xr[i],0.333);else fx[i]=(903.3*xr[i]+16.0)/116.0;
if(yr[i]> epsilon) fy[i]=pow(yr[i],0.333);else fy[i]=(903.3*yr[i]+16.0)/116.0;
if(zr[i]> epsilon) fz[i]=pow(zr[i],0.333);else fz[i]=(903.3*zr[i]+16.0)/116.0;
}
for(int i=0;i<N_c;i++) {
Llamp[i]=116.0*fy[i]-16.0;
alamp[i]=500.0*(fx[i]-fy[i]);
blamp[i]=200.0*(fy[i]-fz[i]);
}
//blackbody at tempx
for(int i=0;i<N_c;i++) {
xr[i]=Xcam02[i]/whiteD50[0];
yr[i]=Ycam02[i]/whiteD50[1];
zr[i]=Zcam02[i]/whiteD50[2];
//
if(xr[i]> epsilon) fx[i]=pow(xr[i],0.333);else fx[i]=(903.3*xr[i]+16.0)/116.0;
if(yr[i]> epsilon) fy[i]=pow(yr[i],0.333);else fy[i]=(903.3*yr[i]+16.0)/116.0;
if(zr[i]> epsilon) fz[i]=pow(zr[i],0.333);else fz[i]=(903.3*zr[i]+16.0)/116.0;
}
for(int i=0;i<N_c;i++) {
Lbb[i]=116.*fy[i]-16.;
abb[i]=500.*(fx[i]-fy[i]);
bbb[i]=200.*(fy[i]-fz[i]);
}
//display value to verify calculs
if(settings->CRI_color != 0) {
printf("Color Number %i\n",numero_color);
printf("L_refer=%2.2f a=%2.2f b=%2.2f\n", Lbb[numero_color],abb[numero_color],bbb[numero_color]);
printf("L_lamp=%2.2f al=%2.2f bl=%2.2f\n", Llamp[numero_color],alamp[numero_color],blamp[numero_color]);
}
//then calculate DeltaE CIE 1976
for(int i=0;i<8;i++)
DeltaEs[i]=sqrt((Lbb[i]-Llamp[i])*(Lbb[i]-Llamp[i])+(abb[i]-alamp[i])*(abb[i]-alamp[i])+(bbb[i]-blamp[i])*(bbb[i]-blamp[i]));
for(int i=0;i<8;i++)
CRIs[i]=100-3.0*DeltaEs[i]; //3.0 coef to adapt ==> same results than CRI "official"
for(int i=0;i<8;i++)
CRI_RTs+=CRIs[i];
CRI_RTs/=8;
for(int i=0;i<8;i++)
quadCRIs+=(CRIs[i]-CRI_RTs)*(CRIs[i]-CRI_RTs);
quadCRIs/=8;
for(int i=0;i<N_c;i++)
DeltaE[i]=sqrt((Lbb[i]-Llamp[i])*(Lbb[i]-Llamp[i])+(abb[i]-alamp[i])*(abb[i]-alamp[i])+(bbb[i]-blamp[i])*(bbb[i]-blamp[i]));
for(int i=0;i<N_c;i++)
CRI[i]=100-3.0*DeltaE[i]; //3.0 coef to adapt ==> same results than CRI "official"
for(int i=0;i<N_c;i++)
CRI_RT+=CRI[i];
CRI_RT/=N_c;
for(int i=0;i<N_c;i++)
quadCRI+=(CRI[i]-CRI_RT)*(CRI[i]-CRI_RT);
quadCRI/=N_c;
if(settings->CRI_color != 0) {
printf("CRI_standard=%i CRI:1->8=%i %i %i %i %i %i %i %i Sigma=%2.1f\n",(int) CRI_RTs, (int) CRIs[0], (int) CRIs[1],(int) CRIs[2],(int) CRIs[3],(int) CRIs[4],(int) CRIs[5],(int) CRIs[6],(int) CRIs[7],sqrt(quadCRIs));
printf("CRI_RT_exten=%i CRI:9->20=%i %i %i %i %i %i %i %i %i %i %i %i Sigma=%2.1f\n",(int) CRI_RT,(int) CRI[8],(int) CRI[9], (int) CRI[10],(int) CRI[11],(int) CRI[12],(int) CRI[13],(int) CRI[14],(int) CRI[15],(int) CRI[16],(int) CRI[17],(int) CRI[18],(int) CRI[19],sqrt(quadCRI));
}
}
}
}
/* J.Desmis october 2012 - CIECAM02 :
I have notably modified the code of Billy Biggs to adapt to RT
The code is update from last works of M.Fairchild
and also gamut correction M.H.Brill S.Susstrunk
*/
/**
* Copyright (c) 2003 Billy Biggs <vektor@dumbterm.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
void ColorTemp::xyz_to_cat02( double &r, double &g, double &b, double x, double y, double z, int gamu )
{
gamu=1;
if(gamu==0){
r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
b = ( 0.0030 * x) + (0.0136 * y) + (0.9834 * z);
}
else if (gamu==1) {//gamut correction M.H.Brill S.Susstrunk
//r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
//g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
//b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
r = ( 1.007245 * x) + (0.011136* y) - (0.018381 * z);//Changjun Li
g = (-0.318061 * x) + (1.314589 * y) + (0.003471 * z);
b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
}
}
void ColorTemp::xyz_to_cat02float( float &r, float &g, float &b, float x, float y, float z, int gamu )
{
gamu=1;
if(gamu==0){
r = ( 0.7328f * x) + (0.4296f * y) - (0.1624f * z);
g = (-0.7036f * x) + (1.6975f * y) + (0.0061f * z);
b = ( 0.0030f * x) + (0.0136f * y) + (0.9834f * z);
}
else if (gamu==1) {//gamut correction M.H.Brill S.Susstrunk
//r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
//g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
//b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
r = ( 1.007245f * x) + (0.011136f* y) - (0.018381f * z);//Changjun Li
g = (-0.318061f * x) + (1.314589f * y) + (0.003471f * z);
b = ( 0.0000f * x) + (0.0000f * y) + (1.0000f * z);
}
}
void ColorTemp::cat02_to_xyz( double &x, double &y, double &z, double r, double g, double b, int gamu )
{
gamu=1;
if(gamu==0) {
x = ( 1.096124 * r) - (0.278869 * g) + (0.182745 * b);
y = ( 0.454369 * r) + (0.473533 * g) + (0.072098 * b);
z = (-0.009628 * r) - (0.005698 * g) + (1.015326 * b);
}
else if(gamu==1) {//gamut correction M.H.Brill S.Susstrunk
//x = ( 1.0978566 * r) - (0.277843 * g) + (0.179987 * b);
//y = ( 0.455053 * r) + (0.473938 * g) + (0.0710096* b);
//z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
x = ( 0.99015849 * r) - (0.00838772* g) + (0.018229217 * b);//Changjun Li
y = ( 0.239565979 * r) + (0.758664642 * g) + (0.001770137* b);
z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
}
}
void ColorTemp::cat02_to_xyzfloat( float &x, float &y, float &z, float r, float g, float b, int gamu )
{
gamu=1;
if(gamu==0) {
x = ( 1.096124f * r) - (0.278869f * g) + (0.182745f * b);
y = ( 0.454369f * r) + (0.473533f * g) + (0.072098f * b);
z = (-0.009628f * r) - (0.005698f * g) + (1.015326f * b);
}
else if(gamu==1) {//gamut correction M.H.Brill S.Susstrunk
//x = ( 1.0978566 * r) - (0.277843 * g) + (0.179987 * b);
//y = ( 0.455053 * r) + (0.473938 * g) + (0.0710096* b);
//z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
x = ( 0.99015849f * r) - (0.00838772f* g) + (0.018229217f * b);//Changjun Li
y = ( 0.239565979f * r) + (0.758664642f * g) + (0.001770137f* b);
z = ( 0.000000f * r) - (0.000000f * g) + (1.000000f * b);
}
}
void ColorTemp::hpe_to_xyz( double &x, double &y, double &z, double r, double g, double b )
{
x = (1.910197 * r) - (1.112124 * g) + (0.201908 * b);
y = (0.370950 * r) + (0.629054 * g) - (0.000008 * b);
z = b;
}
void ColorTemp::hpe_to_xyzfloat( float &x, float &y, float &z, float r, float g, float b )
{
x = (1.910197f * r) - (1.112124f * g) + (0.201908f * b);
y = (0.370950f * r) + (0.629054f * g) - (0.000008f * b);
z = b;
}
void ColorTemp::cat02_to_hpe( double &rh, double &gh, double &bh, double r, double g, double b, int gamu )
{ gamu=1;
if(gamu==0){
rh = ( 0.7409792 * r) + (0.2180250 * g) + (0.0410058 * b);
gh = ( 0.2853532 * r) + (0.6242014 * g) + (0.0904454 * b);
bh = (-0.0096280 * r) - (0.0056980 * g) + (1.0153260 * b);
}
else if (gamu==1) {//Changjun Li
rh = ( 0.550930835 * r) + (0.519435987* g) - ( 0.070356303* b);
gh = ( 0.055954056 * r) + (0.89973132 * g) + (0.044315524 * b);
bh = (0.0 * r) - (0.0* g) + (1.0 * b);
}
}
void ColorTemp::cat02_to_hpefloat( float &rh, float &gh, float &bh, float r, float g, float b, int gamu )
{ gamu=1;
if(gamu==0){
rh = ( 0.7409792f * r) + (0.2180250f * g) + (0.0410058f * b);
gh = ( 0.2853532f * r) + (0.6242014f * g) + (0.0904454f * b);
bh = (-0.0096280f * r) - (0.0056980f * g) + (1.0153260f * b);
}
else if (gamu==1) {//Changjun Li
rh = ( 0.550930835f * r) + (0.519435987f* g) - ( 0.070356303f* b);
gh = ( 0.055954056f * r) + (0.89973132f * g) + (0.044315524f * b);
bh = (0.0f * r) - (0.0f* g) + (1.0f * b);
}
}
void ColorTemp::Aab_to_rgb( double &r, double &g, double &b, double A, double aa, double bb, double nbb )
{
double x = (A / nbb) + 0.305;
/* c1 c2 c3 */
r = (0.32787 * x) + (0.32145 * aa) + (0.20527 * bb);
/* c1 c4 c5 */
g = (0.32787 * x) - (0.63507 * aa) - (0.18603 * bb);
/* c1 c6 c7 */
b = (0.32787 * x) - (0.15681 * aa) - (4.49038 * bb);
}
void ColorTemp::Aab_to_rgbfloat( float &r, float &g, float &b, float A, float aa, float bb, float nbb )
{
float x = (A / nbb) + 0.305f;
/* c1 c2 c3 */
r = (0.32787f * x) + (0.32145f * aa) + (0.20527f * bb);
/* c1 c4 c5 */
g = (0.32787f * x) - (0.63507f * aa) - (0.18603f * bb);
/* c1 c6 c7 */
b = (0.32787f * x) - (0.15681f * aa) - (4.49038f * bb);
}
void ColorTemp::calculate_ab( double &aa, double &bb, double h, double e, double t, double nbb, double a )
{
double hrad = (h * M_PI) / 180.0;
double sinh = sin( hrad );
double cosh = cos( hrad );
double x = (a / nbb) + 0.305;
double p3 = 21.0/20.0;
if( fabs( sinh ) >= fabs( cosh ) ) {
bb = ((0.32787 * x) * (2.0 + p3)) /
((e / (t * sinh)) -
// ((0.32145 - 0.63507 - (p3 * 0.15681)) * (cosh / sinh)) -
// (0.20527 - 0.18603 - (p3 * 4.49038)));
((-0.31362 - (p3 * 0.15681)) * (cosh / sinh)) -
(0.01924 - (p3 * 4.49038)));
aa = (bb * cosh) / sinh;
} else {
aa = ((0.32787 * x) * (2.0 + p3)) /
((e / (t * cosh)) -
// (0.32145 - 0.63507 - (p3 * 0.15681)) -
// ((0.20527 - 0.18603 - (p3 * 4.49038)) * (sinh / cosh)));
(-0.31362 - (p3 * 0.15681)) -
((0.01924 - (p3 * 4.49038)) * (sinh / cosh)));
bb = (aa * sinh) / cosh;
}
}
void ColorTemp::calculate_abfloat( float &aa, float &bb, float h, float e, float t, float nbb, float a )
{
float2 sincosval = xsincosf((h * M_PI) / 180.0f);
float sinh = sincosval.x;
float cosh = sincosval.y;
float x = (a / nbb) + 0.305f;
float p3 = 21.0f/20.0f;
if( fabs( sinh ) >= fabs( cosh ) ) {
bb = ((0.32787f * x) * (2.0f + p3)) /
((e / (t * sinh)) -
// ((0.32145 - 0.63507 - (p3 * 0.15681)) * (cosh / sinh)) -
// (0.20527 - 0.18603 - (p3 * 4.49038)));
((-0.31362f - (p3 * 0.15681f)) * (cosh / sinh)) -
(0.01924f - (p3 * 4.49038f)));
aa = (bb * cosh) / sinh;
} else {
aa = ((0.32787f * x) * (2.0f + p3)) /
((e / (t * cosh)) -
// (0.32145 - 0.63507 - (p3 * 0.15681)) -
// ((0.20527 - 0.18603 - (p3 * 4.49038)) * (sinh / cosh)));
(-0.31362f - (p3 * 0.15681f)) -
((0.01924f - (p3 * 4.49038f)) * (sinh / cosh)));
bb = (aa * sinh) / cosh;
}
}
void ColorTemp::initcam1(double gamu, double yb, double pilotd, double f, double la, double xw, double yw, double zw, double &n, double &d, double &nbb, double &ncb,
double &cz, double &aw, double &wh, double &pfl, double &fl, double &c)
{
n = yb / yw;
if(pilotd==2.0) d = d_factor( f, la );else d=pilotd;
fl = calculate_fl_from_la_ciecam02( la );
nbb = ncb = 0.725 * pow( 1.0 / n, 0.2 );
cz = 1.48 + sqrt( n );
aw = achromatic_response_to_white( xw, yw, zw, d, fl, nbb, gamu );
wh =( 4.0 / c ) * ( aw + 4.0 ) * pow( fl, 0.25 );
pfl = pow( fl, 0.25 );
#ifdef _DEBUG
if (settings->verbose) printf("Source double d=%f aw=%f fl=%f wh=%f\n",d,aw,fl,wh);
#endif
}
void ColorTemp::initcam1float(float gamu, float yb, float pilotd, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb,
float &cz, float &aw, float &wh, float &pfl, float &fl, float &c)
{
n = yb / yw;
if(pilotd==2.0) d = d_factorfloat( f, la );else d=pilotd;
fl = calculate_fl_from_la_ciecam02float( la );
nbb = ncb = 0.725f * pow_F( 1.0f / n, 0.2f );
cz = 1.48f + sqrt( n );
aw = achromatic_response_to_whitefloat( xw, yw, zw, d, fl, nbb, gamu );
wh =( 4.0f / c ) * ( aw + 4.0f ) * pow_F( fl, 0.25f );
pfl = pow_F( fl, 0.25f );
#ifdef _DEBUG
if (settings->verbose) printf("Source float d=%f aw=%f fl=%f wh=%f c=%f awc=%f\n",d,aw,fl,wh,c,(4.f/c)*(aw+4.f));
#endif
}
void ColorTemp::initcam2(double gamu, double yb, double f, double la, double xw, double yw, double zw, double &n, double &d, double &nbb, double &ncb,
double &cz, double &aw, double &fl)
{
n = yb / yw;
d = d_factor( f, la );
fl = calculate_fl_from_la_ciecam02( la );
nbb = ncb = 0.725 * pow( 1.0 / n, 0.2 );
cz = 1.48 + sqrt( n );
aw = achromatic_response_to_white( xw, yw, zw, d, fl, nbb, gamu );
#ifdef _DEBUG
if (settings->verbose) printf("Viewing double d=%f aw=%f fl=%f n=%f\n",d,aw,fl,n);
#endif
}
void ColorTemp::initcam2float(float gamu, float yb, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb,
float &cz, float &aw, float &fl)
{
n = yb / yw;
d = d_factorfloat( f, la );
fl = calculate_fl_from_la_ciecam02float( la );
nbb = ncb = 0.725f * pow_F( 1.0f / n, 0.2f );
cz = 1.48f + sqrt( n );
aw = achromatic_response_to_whitefloat( xw, yw, zw, d, fl, nbb, gamu );
#ifdef _DEBUG
if (settings->verbose) printf("Viewing float d=%f aw=%f fl=%f n=%f\n",d,aw,fl,n);
#endif
}
void ColorTemp::xyz2jchqms_ciecam02( double &J, double &C, double &h, double &Q, double &M, double &s,double &aw, double &fl, double &wh,
double x, double y, double z, double xw, double yw, double zw,
double yb, double la, double f, double c, double nc, double pilotd, int gamu , double n, double nbb, double ncb, double pfl, double cz, double d)
{
double r, g, b;
double rw, gw, bw;
double rc, gc, bc;
double rp, gp, bp;
double rpa, gpa, bpa;
double a, ca, cb;
double e, t;
double myh, myj, myc, myq, mym, mys;
gamu=1;
xyz_to_cat02( r, g, b, x, y, z, gamu );
xyz_to_cat02( rw, gw, bw, xw, yw, zw, gamu );
rc = r * (((yw * d) / rw) + (1.0 - d));
gc = g * (((yw * d) / gw) + (1.0 - d));
bc = b * (((yw * d) / bw) + (1.0 - d));
ColorTemp::cat02_to_hpe( rp, gp, bp, rc, gc, bc, gamu );
if(gamu==1){//gamut correction M.H.Brill S.Susstrunk
rp=MAXR(rp,0.0);
gp=MAXR(gp,0.0);
bp=MAXR(bp,0.0);
}
rpa = nonlinear_adaptation( rp, fl );
gpa = nonlinear_adaptation( gp, fl );
bpa = nonlinear_adaptation( bp, fl );
ca = rpa - ((12.0 * gpa) / 11.0) + (bpa / 11.0);
cb = (1.0 / 9.0) * (rpa + gpa - (2.0 * bpa));
myh = (180.0 / M_PI) * atan2( cb, ca );
if( myh < 0.0 ) myh += 360.0;
//we can also calculate H, if necessary...but it's using time...for what usage ?
/*double temp;
if(myh<20.14) {
temp = ((myh + 122.47)/1.2) + ((20.14 - myh)/0.8);
H = 300 + (100*((myh + 122.47)/1.2)) / temp;
}
else if(myh < 90.0) {
temp = ((myh - 20.14)/0.8) + ((90.00 - myh)/0.7);
H = (100*((myh - 20.14)/0.8)) / temp;
}
else if (myh < 164.25) {
temp = ((myh - 90.00)/0.7) + ((164.25 - myh)/1.0);
H = 100 + ((100*((myh - 90.00)/0.7)) / temp);
}
else if (myh < 237.53) {
temp = ((myh - 164.25)/1.0) + ((237.53 - myh)/1.2);
H = 200 + ((100*((myh - 164.25)/1.0)) / temp);
}
else {
temp = ((myh - 237.53)/1.2) + ((360 - myh + 20.14)/0.8);
H = 300 + ((100*((myh - 237.53)/1.2)) / temp);
}
*/
a = ((2.0 * rpa) + gpa + ((1.0 / 20.0) * bpa) - 0.305) * nbb;
if (gamu==1) a=MAXR(a,0.0);//gamut correction M.H.Brill S.Susstrunk
J = 100.0 * pow( a / aw, c * cz );
e = ((12500.0 / 13.0) * nc * ncb) * (cos( ((myh * M_PI) / 180.0) + 2.0 ) + 3.8);
t = (e * sqrt( (ca * ca) + (cb * cb) )) / (rpa + gpa + ((21.0 / 20.0) * bpa));
C = pow( t, 0.9 ) * sqrt( J / 100.0 )
* pow( 1.64 - pow( 0.29, n ), 0.73 );
Q = wh * sqrt( J / 100.0 );
M = C * pfl;
s = 100.0 * sqrt( M / Q );
h = myh;
}
void ColorTemp::xyz2jchqms_ciecam02float( float &J, float &C, float &h, float &Q, float &M, float &s,float &aw, float &fl, float &wh,
float x, float y, float z, float xw, float yw, float zw,
float yb, float la, float f, float c, float nc, float pilotd, int gamu, float n, float nbb, float ncb, float pfl, float cz, float d)
{
float r, g, b;
float rw, gw, bw;
float rc, gc, bc;
float rp, gp, bp;
float rpa, gpa, bpa;
float a, ca, cb;
float e, t;
float myh, myj, myc, myq, mym, mys;
gamu=1;
xyz_to_cat02float( r, g, b, x, y, z, gamu );
xyz_to_cat02float( rw, gw, bw, xw, yw, zw, gamu );
rc = r * (((yw * d) / rw) + (1.0 - d));
gc = g * (((yw * d) / gw) + (1.0 - d));
bc = b * (((yw * d) / bw) + (1.0 - d));
ColorTemp::cat02_to_hpefloat( rp, gp, bp, rc, gc, bc, gamu );
if(gamu==1){//gamut correction M.H.Brill S.Susstrunk
rp=MAXR(rp,0.0f);
gp=MAXR(gp,0.0f);
bp=MAXR(bp,0.0f);
}
rpa = nonlinear_adaptationfloat( rp, fl );
gpa = nonlinear_adaptationfloat( gp, fl );
bpa = nonlinear_adaptationfloat( bp, fl );
ca = rpa - ((12.0f * gpa) / 11.0f) + (bpa / 11.0f);
cb = (1.0f / 9.0f) * (rpa + gpa - (2.0f * bpa));
myh = (180.0f / M_PI) * xatan2f( cb, ca );
if( myh < 0.0f ) myh += 360.0f;
//we can also calculate H, if necessary...but it's using time...for what usage ?
/*double temp;
if(myh<20.14) {
temp = ((myh + 122.47)/1.2) + ((20.14 - myh)/0.8);
H = 300 + (100*((myh + 122.47)/1.2)) / temp;
}
else if(myh < 90.0) {
temp = ((myh - 20.14)/0.8) + ((90.00 - myh)/0.7);
H = (100*((myh - 20.14)/0.8)) / temp;
}
else if (myh < 164.25) {
temp = ((myh - 90.00)/0.7) + ((164.25 - myh)/1.0);
H = 100 + ((100*((myh - 90.00)/0.7)) / temp);
}
else if (myh < 237.53) {
temp = ((myh - 164.25)/1.0) + ((237.53 - myh)/1.2);
H = 200 + ((100*((myh - 164.25)/1.0)) / temp);
}
else {
temp = ((myh - 237.53)/1.2) + ((360 - myh + 20.14)/0.8);
H = 300 + ((100*((myh - 237.53)/1.2)) / temp);
}
*/
a = ((2.0f * rpa) + gpa + ((1.0f / 20.0f) * bpa) - 0.305f) * nbb;
if (gamu==1) a=MAXR(a,0.0f);//gamut correction M.H.Brill S.Susstrunk
J = 100.0f * pow_F( a / aw, c * cz );
e = ((12500.0f / 13.0f) * nc * ncb) * (xcosf( ((myh * M_PI) / 180.0f) + 2.0f ) + 3.8f);
t = (e * sqrt( (ca * ca) + (cb * cb) )) / (rpa + gpa + ((21.0f / 20.0f) * bpa));
C = pow_F( t, 0.9f ) * sqrt( J / 100.0f )
* pow_F( 1.64f - pow_F( 0.29f, n ), 0.73f );
Q = wh * sqrt( J / 100.0f );
M = C * pfl;
s = 100.0f * sqrt( M / Q );
h = myh;
}
void ColorTemp::jch2xyz_ciecam02( double &x, double &y, double &z, double J, double C, double h,
double xw, double yw, double zw, double yb, double la,
double f, double c, double nc , int gamu, double n, double nbb, double ncb, double fl, double cz, double d, double aw )
{
double r, g, b;
double rc, gc, bc;
double rp, gp, bp;
double rpa, gpa, bpa;
double rw, gw, bw;
double a, ca, cb;
double e, t;
gamu=1;
ColorTemp::xyz_to_cat02( rw, gw, bw, xw, yw, zw, gamu );
e = ((12500.0 / 13.0) * nc * ncb) * (cos( ((h * M_PI) / 180.0) + 2.0 ) + 3.8);
a = pow( J / 100.0, 1.0 / (c * cz) ) * aw;
t = pow( C / (sqrt( J / 100) * pow( 1.64 - pow( 0.29, n ), 0.73 )), 10.0 / 9.0 );
calculate_ab( ca, cb, h, e, t, nbb, a );
Aab_to_rgb( rpa, gpa, bpa, a, ca, cb, nbb );
rp = inverse_nonlinear_adaptation( rpa, fl );
gp = inverse_nonlinear_adaptation( gpa, fl );
bp = inverse_nonlinear_adaptation( bpa, fl );
ColorTemp::hpe_to_xyz( x, y, z, rp, gp, bp );
ColorTemp::xyz_to_cat02( rc, gc, bc, x, y, z, gamu );
r = rc / (((yw * d) / rw) + (1.0 - d));
g = gc / (((yw * d) / gw) + (1.0 - d));
b = bc / (((yw * d) / bw) + (1.0 - d));
ColorTemp::cat02_to_xyz( x, y, z, r, g, b, gamu );
}
void ColorTemp::jch2xyz_ciecam02float( float &x, float &y, float &z, float J, float C, float h,
float xw, float yw, float zw, float yb, float la,
float f, float c, float nc , int gamu, float n, float nbb, float ncb, float fl, float cz, float d, float aw)
{
float r, g, b;
float rc, gc, bc;
float rp, gp, bp;
float rpa, gpa, bpa;
float rw, gw, bw;
float a, ca, cb;
float e, t;
gamu=1;
ColorTemp::xyz_to_cat02float( rw, gw, bw, xw, yw, zw, gamu );
e = ((12500.0f / 13.0f) * nc * ncb) * (xcosf( ((h * M_PI) / 180.0f) + 2.0f ) + 3.8f);
a = pow_F( J / 100.0f, 1.0f / (c * cz) ) * aw;
t = pow_F( C / (sqrt( J / 100.f) * pow_F( 1.64f - pow_F( 0.29f, n ), 0.73f )), 10.0f / 9.0f );
calculate_abfloat( ca, cb, h, e, t, nbb, a );
Aab_to_rgbfloat( rpa, gpa, bpa, a, ca, cb, nbb );
rp = inverse_nonlinear_adaptationfloat( rpa, fl );
gp = inverse_nonlinear_adaptationfloat( gpa, fl );
bp = inverse_nonlinear_adaptationfloat( bpa, fl );
ColorTemp::hpe_to_xyzfloat( x, y, z, rp, gp, bp );
ColorTemp::xyz_to_cat02float( rc, gc, bc, x, y, z, gamu );
r = rc / (((yw * d) / rw) + (1.0f - d));
g = gc / (((yw * d) / gw) + (1.0f - d));
b = bc / (((yw * d) / bw) + (1.0f - d));
ColorTemp::cat02_to_xyzfloat( x, y, z, r, g, b, gamu );
}
//end CIECAM Billy Bigg
/*
Calculate Planck's radiation
*/
//calculate spectral data for blackbody at temp!
double ColorTemp::blackbody_spect(double wavelength, double m1, double m2, double temp)
{
double wlm = wavelength * 1e-9; /* Wavelength in meters */
return (3.7417715247e-16 * pow(wlm, -5.0)) / //3.7417..= c1 = 2*Pi*h*c2 where h=Planck constant, c=velocity of light
(exp(1.438786e-2 / (wlm * temp)) - 1.0); //1.4387..= c2 = h*c/k where k=Boltzmann constant
}
/*
The next 3 methods are inspired from:
a) Colour Rendering of Spectra by John Walker
http://www.fourmilab.ch/
This program is in the public domain.
b) Bruce Lindbloom
Adapted to Rawtherapee by J.Desmis
this values are often called xBar yBar zBar and are characteristics of a color / illuminant
values cie_colour_match[][3] = Observer 2<> x2, y2, z2
E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.0014 0.0000 0.0065 above
I have increase precision used by J.Walker and pass to 350nm to 830nm
*/
void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double _temp, double &x, double &y, double &z)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, XYZ;
for (i=0, lambda=350.; lambda<830.1; i++, lambda+=5.) {
double Me = daylight_spect(lambda, _m1, _m2, _temp);
X += Me * cie_colour_match_jd[i][0];
Y += Me * cie_colour_match_jd[i][1];
Z += Me * cie_colour_match_jd[i][2];
}
XYZ = (X + Y + Z);
x = X / XYZ;
y = Y / XYZ;
z = Z / XYZ;
}
void ColorTemp::spectrum_to_xyz_blackbody(double _m1, double _m2, double _temp, double &x, double &y, double &z)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, XYZ;
for (i=0, lambda=350.; lambda<830.1; i++, lambda+=5.) {
double Me = blackbody_spect(lambda, _m1, _m2, _temp);
X += Me * cie_colour_match_jd[i][0];
Y += Me * cie_colour_match_jd[i][1];
Z += Me * cie_colour_match_jd[i][2];
}
XYZ = (X + Y + Z);
x = X / XYZ;
y = Y / XYZ;
z = Z / XYZ;
}
void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, double &y, double &z)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, XYZ;
/*
Inspired from:
a) Colour Rendering of Spectra by John Walker
http://www.fourmilab.ch/
This program is in the public domain.
b) Bruce Lindbloom
Adapted to RawTherapee by J.Desmis
this values are often called xBar yBar zBar and are characteristics of a color / illuminant
values cie_colour_match[][3] = Observer 2<> x2, y2, z2
E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.0014 0.0000 0.0065 above
I have increased the precision used by J.Walker and pass from 350nm to 830nm
*/
for (i=0, lambda=350.; lambda<830.1; i++, lambda+=5.) {
double Me = get_spectral_color(lambda, spec_intens);
X += Me * cie_colour_match_jd[i][0];
Y += Me * cie_colour_match_jd[i][1];
Z += Me * cie_colour_match_jd[i][2];
}
XYZ = (X + Y + Z);
x = X / XYZ;
y = Y / XYZ;
z = Z / XYZ;
}
//calculate XYZ from spectrum data (color) and illuminant : J.Desmis December 2011
void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, Yo=0;
for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) {
double Me;
double Mc;
Me = get_spectral_color(lambda, spec_color);
Mc = get_spectral_color(lambda, spec_intens);
X += Mc * cie_colour_match_jd[i][0] * Me;
Y += Mc * cie_colour_match_jd[i][1] * Me;
Z += Mc * cie_colour_match_jd[i][2] * Me;
}
for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) {
double Ms;
Ms = get_spectral_color(lambda, spec_intens);
Yo += cie_colour_match_jd[i][1] * Ms;
}
xx = X / Yo;
yy = Y / Yo;
zz = Z / Yo;
}
//calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011
void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double _m1, double _m2, double _temp, double &xx, double &yy, double &zz)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, Yo=0;
for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) {
double Me;
double Mc;
Me = get_spectral_color(lambda, spec_color);
Mc = daylight_spect(lambda,_m1, _m2, _temp);
X += Mc * cie_colour_match_jd[i][0] * Me;
Y += Mc * cie_colour_match_jd[i][1] * Me;
Z += Mc * cie_colour_match_jd[i][2] * Me;
}
for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) {
double Ms;
Ms = daylight_spect(lambda,_m1, _m2, _temp);
Yo += cie_colour_match_jd[i][1] * Ms;
}
xx = X / Yo;
yy = Y / Yo;
zz = Z / Yo;
}
//calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011
void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double _m1, double _m2, double _temp, double &xx, double &yy, double &zz)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, Yo=0;
for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) {
double Me;
double Mc;
Me = get_spectral_color(lambda, spec_color);
Mc = blackbody_spect(lambda,_m1, _m2, _temp);
X += Mc * cie_colour_match_jd[i][0] * Me;
Y += Mc * cie_colour_match_jd[i][1] * Me;
Z += Mc * cie_colour_match_jd[i][2] * Me;
}
for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) {
double Ms;
Ms = blackbody_spect(lambda,_m1, _m2, _temp);
Yo += cie_colour_match_jd[i][1] * Ms;
}
xx = X / Yo;
yy = Y / Yo;
zz = Z / Yo;
}
double ColorTemp::daylight_spect(double wavelength, double m1, double m2, double temp)
{
//Values for Daylight illuminant: s0 s1 s2
//s0
static const double s0[97]={61.80,61.65,61.50,65.15,68.80,66.10,63.40,64.60,65.80,80.30,94.80,99.80,104.80,105.35,105.90,101.35,96.80,105.35,113.90,119.75,125.60,125.55,125.50,123.40,121.30,121.30,121.30,117.40,113.50,113.30,
113.10,111.95,110.80,108.65,106.50,107.65,108.80,107.05,105.30,104.85,104.40,102.20,100.00,98.00,96.00,95.55,95.10,92.10,89.10,89.80,90.50,90.40,90.30,89.35,88.40,86.20,84.00,84.55,85.10,
83.50,81.90,82.25,82.60,83.75,84.90,83.10,81.30,76.60,71.90,73.10,74.30,75.35,76.40,69.85,63.30,67.50,71.70,74.35,77.00,71.10,65.20,56.45,47.70,58.15,68.60,66.80,65.00,65.50,66.00,63.50,61.00,57.15,
53.30,56.10,58.90,60.40,61.90};
//s1
static const double s1[97]={41.60,39.80,38.00,40.70,43.40,40.95,38.50,36.75,35.00,39.20,43.40,44.85,46.30,45.10,43.90,40.50,37.10,36.90,36.70,36.30,35.90,34.25,32.60,30.25,27.90,26.10,24.30,22.20,20.10,18.15,16.20,14.70,
13.20,10.90,8.60,7.35,6.10,5.15,4.20,3.05,1.90,0.95,0.00,-0.80,-1.60,-2.55,-3.50,-3.50,-3.50,-4.65,-5.80,-6.50,-7.20,-7.90,-8.60,-9.05,-9.50,-10.20,-10.90,-10.80,-10.70,-11.35,-12.00,-13.00,-14.00,
-13.80,-13.60,-12.80,-12.00,-12.65,-13.30,-13.10,-12.90,-11.75,-10.60,-11.10,-11.60,-11.90,-12.20,-11.20,-10.20,-9.00,-7.80,-9.50,-11.20,-10.80,-10.50,-10.60,-10.15,-9.70,-9.00,-8.30,
-8.80,-9.30,-9.55,-9.80};
//s2
static const double s2[97]={6.70,6.00,5.30,5.70,6.10,4.55,3.00,2.10,1.20,0.05,-1.10,-0.80,-0.50,-0.60,-0.70,-0.95,-1.20,-1.90,-2.60,-2.75,-2.90,-2.85,-2.80,-2.70,-2.60,-2.60,-2.60,-2.20,-1.80,-1.65,-1.50,-1.40,-1.30,
-1.25,-1.20,-1.10,-1.00,-0.75,-0.50,-0.40,-0.30,-0.15,0.00,0.10,0.20,0.35,0.50,1.30,2.10,2.65,3.65,4.10,4.40,4.70,4.90,5.10,5.90,6.70,7.00,7.30,7.95,8.60,9.20,9.80,10.00,10.20,9.25,8.30,8.95,
9.60,9.05,8.50,7.75,7.00,7.30,7.60,7.80,8.00,7.35,6.70,5.95,5.20,6.30,7.40,7.10,6.80,6.90,7.00,6.70,6.40,5.95,5.50,5.80,6.10,6.30,6.50};
int wlm = (int) ((wavelength -350.)/5.);
return (s0[wlm]+m1*s1[wlm]+m2*s2[wlm]);
}
}