Krita Source Code Documentation
Loading...
Searching...
No Matches
KoColorSpaceMaths.h File Reference
#include <cmath>
#include <limits>
#include "kritapigment_export.h"
#include <KoIntegerMaths.h>
#include "KoChannelInfo.h"
#include "KoLut.h"
#include <kis_global.h>
#include <KoConfig.h>

Go to the source code of this file.

Classes

struct  HSIType
 
struct  HSLType
 
struct  HSVType
 
struct  HSYType
 
class  KoColorSpaceMaths< _T, _Tdst >
 
class  KoColorSpaceMathsTraits< _T >
 
class  KoColorSpaceMathsTraits< double >
 
class  KoColorSpaceMathsTraits< float >
 
class  KoColorSpaceMathsTraits< qint16 >
 
class  KoColorSpaceMathsTraits< quint16 >
 
class  KoColorSpaceMathsTraits< quint32 >
 
class  KoColorSpaceMathsTraits< quint8 >
 
struct  KoIntegerToFloat< _T_ >
 
struct  KoLuts
 

Namespaces

namespace  Arithmetic
 

Functions

template<class HSXType , class TReal >
void addLightness (TReal &r, TReal &g, TReal &b, TReal light)
 
template<class T >
KoColorSpaceMathsTraits< T >::compositetype Arithmetic::and (T a, T b)
 
template<class T >
Arithmetic::blend (T src, T srcAlpha, T dst, T dstAlpha, T cfValue)
 
template<class T >
Arithmetic::clamp (typename KoColorSpaceMathsTraits< T >::compositetype a)
 
template<class T >
Arithmetic::clampChannelToSDR (T a)
 
template<class T >
Arithmetic::clampChannelToSDRBottom (T a)
 
template<class T >
Arithmetic::clampToSDR (typename KoColorSpaceMathsTraits< T >::compositetype a)
 
template<class T >
Arithmetic::clampToSDRBottom (typename KoColorSpaceMathsTraits< T >::compositetype a)
 
template<class T >
Arithmetic::clampToSDRTop (typename KoColorSpaceMathsTraits< T >::compositetype a)
 
template<class T >
KoColorSpaceMathsTraits< T >::compositetype Arithmetic::div (T a, T b)
 
template<class T , typename composite_type = typename KoColorSpaceMathsTraits<T>::compositetype>
composite_type Arithmetic::divideInCompositeSpace (composite_type a, composite_type b)
 
template<class T >
Arithmetic::epsilon ()
 
int float2int (double x)
 
int float2int (float x)
 
template<class TReal >
TReal getHue (TReal r, TReal g, TReal b)
 
template<class HSXType , class TReal >
static TReal getLightness (TReal r, TReal g, TReal b)
 
template<class TReal >
void getRGB (TReal &r, TReal &g, TReal &b, TReal hue)
 
template<class HSXType , class TReal >
static TReal getSaturation (TReal r, TReal g, TReal b)
 
template<class T >
Arithmetic::halfValue ()
 
template<class T >
Arithmetic::inv (T a)
 
template<typename T >
static bool Arithmetic::isHalfValueFuzzy (T v)
 
template<typename T >
static bool Arithmetic::isUnitValueClampedFuzzy (T v)
 
template<typename T >
bool Arithmetic::isUnitValueClampedStrict (T value)
 
template<typename T >
static bool Arithmetic::isUnitValueFuzzy (T v)
 
template<typename T >
bool Arithmetic::isUnitValueStrict (T value)
 
template<typename T >
Arithmetic::isUnsafeAsDivisor (T value)
 
template<typename T >
static bool Arithmetic::isZeroValueClampedFuzzy (T v)
 
template<typename T >
bool Arithmetic::isZeroValueClampedStrict (T value)
 
template<typename T >
static bool Arithmetic::isZeroValueFuzzy (T v)
 
template<typename T >
bool Arithmetic::isZeroValueStrict (T value)
 
template<class T >
Arithmetic::lerp (T a, T b, T alpha)
 
template<class T >
Arithmetic::max (T a, T b, T c)
 
template<class T >
Arithmetic::min (T a, T b, T c)
 
template<class T >
KoColorSpaceMathsTraits< T >::compositetype Arithmetic::mod (T a, T b)
 
template<class T >
Arithmetic::mul (T a, T b)
 
template<class T >
Arithmetic::mul (T a, T b, T c)
 
template<class T , typename composite_type = typename KoColorSpaceMathsTraits<T>::compositetype>
composite_type Arithmetic::multiplyInCompositeSpace (composite_type a, composite_type b)
 
template<class T >
KoColorSpaceMathsTraits< T >::compositetype Arithmetic::or (T a, T b)
 
template<class TRet , class T >
TRet Arithmetic::scale (T a)
 
template<class HSXType , class TReal >
void setLightness (TReal &r, TReal &g, TReal &b, TReal light)
 
template<class HSXType , class TReal >
void setSaturation (TReal &r, TReal &g, TReal &b, TReal sat)
 
template<class HSXType , class TReal >
void ToneMapping (TReal &r, TReal &g, TReal &b)
 
template<class T >
Arithmetic::unionShapeOpacity (T a, T b)
 
template<class T >
Arithmetic::unitValue ()
 
template<class T >
KoColorSpaceMathsTraits< T >::compositetype Arithmetic::xor (T a, T b)
 
template<class T >
Arithmetic::zeroValue ()
 

Variables

static const qreal Arithmetic::pi = 3.14159265358979323846
 

Function Documentation

◆ addLightness()

template<class HSXType , class TReal >
void addLightness ( TReal & r,
TReal & g,
TReal & b,
TReal light )
inline

Definition at line 1123 of file KoColorSpaceMaths.h.

1124{
1125 using namespace Arithmetic;
1126
1127 r += light;
1128 g += light;
1129 b += light;
1130
1131 ToneMapping<HSXType, TReal>(r, g, b);
1132}

◆ float2int() [1/2]

int float2int ( double x)
inline

Definition at line 173 of file KoColorSpaceMaths.h.

174{
175 // NOTE: we don't use rint() here, because on Windows
176 // it falls back to x87 instructions on Intel CPUs,
177 // which are executed extremely slowly
178 // NOTE2: we do always clamp value to 0...0xff range
179 // before calling this function, so `x` cannot be
180 // negative.
181 return int(x + 0.5);
182}

◆ float2int() [2/2]

int float2int ( float x)
inline

Definition at line 162 of file KoColorSpaceMaths.h.

163{
164 // NOTE: we don't use rint() here, because on Windows
165 // it falls back to x87 instructions on Intel CPUs,
166 // which are executed extremely slowly
167 // NOTE2: we do always clamp value to 0...0xff range
168 // before calling this function, so `x` cannot be
169 // negative.
170 return int(x + 0.5f);
171}

◆ getHue()

template<class TReal >
TReal getHue ( TReal r,
TReal g,
TReal b )

Definition at line 988 of file KoColorSpaceMaths.h.

988 {
989 TReal min = Arithmetic::min(r, g, b);
990 TReal max = Arithmetic::max(r, g, b);
991 TReal chroma = max - min;
992
993 TReal hue = TReal(-1.0);
994
995 if(chroma > std::numeric_limits<TReal>::epsilon()) {
996
997// return atan2(TReal(2.0)*r - g - b, TReal(1.73205080756887729353)*(g - b));
998
999 if(max == r) // between yellow and magenta
1000 hue = (g - b) / chroma;
1001 else if(max == g) // between cyan and yellow
1002 hue = TReal(2.0) + (b - r) / chroma;
1003 else if(max == b) // between magenta and cyan
1004 hue = TReal(4.0) + (r - g) / chroma;
1005
1006 if(hue < -std::numeric_limits<TReal>::epsilon())
1007 hue += TReal(6.0);
1008
1009 hue /= TReal(6.0);
1010 }
1011
1012// hue = (r == max) ? (b-g) : (g == max) ? TReal(2.0)+(r-b) : TReal(4.0)+(g-r);
1013
1014 return hue;
1015}
T max(T a, T b, T c)
T min(T a, T b, T c)
constexpr std::enable_if< sizeof...(values)==0, size_t >::type max()

References Arithmetic::max(), and Arithmetic::min().

◆ getLightness()

template<class HSXType , class TReal >
static TReal getLightness ( TReal r,
TReal g,
TReal b )
inlinestatic

Definition at line 1047 of file KoColorSpaceMaths.h.

1047 {
1048 return HSXType::getLightness(r, g, b);
1049}

◆ getRGB()

template<class TReal >
void getRGB ( TReal & r,
TReal & g,
TReal & b,
TReal hue )

Definition at line 1018 of file KoColorSpaceMaths.h.

1018 {
1019 // 0 red -> (1,0,0)
1020 // 1 yellow -> (1,1,0)
1021 // 2 green -> (0,1,0)
1022 // 3 cyan -> (0,1,1)
1023 // 4 blue -> (0,0,1)
1024 // 5 magenta -> (1,0,1)
1025 // 6 red -> (1,0,0)
1026
1027 if(hue < -std::numeric_limits<TReal>::epsilon()) {
1028 r = g = b = TReal(0.0);
1029 return;
1030 }
1031
1032 int i = int(hue * TReal(6.0));
1033 TReal x = hue * TReal(6.0) - i;
1034 TReal y = TReal(1.0) - x;
1035
1036 switch(i % 6){
1037 case 0: { r=TReal(1.0), g=x , b=TReal(0.0); } break;
1038 case 1: { r=y , g=TReal(1.0), b=TReal(0.0); } break;
1039 case 2: { r=TReal(0.0), g=TReal(1.0), b=x ; } break;
1040 case 3: { r=TReal(0.0), g=y , b=TReal(1.0); } break;
1041 case 4: { r=x , g=TReal(0.0), b=TReal(1.0); } break;
1042 case 5: { r=TReal(1.0), g=TReal(0.0), b=y ; } break;
1043 }
1044}

◆ getSaturation()

template<class HSXType , class TReal >
static TReal getSaturation ( TReal r,
TReal g,
TReal b )
inlinestatic

Definition at line 1141 of file KoColorSpaceMaths.h.

1141 {
1142 return HSXType::getSaturation(r, g, b);
1143}

◆ setLightness()

template<class HSXType , class TReal >
void setLightness ( TReal & r,
TReal & g,
TReal & b,
TReal light )
inline

Definition at line 1135 of file KoColorSpaceMaths.h.

1136{
1137 addLightness<HSXType>(r,g,b, light - HSXType::getLightness(r,g,b));
1138}

◆ setSaturation()

template<class HSXType , class TReal >
void setSaturation ( TReal & r,
TReal & g,
TReal & b,
TReal sat )
inline

Definition at line 1146 of file KoColorSpaceMaths.h.

1147{
1148 int min = 0;
1149 int mid = 1;
1150 int max = 2;
1151 TReal rgb[3] = {r, g, b};
1152
1153 if(rgb[mid] < rgb[min]) {
1154 int tmp = min;
1155 min = mid;
1156 mid = tmp;
1157 }
1158
1159 if(rgb[max] < rgb[mid]) {
1160 int tmp = mid;
1161 mid = max;
1162 max = tmp;
1163 }
1164
1165 if(rgb[mid] < rgb[min]) {
1166 int tmp = min;
1167 min = mid;
1168 mid = tmp;
1169 }
1170
1171 if((rgb[max] - rgb[min]) > std::numeric_limits<TReal>::epsilon()) {
1172 rgb[mid] = ((rgb[mid]-rgb[min]) * sat) / (rgb[max]-rgb[min]);
1173 rgb[max] = sat;
1174 rgb[min] = TReal(0.0);
1175
1176 r = rgb[0];
1177 g = rgb[1];
1178 b = rgb[2];
1179 }
1180 else r = g = b = TReal(0.0);
1181}

◆ ToneMapping()

template<class HSXType , class TReal >
void ToneMapping ( TReal & r,
TReal & g,
TReal & b )
inline

The tonemapping method we use does not support lightness values below 0.0, so we just clamp the value.

TODO: use proper HSV/HSI shape-tracking clamping methods we use in kis_hsv_adjustment.cpp

The tonemapping method we use does not support lightness values above 1.0, so we just clamp the value.

TODO: use proper HSV/HSI shape-tracking clamping methods we use in kis_hsv_adjustment.cpp

Definition at line 1052 of file KoColorSpaceMaths.h.

1053{
1054 using namespace Arithmetic;
1055
1056
1057 TReal l = HSXType::getLightness(r, g, b);
1058 TReal n = min(r, g, b);
1059 TReal x = max(r, g, b);
1060
1061 if(n < TReal(0.0)) {
1062 if (isZeroValueClampedFuzzy<float>(l)) {
1070 r = g = b = TReal(0.0);
1071 } else {
1072 const TReal stretch = l - n;
1073
1074 if (stretch < std::numeric_limits<TReal>::epsilon()) {
1075 r = g = b = TReal(0.0);
1076 } else {
1077 TReal iln = TReal(1.0) / stretch;
1078 r = l + ((r-l) * l) * iln;
1079 g = l + ((g-l) * l) * iln;
1080 b = l + ((b-l) * l) * iln;
1081 }
1082 }
1083 }
1084
1085 if(x > TReal(1.0)) {
1086 auto setFallbackValues = [&] () {
1087 if constexpr (HSXType::lightnessIsAverage) {
1088 r = g = b = TReal(1.0);
1089 } else {
1090 r = qMin(r, TReal(1.0));
1091 g = qMin(g, TReal(1.0));
1092 b = qMin(b, TReal(1.0));
1093 }
1094 };
1095
1096 if (l > TReal(1.0)) {
1104 setFallbackValues();
1105 } else {
1106 const TReal stretch = x - l;
1107
1108 if (stretch < std::numeric_limits<TReal>::epsilon()) {
1109 setFallbackValues();
1110 } else {
1111 TReal il = TReal(1.0) - l;
1112 TReal ixl = TReal(1.0) / stretch;
1113
1114 r = l + ((r-l) * il) * ixl;
1115 g = l + ((g-l) * il) * ixl;
1116 b = l + ((b-l) * il) * ixl;
1117 }
1118 }
1119 }
1120}