22 QVector4D srcLMS(src[0], src[1], src[2], 0.0);
23 QVector4D dstLMS(dst[0], dst[1], dst[2], 0.0);
26 0.8951000, 0.2664000, -0.1614000, 0.0,
27 -0.7502000, 1.7135000, 0.0367000, 0.0,
28 0.0389000, -0.0685000, 1.0296000, 0.0,
31 const QMatrix4x4 bradfordMatrixInverted (
32 0.9869929, -0.1470543, 0.1599627, 0.0,
33 0.4323053, 0.5183603, 0.0492912, 0.0,
34 -0.0085287, 0.0400428, 0.9684867, 0.0,
41 const QMatrix4x4 adaptationMatrix (
42 dstLMS.x()/srcLMS.x(), 0, 0, 0,
43 0, dstLMS.y()/srcLMS.y(), 0, 0,
44 0, 0, dstLMS.z()/srcLMS.z(), 0,
59 const double mul = 1.0/factor;
66 QMatrix4x4 initialXYZMatrix(
67 col[0].toXYZ().X, col[1].toXYZ().X, col[2].toXYZ().X, 0.0,
69 col[0].toXYZ().Z, col[1].toXYZ().Z, col[2].toXYZ().Z, 0.0,
76 QVector4D
S = initialXYZMatrix.inverted() * wp;
84 QMatrix4x4 finalXYZMatrix(
85 initialXYZMatrix(0, 0) *
S.x(), initialXYZMatrix(0, 1) *
S.y(), initialXYZMatrix(0, 2) *
S.z(), 0.0,
86 initialXYZMatrix(1, 0) *
S.x(), initialXYZMatrix(1, 1) *
S.y(), initialXYZMatrix(1, 2) *
S.z(), 0.0,
87 initialXYZMatrix(2, 0) *
S.x(), initialXYZMatrix(2, 1) *
S.y(), initialXYZMatrix(2, 2) *
S.z(), 0.0,
91 QVector4D wpD50(0.9642, 1.0, 0.8249, 0.0);
94 finalXYZMatrix.scale(mul);
95 return finalXYZMatrix;
110cmsInt32Number
samplePQDummyClut(
const cmsUInt16Number In[], cmsUInt16Number Out[],
void *Cargo) {
112 const float pqScale = 125.0;
116 for (
int i = 0; i < helper->
channels; i++) {
117 const float val = float(In[i])/65535.0;
124 for (
int i = 0; i < helper->
channels; i++) {
125 cmsUInt16Number finalResult = In[i];
127 finalResult = qBound(0, qRound(
applyHLGCurve(lin[i]) * 65535 ), 65535);
129 finalResult = qBound(0, qRound(
applySmpte2048Curve((lin[i] / nominalPeak) * pqScale) * 65535 ), 65535);
131 Out[i] = finalResult;
139 const double factor = 1.0;
140 const int lutSize = 4;
143 const QMatrix4x4 tf =
rgbMatrix(primaries, factor, luma);
146 cmsPipeline *a2B = cmsPipelineAlloc(
nullptr, 3, 3);
148 cmsToneCurve *linearCurves[3];
149 linearCurves[0] = linearCurves[1] = linearCurves[2] = cmsBuildGamma(
nullptr, 1.0);
150 cmsStage *lCurveStage = cmsStageAllocToneCurves(
nullptr, 3, linearCurves);
151 cmsPipelineInsertStage(a2B, cmsAT_END, lCurveStage);
153 cmsStage *clutStage = cmsStageAllocCLut16bit(
nullptr, lutSize, 3, 3,
nullptr);
159 cmsPipelineInsertStage(a2B, cmsAT_END, clutStage);
162 cmsToneCurve *curve[3];
163 curve[0] = curve[1] = curve[2] = cmsBuildGamma(
nullptr, 2.2);
164 cmsStage *curveStage = cmsStageAllocToneCurves(
nullptr, 3, curve);
165 cmsPipelineInsertStage(a2B, cmsAT_END, curveStage);
170 tf(0, 0), tf(0, 1), tf(0, 2),
171 tf(1, 0), tf(1, 1), tf(1, 2),
172 tf(2, 0), tf(2, 1), tf(2, 2)
175 cmsStage* matrixStage = cmsStageAllocMatrix(
nullptr, 3, 3, m,
nullptr);
176 cmsPipelineInsertStage(a2B, cmsAT_END, matrixStage);
179 cmsPipelineInsertStage(a2B, cmsAT_END, cmsStageDup(lCurveStage));
181 bool success = cmsWriteTag(iccProfile, tag, a2B);
182 cmsFreeToneCurve(curve[0]);
183 cmsFreeToneCurve(linearCurves[0]);
184 cmsPipelineFree(a2B);
191 const double factor = 1.0;
192 const int lutSize = 4;
193 cmsPipeline *b2A = cmsPipelineAlloc(
nullptr, 3, 3);
196 cmsToneCurve *linearCurves[3];
197 linearCurves[0] = linearCurves[1] = linearCurves[2] = cmsBuildGamma(
nullptr, 1.0);
198 cmsStage *lCurveStage = cmsStageAllocToneCurves(
nullptr, 3, linearCurves);
199 cmsPipelineInsertStage(b2A, cmsAT_END, lCurveStage);
203 const QMatrix4x4 tf =
rgbMatrix(primaries, factor, luma).inverted();
205 tf(0, 0), tf(0, 1), tf(0, 2),
206 tf(1, 0), tf(1, 1), tf(1, 2),
207 tf(2, 0), tf(2, 1), tf(2, 2)
210 cmsStage* matrixStage = cmsStageAllocMatrix(
nullptr, 3, 3, m,
nullptr);
211 cmsPipelineInsertStage(b2A, cmsAT_END, matrixStage);
213 cmsToneCurve *curve[3];
214 curve[0] = curve[1] = curve[2] = cmsBuildGamma(
nullptr, 1/2.2);
215 cmsStage *curveStage = cmsStageAllocToneCurves(
nullptr, 3, curve);
216 cmsPipelineInsertStage(b2A, cmsAT_END, curveStage);
218 cmsStage *clutStage = cmsStageAllocCLut16bit(
nullptr, lutSize, 3, 3,
nullptr);
220 helper.
toXYZ =
false;
224 cmsPipelineInsertStage(b2A, cmsAT_END, clutStage);
226 cmsPipelineInsertStage(b2A, cmsAT_END, cmsStageDup(lCurveStage));
228 bool success = cmsWriteTag(iccProfile, tag, b2A);
229 cmsFreeToneCurve(curve[0]);
230 cmsFreeToneCurve(linearCurves[0]);
231 cmsPipelineFree(b2A);
237 bool success =
false;
238 cmsHANDLE dictionary = cmsDictAlloc(
nullptr);
243 cmsMLU *mluName = cmsMLUalloc (NULL, 1);
244 QString name(
"CRWL");
245 cmsMLUsetASCII (mluName,
"en",
"US", name.toLatin1());
248 int count = cmsMLUgetWide(mluName,
"en",
"US",
nullptr, 0);
249 std::vector<wchar_t> nameArray(count);
250 cmsMLUgetWide(mluName,
"en",
"US", nameArray.data(), count);
252 cmsMLU *mluValue = cmsMLUalloc (NULL, 1);
254 cmsMLUsetASCII (mluValue,
"en",
"US",
value.toLatin1());
255 count = cmsMLUgetWide(mluValue,
"en",
"US",
nullptr, 0);
256 std::vector<wchar_t> valArray(count);
257 cmsMLUgetWide(mluValue,
"en",
"US", valArray.data(), count);
259 success = cmsDictAddEntry(dictionary, nameArray.data(), valArray.data(), mluName, mluValue);
262 success = cmsWriteTag(iccProfile, cmsSigMetaTag, dictionary);
266 cmsMLUfree(mluValue);
267 cmsDictFree(dictionary);
cmsInt32Number samplePQDummyClut(const cmsUInt16Number In[], cmsUInt16Number Out[], void *Cargo)
samplePQDummyClut In this sampler, we convert the PQ data to linear and then to HLG....
static void colorantsForType(ColorPrimaries primaries, KoColorimetryUtils::xy &whitePoint, QList< KoColorimetryUtils::xy > &colorants, const bool prequantized=false)
colorantsForPrimaries fills a QVector<float> with the xy values of the whitepoint and red,...