Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_hsv_adjustment.cpp File Reference
#include "kis_hsv_adjustment.h"
#include <KoConfig.h>
#include <kis_debug.h>
#include <klocalizedstring.h>
#include <KoColorConversions.h>
#include <KoColorModelStandardIds.h>
#include <KoColorSpace.h>
#include <KoColorSpaceTraits.h>
#include <KoColorTransformation.h>
#include <KoID.h>
#include "kis_global.h"

Go to the source code of this file.

Classes

struct  HCIPolicy
 
struct  HCYPolicy
 
struct  HSLPolicy
 
struct  HSVPolicy
 
class  KisHSVAdjustment< _channel_type_, traits >
 
class  KisHSVCurveAdjustment< _channel_type_, traits >
 

Macros

#define FLOAT_CLAMP(v)   *v = (*v < 0.0) ? 0.0 : ( (*v>1.0) ? 1.0 : *v )
 
#define SCALE_FROM_FLOAT(v)   KoColorSpaceMaths< float, _channel_type_>::scaleToA( v )
 
#define SCALE_TO_FLOAT(v)   KoColorSpaceMaths< _channel_type_, float>::scaleToA( v )
 

Functions

template<typename _channel_type_ >
void clamp (float *r, float *g, float *b)
 
template<>
void clamp< float > (float *r, float *g, float *b)
 
template<>
void clamp< quint16 > (float *r, float *g, float *b)
 
template<>
void clamp< quint8 > (float *r, float *g, float *b)
 
template<class ValuePolicy >
void HSVTransform (float *r, float *g, float *b, float dh, float ds, float dv, ValuePolicy valuePolicy)
 
static void writeRGBSimple (float *r, float *g, float *b, int sextant, float x, float m, float M)
 

Macro Definition Documentation

◆ FLOAT_CLAMP

#define FLOAT_CLAMP ( v)    *v = (*v < 0.0) ? 0.0 : ( (*v>1.0) ? 1.0 : *v )

Definition at line 30 of file kis_hsv_adjustment.cpp.

◆ SCALE_FROM_FLOAT

#define SCALE_FROM_FLOAT ( v)    KoColorSpaceMaths< float, _channel_type_>::scaleToA( v )

Definition at line 25 of file kis_hsv_adjustment.cpp.

◆ SCALE_TO_FLOAT

#define SCALE_TO_FLOAT ( v)    KoColorSpaceMaths< _channel_type_, float>::scaleToA( v )

Definition at line 24 of file kis_hsv_adjustment.cpp.

Function Documentation

◆ clamp()

template<typename _channel_type_ >
void clamp ( float * r,
float * g,
float * b )

◆ clamp< float >()

template<>
void clamp< float > ( float * r,
float * g,
float * b )

Definition at line 59 of file kis_hsv_adjustment.cpp.

60{
61 *r = qMax(0.0f, *r);
62 *g = qMax(0.0f, *g);
63 *b = qMax(0.0f, *b);
64}

◆ clamp< quint16 >()

template<>
void clamp< quint16 > ( float * r,
float * g,
float * b )

Definition at line 41 of file kis_hsv_adjustment.cpp.

42{
43 FLOAT_CLAMP(r);
44 FLOAT_CLAMP(g);
45 FLOAT_CLAMP(b);
46}
#define FLOAT_CLAMP(v)

References FLOAT_CLAMP.

◆ clamp< quint8 >()

template<>
void clamp< quint8 > ( float * r,
float * g,
float * b )

Definition at line 33 of file kis_hsv_adjustment.cpp.

34{
35 FLOAT_CLAMP(r);
36 FLOAT_CLAMP(g);
37 FLOAT_CLAMP(b);
38}

References FLOAT_CLAMP.

◆ HSVTransform()

template<class ValuePolicy >
void HSVTransform ( float * r,
float * g,
float * b,
float dh,
float ds,
float dv,
ValuePolicy valuePolicy )

approximation of a nonlinear slider: ds = 0.0 -> chroma *= 1.0; ds = 0.5 -> chroma *= 2.0; ds = 1.0 -> chroma *= 4.0;

Definition at line 237 of file kis_hsv_adjustment.cpp.

238{
239 static const float EPSILON = 1e-9f;
240
241 float h;
242
243 float M = qMax(*r, qMax(*g, *b));
244 float m = qMin(*r, qMin(*g, *b));
245
246 float chroma = M - m;
247
248 float v = valuePolicy.valueFromRGB(*r, *g, *b, m, M);
249
250 if (!valuePolicy.hasChroma(v)) {
251 chroma = 0.0f;
252 h = 0.0f;
253 if (dv < 0) {
254 v *= dv + 1.0f;
255 } else {
256 v += dv * (1.0f - v);
257 }
258 } else {
259 if (chroma > EPSILON) {
260 if (*r == M)
261 h = (*g - *b) / chroma;
262 else if (*g == M)
263 h = 2 + (*b - *r) / chroma;
264 else
265 h = 4 + (*r - *g) / chroma;
266
267 h *= 60;
268 h += dh * 180;
269
271
272 if (ds > 0) {
277
278 chroma = qMin(1.0f, chroma * (1.0f + ds + 2.0f * pow2(ds)));
279 } else {
280 chroma *= ds + 1.0f;
281 }
282
283 } else {
284 h = 0.0f;
285 }
286
287 {
288 const float dstV = dv > 0.0f ? 1.0f : 0.0f;
289 const float vCoeff = dstV - v;
290 const float chromaCoeff = 0 - chroma;
291 const float movement = std::abs(dv);
292
293 v += movement * vCoeff;
294 chroma += movement * chromaCoeff;
295 }
296
297 v = qBound(0.0f, v, 1.0f);
298 chroma = valuePolicy.fixupChroma(chroma, v);
299 }
300
301 if (v <= EPSILON) {
302 *r = *g = *b = 0.0;
303 } else {
304 h /= 60.0f;
305 const int sextant = static_cast<int>(h);
306 const float fract = h - sextant;
307
308 const float x =
309 sextant & 0x1 ?
310 chroma - chroma * fract :
311 chroma * fract;
312
313 valuePolicy.writeRGB(r, g, b, sextant, x, chroma, v);
314 }
315}
qreal v
#define EPSILON
T pow2(const T &x)
Definition kis_global.h:166
std::enable_if< std::is_floating_point< T >::value, T >::type normalizeAngleDegrees(T a)
Definition kis_global.h:132

References EPSILON, normalizeAngleDegrees(), pow2(), and v.

◆ writeRGBSimple()

static void writeRGBSimple ( float * r,
float * g,
float * b,
int sextant,
float x,
float m,
float M )
inlinestatic

Definition at line 68 of file kis_hsv_adjustment.cpp.

71{
72 switch (sextant) {
73 case 0: *r = M; *g = x + m; *b = m; break;
74 case 1: *r = x + m; *g = M; *b = m; break;
75 case 2: *r = m; *g = M; *b = x + m; break;
76 case 3: *r = m; *g = x + m; *b = M; break;
77 case 4: *r = x + m; *g = m; *b = M; break;
78 case 5: *r = M; *g = m; *b = x + m; break;
79 }
80}