1 //  ---------------------------------------------------------------------------
2 //
3 //  @file       TwColors.cpp
4 //  @author     Philippe Decaudin
5 //  @license    This file is part of the AntTweakBar library.
6 //              For conditions of distribution and use, see License.txt
7 //
8 //  ---------------------------------------------------------------------------
9 
10 
11 #include "TwPrecomp.h"
12 #include "TwColors.h"
13 
14 
ColorRGBToHLSf(float _R,float _G,float _B,float * _Hue,float * _Light,float * _Saturation)15 void ColorRGBToHLSf(float _R, float _G, float _B, float *_Hue, float *_Light, float *_Saturation)
16 {
17     // Compute HLS from RGB. The r,g,b triplet is between [0,1],
18     // hue is between [0,360], light and saturation are [0,1].
19 
20     float rnorm, gnorm, bnorm, minval, maxval, msum, mdiff, r, g, b;
21     r = g = b = 0;
22     if(_R>0) r = _R; if(r>1) r = 1;
23     if(_G>0) g = _G; if(g>1) g = 1;
24     if(_B>0) b = _B; if(b>1) b = 1;
25 
26     minval = r;
27     if(g<minval) minval = g;
28     if(b<minval) minval = b;
29     maxval = r;
30     if(g>maxval) maxval = g;
31     if(b>maxval) maxval = b;
32 
33     rnorm = gnorm = bnorm = 0;
34     mdiff = maxval - minval;
35     msum  = maxval + minval;
36     float l = 0.5f * msum;
37     if(_Light)
38         *_Light = l;
39     if(maxval!=minval)
40     {
41         rnorm = (maxval - r)/mdiff;
42         gnorm = (maxval - g)/mdiff;
43         bnorm = (maxval - b)/mdiff;
44     }
45     else
46     {
47         if(_Saturation)
48             *_Saturation = 0;
49         if(_Hue)
50             *_Hue = 0;
51         return;
52     }
53 
54     if(_Saturation)
55     {
56         if(l<0.5f)
57             *_Saturation = mdiff/msum;
58         else
59             *_Saturation = mdiff/(2.0f - msum);
60     }
61 
62     if(_Hue)
63     {
64         if(r==maxval)
65             *_Hue = 60.0f * (6.0f + bnorm - gnorm);
66         else if(g==maxval)
67             *_Hue = 60.0f * (2.0f + rnorm - bnorm);
68         else
69             *_Hue = 60.0f * (4.0f + gnorm - rnorm);
70 
71         if(*_Hue>360.0f)
72             *_Hue -= 360.0f;
73     }
74 }
75 
76 
ColorRGBToHLSi(int _R,int _G,int _B,int * _Hue,int * _Light,int * _Saturation)77 void ColorRGBToHLSi(int _R, int _G, int _B, int *_Hue, int *_Light, int *_Saturation)
78 {
79     float h, l, s;
80     ColorRGBToHLSf((1.0f/255.0f)*float(_R), (1.0f/255.0f)*float(_G), (1.0f/255.0f)*float(_B), &h, &l, &s);
81     if(_Hue)        *_Hue       = (int)TClamp(h*(256.0f/360.0f), 0.0f, 255.0f);
82     if(_Light)      *_Light     = (int)TClamp(l*256.0f, 0.0f, 255.0f);
83     if(_Saturation) *_Saturation= (int)TClamp(s*256.0f, 0.0f, 255.0f);
84 }
85 
86 
ColorHLSToRGBf(float _Hue,float _Light,float _Saturation,float * _R,float * _G,float * _B)87 void ColorHLSToRGBf(float _Hue, float _Light, float _Saturation, float *_R, float *_G, float *_B)
88 {
89     // Compute RGB from HLS. The light and saturation are between [0,1]
90     // and hue is between [0,360]. The returned r,g,b triplet is between [0,1].
91 
92     // a local auxiliary function
93     struct CLocal
94     {
95         static float HLSToRGB(float _Rn1, float _Rn2, float _Huei)
96         {
97             float hue = _Huei;
98             if(hue>360) hue = hue - 360;
99             if(hue<0)   hue = hue + 360;
100             if(hue<60 ) return _Rn1 + (_Rn2-_Rn1)*hue/60;
101             if(hue<180) return _Rn2;
102             if(hue<240) return _Rn1 + (_Rn2-_Rn1)*(240-hue)/60;
103             return _Rn1;
104         }
105     };
106 
107     float rh, rl, rs, rm1, rm2;
108     rh = rl = rs = 0;
109     if(_Hue>0)        rh = _Hue;        if(rh>360) rh = 360;
110     if(_Light>0)      rl = _Light;      if(rl>1)   rl = 1;
111     if(_Saturation>0) rs = _Saturation; if(rs>1)   rs = 1;
112 
113     if(rl<=0.5f)
114         rm2 = rl*(1.0f + rs);
115     else
116         rm2 = rl + rs - rl*rs;
117     rm1 = 2.0f*rl - rm2;
118 
119     if(!rs)
120     {
121         if(_R) *_R = rl;
122         if(_G) *_G = rl;
123         if(_B) *_B = rl;
124     }
125     else
126     {
127         if(_R) *_R = CLocal::HLSToRGB(rm1, rm2, rh+120);
128         if(_G) *_G = CLocal::HLSToRGB(rm1, rm2, rh);
129         if(_B) *_B = CLocal::HLSToRGB(rm1, rm2, rh-120);
130     }
131 }
132 
133 
ColorHLSToRGBi(int _Hue,int _Light,int _Saturation,int * _R,int * _G,int * _B)134 void ColorHLSToRGBi(int _Hue, int _Light, int _Saturation, int *_R, int *_G, int *_B)
135 {
136     float r, g, b;
137     ColorHLSToRGBf((360.0f/255.0f)*float(_Hue), (1.0f/255.0f)*float(_Light), (1.0f/255.0f)*float(_Saturation), &r, &g, &b);
138     if(_R) *_R = (int)TClamp(r*256.0f, 0.0f, 255.0f);
139     if(_G) *_G = (int)TClamp(g*256.0f, 0.0f, 255.0f);
140     if(_B) *_B = (int)TClamp(b*256.0f, 0.0f, 255.0f);
141 }
142 
143 
ColorBlend(color32 _Color1,color32 _Color2,float _S)144 color32 ColorBlend(color32 _Color1, color32 _Color2, float _S)
145 {
146     float a1, r1, g1, b1, a2, r2, g2, b2;
147     Color32ToARGBf(_Color1, &a1, &r1, &g1, &b1);
148     Color32ToARGBf(_Color2, &a2, &r2, &g2, &b2);
149     float t = 1.0f-_S;
150     return Color32FromARGBf(t*a1+_S*a2, t*r1+_S*r2, t*g1+_S*g2, t*b1+_S*b2);
151 }
152 
153 
154