Krita Source Code Documentation
Loading...
Searching...
No Matches
LcmsPredefinedPipelineFunctions.cpp File Reference
#include "LcmsPredefinedPipelineFunctions.h"
#include "kis_dom_utils.h"
#include <KoColorTransferFunctions.h>
#include <KoColorProfile.h>
#include <QMatrix4x4>
#include <QVector4D>

Go to the source code of this file.

Classes

struct  perceptualDummyHelper
 

Functions

static QMatrix4x4 bradfordMatrix (QVector4D src, QVector4D dst)
 bradfordMatrix From http://brucelindbloom.com/index.html?Eqn_ChromAdapt.html
 
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. The benefit of HLG is that it sort of allows for tonemapping.
 

Function Documentation

◆ bradfordMatrix()

static QMatrix4x4 bradfordMatrix ( QVector4D src,
QVector4D dst )
static

bradfordMatrix From http://brucelindbloom.com/index.html?Eqn_ChromAdapt.html

Parameters
src– source white point XYZ
dst– destionation white point XYZ
Returns
chromatic adaptation matrix.

Definition at line 20 of file LcmsPredefinedPipelineFunctions.cpp.

20 {
21
22 QVector4D srcLMS(src[0], src[1], src[2], 0.0);
23 QVector4D dstLMS(dst[0], dst[1], dst[2], 0.0);
24
25 const QMatrix4x4 bradfordMatrix(
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,
29 0.0, 0.0, 0.0, 1.0
30 );
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,
35 0.0, 0.0, 0.0, 1.0
36 );
37
38 srcLMS = bradfordMatrix * srcLMS;
39 dstLMS = bradfordMatrix * dstLMS;
40
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,
45 0.0, 0.0, 0.0, 1.0
46 );
47
48
49 return bradfordMatrixInverted * adaptationMatrix * bradfordMatrix;
50}
static QMatrix4x4 bradfordMatrix(QVector4D src, QVector4D dst)
bradfordMatrix From http://brucelindbloom.com/index.html?Eqn_ChromAdapt.html

References bradfordMatrix().

◆ rgbMatrix()

static QMatrix4x4 rgbMatrix ( ColorPrimaries primaries,
double factor = 1.0,
double * luma = nullptr )
static

rgbMatrix Generates a proper rgb matrix from a primaries type.

Parameters
primaries– default primaries to use.
factor– scaling factor.
Returns
transfrom representing a XYZ to RGB conversion.

Definition at line 58 of file LcmsPredefinedPipelineFunctions.cpp.

58 {
59 const double mul = 1.0/factor;
60 // Calculation: http://brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
61 // Calculates XYZ with Y = 1.0
64 KoColorProfile::colorantsForType(primaries, wpXY, col, true);
65
66 QMatrix4x4 initialXYZMatrix(
67 col[0].toXYZ().X, col[1].toXYZ().X, col[2].toXYZ().X, 0.0,
68 1.0, 1.0, 1.0, 0.0,
69 col[0].toXYZ().Z, col[1].toXYZ().Z, col[2].toXYZ().Z, 0.0,
70 0.0, 0.0, 0.0, 1.0
71 );
72
73 // Calculate scaling factor with white point.
74 QVector4D wp(wpXY.toXYZ().X, 1.0, wpXY.toXYZ().Z, 0.0);
75
76 QVector4D S = initialXYZMatrix.inverted() * wp;
77 if (luma) {
78 luma[0] = S.x();
79 luma[1] = S.y();
80 luma[2] = S.z();
81 }
82
83 // Apply scaling factor to normalize the Y and get the matrix.
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,
88 0.0, 0.0, 0.0, 1.0
89 );
90 // Apply bradford white point adaptation.
91 QVector4D wpD50(0.9642, 1.0, 0.8249, 0.0);
92 finalXYZMatrix = bradfordMatrix(wp, wpD50) * finalXYZMatrix;
93
94 finalXYZMatrix.scale(mul);
95 return finalXYZMatrix;
96}
Eigen::Matrix< double, 4, 2 > S
T mul(T a, T b)
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,...

References bradfordMatrix(), KoColorProfile::colorantsForType(), S, KoColorimetryUtils::xy::toXYZ(), KoColorimetryUtils::XYZ::X, and KoColorimetryUtils::XYZ::Z.

◆ samplePQDummyClut()

cmsInt32Number samplePQDummyClut ( const cmsUInt16Number In[],
cmsUInt16Number Out[],
void * Cargo )

samplePQDummyClut In this sampler, we convert the PQ data to linear and then to HLG. The benefit of HLG is that it sort of allows for tonemapping.

Important: this normalizes the pq signal.

scaling the nits value by the HLG scaling factor.

Definition at line 110 of file LcmsPredefinedPipelineFunctions.cpp.

110 {
111 struct perceptualDummyHelper *helper = (struct perceptualDummyHelper *) Cargo;
112 const float pqScale = 125.0;
113 const float nominalPeak = 10000.0/(helper->diffuseWhiteNits * 3.7743);
114
115 float lin[3];
116 for (int i = 0; i < helper->channels; i++) {
117 const float val = float(In[i])/65535.0;
118 if (helper->toXYZ) {
119 lin[i] = (removeSmpte2048Curve(val) / pqScale) * nominalPeak;
120 } else {
121 lin[i] = removeHLGCurve(val);
122 }
123 }
124 for (int i = 0; i < helper->channels; i++) {
125 cmsUInt16Number finalResult = In[i];
126 if (helper->toXYZ) {
127 finalResult = qBound(0, qRound( applyHLGCurve(lin[i]) * 65535 ), 65535);
128 } else {
129 finalResult = qBound(0, qRound( applySmpte2048Curve((lin[i] / nominalPeak) * pqScale) * 65535 ), 65535);
130 }
131 Out[i] = finalResult;
132 }
133 return true;
134};
ALWAYS_INLINE float removeHLGCurve(float x) noexcept
ALWAYS_INLINE float applySmpte2048Curve(float x) noexcept
ALWAYS_INLINE float removeSmpte2048Curve(float x) noexcept
ALWAYS_INLINE float applyHLGCurve(float x) noexcept

References applyHLGCurve(), applySmpte2048Curve(), perceptualDummyHelper::channels, perceptualDummyHelper::diffuseWhiteNits, removeHLGCurve(), removeSmpte2048Curve(), and perceptualDummyHelper::toXYZ.