diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2014-03-12 20:58:50 +0400 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2014-03-12 20:58:50 +0400 |
commit | bce924b43c4c5ff46eec7b340b68f37ae8e15215 (patch) | |
tree | af0d8bec8f0c2711fb8a3ebd3e6b82c5220f76ec /source/blender/blenlib/intern/math_color.c | |
parent | 35ed7486c76f11b397d0ff131160f8629af3b49b (diff) |
HSL color wheel implementation.
This is a standard Hue - Saturation - Lightness model
(see for instance entry on wikipedia here: https://en.wikipedia.org/wiki/HSL_and_HSV)
Note though the difference between HSV and HSL saturation, which are not the same.
The advantage of having this color selection scheme is that artists can select
shades and tints of a color easily by using the lightness slider. Also colors
are arranged on (approximated) perceived lightness on the color wheel.
Beware, Old files opened with this preference saved will crash!
Reviewers: sergey, brecht, campbellbarton
Differential Revision: https://developer.blender.org/D385
Diffstat (limited to 'source/blender/blenlib/intern/math_color.c')
-rw-r--r-- | source/blender/blenlib/intern/math_color.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 51980ad36cb..43f6d4c29ae 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -94,12 +94,71 @@ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b) } } +/* HSL to rgb conversion from https://en.wikipedia.org/wiki/HSL_and_HSV */ +void hsl_to_rgb(float h, float s, float l, float *r, float *g, float *b) +{ + float i, f, c; + h = (h - floorf(h)) * 6.0f; + c = (l > 0.5f) ? (2.0f * (1.0f - l) * s) : (2.0f * l * s); + i = floorf(h); + f = h - i; + +#define x2 (c * f) +#define x1 (c * (1.0f - f)) + + /* faster to compare floats then int conversion */ + if (i < 1.0f) { + *r = c; + *g = x2; + *b = 0; + } + else if (i < 2.0f) { + *r = x1; + *g = c; + *b = 0; + } + else if (i < 3.0f) { + *r = 0; + *g = c; + *b = x2; + } + else if (i < 4.0f) { + *r = 0; + *g = x1; + *b = c; + } + else if (i < 5.0f) { + *r = x2; + *g = 0; + *b = c; + } + else { + *r = c; + *g = 0; + *b = x1; + } + +#undef x1 +#undef x2 + + f = l - 0.5f * c; + *r += f; + *g += f; + *b += f; +} + /* convenience function for now */ void hsv_to_rgb_v(const float hsv[3], float r_rgb[3]) { hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]); } +/* convenience function for now */ +void hsl_to_rgb_v(const float hcl[3], float r_rgb[3]) +{ + hsl_to_rgb(hcl[0], hcl[1], hcl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]); +} + void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv) { float y, u, v; @@ -315,6 +374,33 @@ void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll) *ll = l; } +void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll) +{ + float orig_s = *ls; + float orig_h = *lh; + + rgb_to_hsl(r, g, b, lh, ls, ll); + + if (*ll <= 0.0f) { + *lh = orig_h; + *ls = orig_s; + } + else if (*ls <= 0.0f) { + *lh = orig_h; + *ls = orig_s; + } + + if (*lh == 0.0f && orig_h >= 1.0f) { + *lh = 1.0f; + } +} + +void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3]) +{ + rgb_to_hsl_compat(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]); +} + + /* convenience function for now */ void rgb_to_hsl_v(const float rgb[3], float r_hsl[3]) { |