Krita Source Code Documentation
Loading...
Searching...
No Matches
KoColorSpacePreserveLightnessUtils.h File Reference
#include <KoColorSpaceMaths.h>
#include "kis_global.h"

Go to the source code of this file.

Functions

template<typename CSTraits >
static void fillGrayBrushWithColorPreserveLightnessRGB (quint8 *pixels, const QRgb *brush, quint8 *brushColor, qreal strength, qint32 nPixels)
 
template<typename CSTraits >
static void modulateLightnessByGrayBrushRGB (quint8 *pixels, const QRgb *brush, qreal strength, qint32 nPixels)
 

Function Documentation

◆ fillGrayBrushWithColorPreserveLightnessRGB()

template<typename CSTraits >
static void fillGrayBrushWithColorPreserveLightnessRGB ( quint8 * pixels,
const QRgb * brush,
quint8 * brushColor,
qreal strength,
qint32 nPixels )
inlinestatic

Lightness mixing algorithm is developed by Peter Schatz voron.nosp@m.we13.nosp@m.@gmai.nosp@m.l.co.nosp@m.m

We use a formula f(x) where f(0) = 0, f(1) = 1, and f(.5) = z, where z is the lightness of the brush color. This can’t be linear unless the color chosen is also .5. So we use a quadratic equation:

f(x) = ax^2 + b^x +c 0,0 -> 0 = a0^2 + b0 + c -> c = 0 1,1 -> 1 = a1^2 +b1 + c -> 1 = a + b + 0 -> a = 1 - b .5,z -> z = a*.5^2 + b*.5 + c -> z = = a/4 + b/2 + 0 -> z = = 1/4 - b/4 + b/2 -> z = 1/4 + b/4 -> b = 4z - 1

f(x) = (1 - (4z - 1)) * x^2 + (4z - 1) * x

Definition at line 15 of file KoColorSpacePreserveLightnessUtils.h.

15 {
16 using RGBPixel = typename CSTraits::Pixel;
17 using channels_type = typename CSTraits::channels_type;
18 static const quint32 pixelSize = CSTraits::pixelSize;
19
20 const RGBPixel *srcColorRGB = reinterpret_cast<const RGBPixel*>(brushColor);
21
22 const float srcColorR = KoColorSpaceMaths<channels_type, float>::scaleToA(srcColorRGB->red);
23 const float srcColorG = KoColorSpaceMaths<channels_type, float>::scaleToA(srcColorRGB->green);
24 const float srcColorB = KoColorSpaceMaths<channels_type, float>::scaleToA(srcColorRGB->blue);
25 const float srcColorA = KoColorSpaceMaths<channels_type, float>::scaleToA(srcColorRGB->alpha);
26
44 const float srcColorL = getLightness<HSLType, float>(srcColorR, srcColorG, srcColorB);
45 const float lightnessB = 4 * srcColorL - 1;
46 const float lightnessA = 1 - lightnessB;
47
48 for (; nPixels > 0; --nPixels, pixels += pixelSize, ++brush) {
49 float brushMaskL = qRed(*brush) / 255.0f;
50 brushMaskL = (brushMaskL - 0.5) * strength + 0.5;
51 const float finalAlpha = qMin(qAlpha(*brush) / 255.0f, srcColorA);
52 float finalLightness = lightnessA * pow2(brushMaskL) + lightnessB * brushMaskL;
53 finalLightness = qBound(0.0f, finalLightness, 1.0f);
54
55 float pixelR = srcColorR;
56 float pixelG = srcColorG;
57 float pixelB = srcColorB;
58
59 setLightness<HSLType, float>(pixelR, pixelG, pixelB, finalLightness);
60
61 RGBPixel *pixelRGB = reinterpret_cast<RGBPixel*>(pixels);
65 pixelRGB->alpha = KoColorSpaceMaths<quint8, channels_type>::scaleToA(quint8(finalAlpha * 255));
66 }
67}
static _Tdst scaleToA(_T a)
T pow2(const T &x)
Definition kis_global.h:166

References pow2(), and KoColorSpaceMaths< _T, _Tdst >::scaleToA().

◆ modulateLightnessByGrayBrushRGB()

template<typename CSTraits >
static void modulateLightnessByGrayBrushRGB ( quint8 * pixels,
const QRgb * brush,
qreal strength,
qint32 nPixels )
inlinestatic

Lightness mixing algorithm is developed by Peter Schatz voron.nosp@m.we13.nosp@m.@gmai.nosp@m.l.co.nosp@m.m

We use a formula f(x) where f(0) = 0, f(1) = 1, and f(.5) = z, where z is the lightness of the brush color. This can’t be linear unless the color chosen is also .5. So we use a quadratic equation:

f(x) = ax^2 + b^x +c 0,0 -> 0 = a0^2 + b0 + c -> c = 0 1,1 -> 1 = a1^2 +b1 + c -> 1 = a + b + 0 -> a = 1 - b .5,z -> z = a*.5^2 + b*.5 + c -> z = = a/4 + b/2 + 0 -> z = = 1/4 - b/4 + b/2 -> z = 1/4 + b/4 -> b = 4z - 1

f(x) = (1 - (4z - 1)) * x^2 + (4z - 1) * x

Definition at line 70 of file KoColorSpacePreserveLightnessUtils.h.

70 {
71 using RGBPixel = typename CSTraits::Pixel;
72 using channels_type = typename CSTraits::channels_type;
73 static const quint32 pixelSize = CSTraits::pixelSize;
74
75
93 for (; nPixels > 0; --nPixels, pixels += pixelSize, ++brush) {
94
95 RGBPixel *pixelRGB = reinterpret_cast<RGBPixel*>(pixels);
96
97 const float srcColorR = KoColorSpaceMaths<channels_type, float>::scaleToA(pixelRGB->red);
98 const float srcColorG = KoColorSpaceMaths<channels_type, float>::scaleToA(pixelRGB->green);
99 const float srcColorB = KoColorSpaceMaths<channels_type, float>::scaleToA(pixelRGB->blue);
100 //const float srcColorA = KoColorSpaceMaths<channels_type, float>::scaleToA(pixelRGB->alpha);
101
102 const float srcColorL = getLightness<HSLType, float>(srcColorR, srcColorG, srcColorB);
103 float brushMaskL = qRed(*brush) / 255.0f;
104 brushMaskL = (brushMaskL - 0.5) * strength * qAlpha(*brush) / 255.0 + 0.5;
105
106 const float lightnessB = 4 * srcColorL - 1;
107 const float lightnessA = 1 - lightnessB;
108
109 float finalLightness = lightnessA * pow2(brushMaskL) + lightnessB * brushMaskL;
110 finalLightness = qBound(0.0f, finalLightness, 1.0f);
111
112 float pixelR = srcColorR;
113 float pixelG = srcColorG;
114 float pixelB = srcColorB;
115
116 setLightness<HSLType, float>(pixelR, pixelG, pixelB, finalLightness);
117
121 //pixelRGB->alpha = KoColorSpaceMaths<quint8, channels_type>::scaleToA(quint8(finalAlpha * 255));
122 }
123}

References pow2(), and KoColorSpaceMaths< _T, _Tdst >::scaleToA().