Krita Source Code Documentation
Loading...
Searching...
No Matches
LcmsPredefinedPipelineFunctions Class Reference

The LcmsPredfinedPipelineFunctions class This class defines static functions to help create ICC profiles with LCMS. More...

#include <LcmsPredefinedPipelineFunctions.h>

Static Public Member Functions

static bool setDiffuseWhitePerceptualQuantizer (cmsHPROFILE iccProfile, double diffuseWhiteNits=80.0)
 setDiffuseWhitePerceptualQuantizer This adds a dictionary with an CRWL entry to the profile.
 
static bool setPerceptualQuantizerAToBDummyPipeline (cmsHPROFILE iccProfile, cmsTagSignature tag, ColorPrimaries primaries, double diffuseWhiteNits=80.0)
 
static bool setPerceptualQuantizerBToADummyPipeline (cmsHPROFILE iccProfile, cmsTagSignature tag, ColorPrimaries primaries, double diffuseWhiteNits=80.0)
 

Detailed Description

The LcmsPredfinedPipelineFunctions class This class defines static functions to help create ICC profiles with LCMS.

Definition at line 19 of file LcmsPredefinedPipelineFunctions.h.

Member Function Documentation

◆ setDiffuseWhitePerceptualQuantizer()

bool LcmsPredefinedPipelineFunctions::setDiffuseWhitePerceptualQuantizer ( cmsHPROFILE iccProfile,
double diffuseWhiteNits = 80.0 )
static

setDiffuseWhitePerceptualQuantizer This adds a dictionary with an CRWL entry to the profile.

Returns
whether it was successfully written.

Definition at line 235 of file LcmsPredefinedPipelineFunctions.cpp.

236{
237 bool success = false;
238 cmsHANDLE dictionary = cmsDictAlloc(nullptr);
239
240
241
242 // https://registry.color.org/dicttype-metadata/crwl
243 cmsMLU *mluName = cmsMLUalloc (NULL, 1);
244 QString name("CRWL");
245 cmsMLUsetASCII (mluName, "en", "US", name.toLatin1());
246
247 // Hack to avoid having to figure out how to get the value.
248 int count = cmsMLUgetWide(mluName, "en", "US", nullptr, 0);
249 std::vector<wchar_t> nameArray(count);
250 cmsMLUgetWide(mluName, "en", "US", nameArray.data(), count);
251
252 cmsMLU *mluValue = cmsMLUalloc (NULL, 1);
253 QString value = KisDomUtils::toString(diffuseWhiteNits);
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);
258
259 success = cmsDictAddEntry(dictionary, nameArray.data(), valArray.data(), mluName, mluValue);
260
261 if (success) {
262 success = cmsWriteTag(iccProfile, cmsSigMetaTag, dictionary);
263 }
264
265 cmsMLUfree(mluName);
266 cmsMLUfree(mluValue);
267 cmsDictFree(dictionary);
268 return success;
269}
float value(const T *src, size_t ch)
const char * name(StandardAction id)
QString toString(const QString &value)

References KisDomUtils::toString(), and value().

◆ setPerceptualQuantizerAToBDummyPipeline()

bool LcmsPredefinedPipelineFunctions::setPerceptualQuantizerAToBDummyPipeline ( cmsHPROFILE iccProfile,
cmsTagSignature tag,
ColorPrimaries primaries,
double diffuseWhiteNits = 80.0 )
static

Definition at line 136 of file LcmsPredefinedPipelineFunctions.cpp.

137{
138 // From profile space to XYZ.
139 const double factor = 1.0;
140 const int lutSize = 4;
141
142 double luma[3];
143 const QMatrix4x4 tf = rgbMatrix(primaries, factor, luma);
144
145 // linear curves, obligatory for A2B with both matrix and clut: linear-clut-curves-matrix-linear.
146 cmsPipeline *a2B = cmsPipelineAlloc(nullptr, 3, 3);
147
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);
152
153 cmsStage *clutStage = cmsStageAllocCLut16bit(nullptr, lutSize, 3, 3, nullptr);
155 helper.toXYZ = true;
156 helper.luma = luma;
157 helper.diffuseWhiteNits = diffuseWhiteNits;
158 cmsStageSampleCLut16bit(clutStage, &samplePQDummyClut, &helper, 0);
159 cmsPipelineInsertStage(a2B, cmsAT_END, clutStage);
160
161 // close to "PQ" curve
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);
166
167 // matrix
168
169 double m[] = {
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)
173 };
174
175 cmsStage* matrixStage = cmsStageAllocMatrix(nullptr, 3, 3, m, nullptr);
176 cmsPipelineInsertStage(a2B, cmsAT_END, matrixStage);
177
178 // curves, linear
179 cmsPipelineInsertStage(a2B, cmsAT_END, cmsStageDup(lCurveStage));
180
181 bool success = cmsWriteTag(iccProfile, tag, a2B);
182 cmsFreeToneCurve(curve[0]);
183 cmsFreeToneCurve(linearCurves[0]);
184 cmsPipelineFree(a2B);
185 return success;
186}
static QMatrix4x4 rgbMatrix(ColorPrimaries primaries, double factor=1.0, double *luma=nullptr)
rgbMatrix Generates a proper rgb matrix from a primaries type.
cmsInt32Number samplePQDummyClut(const cmsUInt16Number In[], cmsUInt16Number Out[], void *Cargo)
samplePQDummyClut In this sampler, we convert the PQ data to linear and then to HLG....

References perceptualDummyHelper::diffuseWhiteNits, perceptualDummyHelper::luma, rgbMatrix(), samplePQDummyClut(), and perceptualDummyHelper::toXYZ.

◆ setPerceptualQuantizerBToADummyPipeline()

bool LcmsPredefinedPipelineFunctions::setPerceptualQuantizerBToADummyPipeline ( cmsHPROFILE iccProfile,
cmsTagSignature tag,
ColorPrimaries primaries,
double diffuseWhiteNits = 80.0 )
static

Definition at line 188 of file LcmsPredefinedPipelineFunctions.cpp.

189{
190 // From XYZ to profile space.
191 const double factor = 1.0;
192 const int lutSize = 4;
193 cmsPipeline *b2A = cmsPipelineAlloc(nullptr, 3, 3);
194
195 // curves, linear
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);
200
201 // matrix
202 double luma[3];
203 const QMatrix4x4 tf = rgbMatrix(primaries, factor, luma).inverted();
204 double m[] = {
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)
208 };
209
210 cmsStage* matrixStage = cmsStageAllocMatrix(nullptr, 3, 3, m, nullptr);
211 cmsPipelineInsertStage(b2A, cmsAT_END, matrixStage);
212 // pq curve
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);
217
218 cmsStage *clutStage = cmsStageAllocCLut16bit(nullptr, lutSize, 3, 3, nullptr);
220 helper.toXYZ = false;
221 helper.luma = luma;
222 helper.diffuseWhiteNits = diffuseWhiteNits;
223 cmsStageSampleCLut16bit(clutStage, &samplePQDummyClut, &helper, 0);
224 cmsPipelineInsertStage(b2A, cmsAT_END, clutStage);
225
226 cmsPipelineInsertStage(b2A, cmsAT_END, cmsStageDup(lCurveStage));
227
228 bool success = cmsWriteTag(iccProfile, tag, b2A);
229 cmsFreeToneCurve(curve[0]);
230 cmsFreeToneCurve(linearCurves[0]);
231 cmsPipelineFree(b2A);
232 return success;
233}

References perceptualDummyHelper::diffuseWhiteNits, perceptualDummyHelper::luma, rgbMatrix(), samplePQDummyClut(), and perceptualDummyHelper::toXYZ.


The documentation for this class was generated from the following files: