added possibility to specify extra working spaces via a json file

The JSON file is called workingspaces.json, it can be either in the global iccprofiles directory, or in the user's ICC profiles dir (set in preferences).

The format is the following:

{"working_spaces": [
    {
        "name" : "ACES",
        "file" : "/path/to/ACES.icc"
    },
    {
        "name" : "ACEScg",
        "matrix" : [0.7184354, 0.16578523, 0.09882643, 0.29728935, 0.66958117, 0.03571544, -0.00647622, 0.01469771, 0.66732561]
    }
]}

if "matrix" is present, "file" is ignored. If only "file" is present, the matrix is extracted from the ICC profile. For this, we look only at the R, G, and B matrix columns and the white point set in the profile. Bradford adaptation is used to convert the matrix to D50. Anything else (LUT, TRC, ...) in the profile is ignored.

It is the user's responsibility to ensure that the profile is suitable to be used as a working space.
This commit is contained in:
Alberto Griggio
2018-03-20 15:06:09 +01:00
parent 46a556fbaa
commit b09bf381b4
7 changed files with 408 additions and 53 deletions

View File

@@ -37,30 +37,36 @@ namespace
DCPProfile::Matrix invert3x3(const DCPProfile::Matrix& a)
{
const double res00 = a[1][1] * a[2][2] - a[2][1] * a[1][2];
const double res10 = a[2][0] * a[1][2] - a[1][0] * a[2][2];
const double res20 = a[1][0] * a[2][1] - a[2][0] * a[1][1];
const double det = a[0][0] * res00 + a[0][1] * res10 + a[0][2] * res20;
if (std::fabs(det) < 1.0e-10) {
DCPProfile::Matrix res = a;
if (!invertMatrix(a, res)) {
std::cerr << "DCP matrix cannot be inverted! Expect weird output." << std::endl;
return a;
}
DCPProfile::Matrix res;
res[0][0] = res00 / det;
res[0][1] = (a[2][1] * a[0][2] - a[0][1] * a[2][2]) / det;
res[0][2] = (a[0][1] * a[1][2] - a[1][1] * a[0][2]) / det;
res[1][0] = res10 / det;
res[1][1] = (a[0][0] * a[2][2] - a[2][0] * a[0][2]) / det;
res[1][2] = (a[1][0] * a[0][2] - a[0][0] * a[1][2]) / det;
res[2][0] = res20 / det;
res[2][1] = (a[2][0] * a[0][1] - a[0][0] * a[2][1]) / det;
res[2][2] = (a[0][0] * a[1][1] - a[1][0] * a[0][1]) / det;
return res;
// const double res00 = a[1][1] * a[2][2] - a[2][1] * a[1][2];
// const double res10 = a[2][0] * a[1][2] - a[1][0] * a[2][2];
// const double res20 = a[1][0] * a[2][1] - a[2][0] * a[1][1];
// const double det = a[0][0] * res00 + a[0][1] * res10 + a[0][2] * res20;
// if (std::fabs(det) < 1.0e-10) {
// std::cerr << "DCP matrix cannot be inverted! Expect weird output." << std::endl;
// return a;
// }
// DCPProfile::Matrix res;
// res[0][0] = res00 / det;
// res[0][1] = (a[2][1] * a[0][2] - a[0][1] * a[2][2]) / det;
// res[0][2] = (a[0][1] * a[1][2] - a[1][1] * a[0][2]) / det;
// res[1][0] = res10 / det;
// res[1][1] = (a[0][0] * a[2][2] - a[2][0] * a[0][2]) / det;
// res[1][2] = (a[1][0] * a[0][2] - a[0][0] * a[1][2]) / det;
// res[2][0] = res20 / det;
// res[2][1] = (a[2][0] * a[0][1] - a[0][0] * a[2][1]) / det;
// res[2][2] = (a[0][0] * a[1][1] - a[1][0] * a[0][1]) / det;
// return res;
}
DCPProfile::Matrix multiply3x3(const DCPProfile::Matrix& a, const DCPProfile::Matrix& b)