husl.c
Go to the documentation of this file.
1 
2 #include "husl.h"
3 
4 #ifdef __cplusplus //libs if c++ is used
5 #include <cmath>
6 #include <cfloat>
7 #include <cstdio>
8 #include <cstring>
9 #include <cstdlib>
10 #else //libs if pure c is used
11 #include <math.h>
12 #include <float.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #endif
17 
18 float m[3][3] = {{3.2406f, -1.5372f, -0.4986f}, {-0.9689f, 1.8758f, 0.0415f}, {0.0557f, -0.2040f, 1.0570f}};
19 float m_inv[3][3] = {{0.4124f, 0.3576f, 0.1805f}, {0.2126f, 0.7152f, 0.0722f}, {0.0193f, 0.1192f, 0.9505f}};
20 float refX = 0.95047f;
21 float refY = 1.00000f;
22 float refZ = 1.08883f;
23 float refU = 0.19784f;
24 float refV = 0.46834f;
25 float lab_e = 0.008856f;
26 float lab_k = 903.3f;
27 
28 char hex[64];
29 float values[3];
30 
31 
32 float* XYZ_RGB(float *tuple);
33 float* RGB_XYZ(float *tuple);
34 float* XYZ_LUV(float *tuple);
35 float* LUV_XYZ(float *tuple);
36 float* LUV_LCH(float *tuple);
37 float* LCH_LUV(float *tuple);
38 float* HUSL_LCH(float *tuple);
39 float* LCH_HUSL(float *tuple);
40 
41 
42 float maxChroma(float L, float H);
43 float* rgbPrepare(float *tuple);
44 
45 float dotProduct(float* a, float * b, int len);
46 float round_(float num, int places);
47 float f(float t);
48 float f_inv(float t);
49 float fromLinear(float c);
50 float toLinear(float c);
51 
52 
54 
55 
56 void HUSLtoRGB( float *r, float *g, float *b, float h, float s,float l )
57 {
58  values[0] = h;
59  values[1] = s;
60  values[2] = l;
61 
63 
64  *r = values[0];
65  *g = values[1];
66  *b = values[2];
67 
68  return;
69 }
70 
71 void RGBtoHUSL( float *h, float *s,float *l, float r, float g, float b )
72 {
73  values[0] = r;
74  values[1] = g;
75  values[2] = b;
76 
78 
79  *h = values[0];
80  *s = values[1];
81  *l = values[2];
82 
83  return;
84 }
85 
86 
87 
88 
89 
90 
91 float maxChroma(float L, float H){
92 
93  float C, bottom, cosH, hrad, lbottom, m1, m2, m3, rbottom, result, sinH, sub1, sub2, t, top;
94  int _i, _j, _len, _len1;
95  float *row;
96  float _ref[2] = {0.0f, 1.0f};
97 
98 
99  hrad = (float) ((H / 360.0f) * 2 * M_PI);
100  sinH = (float) (sin(hrad));
101  cosH = (float) (cos(hrad));
102  sub1 = (float) (pow(L + 16, 3) / 1560896.0);
103  sub2 = sub1 > 0.008856 ? sub1 : (float) (L / 903.3);
104  result = FLT_MAX;
105  for (_i = 0, _len = 3; _i < _len; ++_i) {
106  row = m[_i];
107  m1 = row[0], m2 = row[1], m3 = row[2];
108  top = (float) ((0.99915 * m1 + 1.05122 * m2 + 1.14460 * m3) * sub2);
109  rbottom = (float) (0.86330 * m3 - 0.17266 * m2);
110  lbottom = (float) (0.12949 * m3 - 0.38848 * m1);
111  bottom = (rbottom * sinH + lbottom * cosH) * sub2;
112 
113  for (_j = 0, _len1 = 2; _j < _len1; ++_j) {
114  t = _ref[_j];
115  C = (float) (L * (top - 1.05122 * t) / (bottom + 0.17266 * sinH * t));
116  if ((C > 0 && C < result)) {
117  result = C;
118  }
119  }
120  }
121  return result;
122 }
123 
124 float dotProduct(float* a, float * b, int len){
125 
126  int i, _i, _ref;
127  float ret = 0.0f;
128  for (i = _i = 0, _ref = len - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
129  ret += a[i] * b[i];
130  }
131  return ret;
132 
133 }
134 
135 float round_( float num, int places )
136 {
137  float n;
138  n = (float) (pow(10.0f, places));
139  return (float) (floor(num * n) / n);
140 }
141 
142 float f( float t )
143 {
144  if (t > lab_e) {
145  return (float) (pow(t, 1.0f / 3.0f));
146  } else {
147  return (float) (7.787 * t + 16 / 116.0);
148  }
149 }
150 
151 float f_inv( float t )
152 {
153  if (pow(t, 3) > lab_e) {
154  return (float) (pow(t, 3));
155  } else {
156  return (116 * t - 16) / lab_k;
157  }
158 }
159 
160 float fromLinear( float c )
161 {
162  if (c <= 0.0031308) {
163  return 12.92f * c;
164  } else {
165  return (float) (1.055 * pow(c, 1 / 2.4f) - 0.055);
166  }
167 }
168 
169 float toLinear( float c )
170 {
171  float a = 0.055f;
172 
173  if (c > 0.04045) {
174  return (float) (pow((c + a) / (1 + a), 2.4f));
175  } else {
176  return (float) (c / 12.92);
177  }
178 }
179 
180 float* rgbPrepare( float *tuple )
181 {
182  int i;
183 
184  for(i = 0; i < 3; ++i){
185  tuple[i] = round_(tuple[i], 3);
186 
187  if (tuple[i] < 0 || tuple[i] > 1) {
188  if(tuple[i] < 0)
189  tuple[i] = 0;
190  else
191  tuple[i] = 1;
192  //printf("Illegal rgb value: %f\n", tuple[i]);
193  }
194 
195  tuple[i] = round_(tuple[i]*255, 0);
196  }
197 
198  return tuple;
199 }
200 
201 float* XYZ_RGB( float *tuple )
202 {
203  float B, G, R;
204  R = fromLinear(dotProduct(m[0], tuple, 3));
205  G = fromLinear(dotProduct(m[1], tuple, 3));
206  B = fromLinear(dotProduct(m[2], tuple, 3));
207 
208  tuple[0] = R;
209  tuple[1] = G;
210  tuple[2] = B;
211 
212  return tuple;
213 }
214 
215 float* RGB_XYZ( float *tuple )
216 {
217  float B, G, R, X, Y, Z;
218  float rgbl[3];
219 
220  R = tuple[0];
221  G = tuple[1];
222  B = tuple[2];
223 
224  rgbl[0] = toLinear(R);
225  rgbl[1] = toLinear(G);
226  rgbl[2] = toLinear(B);
227 
228  X = dotProduct(m_inv[0], rgbl, 3);
229  Y = dotProduct(m_inv[1], rgbl, 3);
230  Z = dotProduct(m_inv[2], rgbl, 3);
231 
232  tuple[0] = X;
233  tuple[1] = Y;
234  tuple[2] = Z;
235 
236  return tuple;
237 }
238 
239 float* XYZ_LUV( float *tuple )
240 {
241  float L, U, V, X, Y, Z, varU, varV;
242 
243  X = tuple[0];
244  Y = tuple[1];
245  Z = tuple[2];
246 
247  varU = (4 * X) / (X + (15.0f * Y) + (3 * Z));
248  varV = (9 * Y) / (X + (15.0f * Y) + (3 * Z));
249  L = 116 * f(Y / refY) - 16;
250  U = 13 * L * (varU - refU);
251  V = 13 * L * (varV - refV);
252 
253  tuple[0] = L;
254  tuple[1] = U;
255  tuple[2] = V;
256 
257  return tuple;
258 }
259 
260 float* LUV_XYZ( float *tuple )
261 {
262  float L, U, V, X, Y, Z, varU, varV, varY;
263 
264  L = tuple[0];
265  U = tuple[1];
266  V = tuple[2];
267 
268  if (L == 0) {
269  tuple[2] = tuple[1] = tuple[0] = 0.0f;
270  return tuple;
271  }
272 
273  varY = f_inv((L + 16) / 116.0f);
274  varU = U / (13.0f * L) + refU;
275  varV = V / (13.0f * L) + refV;
276  Y = varY * refY;
277  X = 0 - (9 * Y * varU) / ((varU - 4.0f) * varV - varU * varV);
278  Z = (9 * Y - (15 * varV * Y) - (varV * X)) / (3.0f * varV);
279 
280  tuple[0] = X;
281  tuple[1] = Y;
282  tuple[2] = Z;
283 
284  return tuple;
285 }
286 
287 float* LUV_LCH( float *tuple )
288 {
289  float C, H, Hrad, L, U, V;
290 
291  L = tuple[0];
292  U = tuple[1];
293  V = tuple[2];
294 
295  C = (float) (pow(pow(U, 2) + pow(V, 2), (1 / 2.0f)));
296  Hrad = (float) (atan2(V, U));
297  H = (float) (Hrad * 360.0f / 2.0f / M_PI);
298  if (H < 0) {
299  H = 360 + H;
300  }
301 
302  tuple[0] = L;
303  tuple[1] = C;
304  tuple[2] = H;
305 
306  return tuple;
307 }
308 
309 float* LCH_LUV( float *tuple )
310 {
311  float C, H, Hrad, L, U, V;
312 
313  L = tuple[0];
314  C = tuple[1];
315  H = tuple[2];
316 
317  Hrad = (float) (H / 360.0 * 2.0 * M_PI);
318  U = (float) (cos(Hrad) * C);
319  V = (float) (sin(Hrad) * C);
320 
321  tuple[0] = L;
322  tuple[1] = U;
323  tuple[2] = V;
324 
325  return tuple;
326 }
327 
328 float* HUSL_LCH( float *tuple )
329 {
330  float C, H, L, S, max;
331 
332  H = tuple[0];
333  S = tuple[1];
334  L = tuple[2];
335 
336  max = maxChroma(L, H);
337  C = max / 100.0f * S;
338 
339  tuple[0] = L;
340  tuple[1] = C;
341  tuple[2] = H;
342 
343  return tuple;
344 }
345 
346 float* LCH_HUSL( float *tuple )
347 {
348  float C, H, L, S, max;
349 
350  L = tuple[0];
351  C = tuple[1];
352  H = tuple[2];
353 
354  max = maxChroma(L, H);
355  S = C / max * 100;
356 
357  tuple[0] = H;
358  tuple[1] = S;
359  tuple[2] = L;
360 
361  return tuple;
362 }
363 
364 
365 
366 
367 
368 
float maxChroma(float L, float H)
Definition: husl.c:91
float f_inv(float t)
Definition: husl.c:151
float refU
Definition: husl.c:23
float dotProduct(float *a, float *b, int len)
Definition: husl.c:124
float * LCH_LUV(float *tuple)
Definition: husl.c:309
float * LCH_HUSL(float *tuple)
Definition: husl.c:346
char hex[64]
Definition: husl.c:28
float lab_k
Definition: husl.c:26
float refY
Definition: husl.c:21
float * HUSL_LCH(float *tuple)
Definition: husl.c:328
float f(float t)
Definition: husl.c:142
void HUSLtoRGB(float *r, float *g, float *b, float h, float s, float l)
Definition: husl.c:56
float toLinear(float c)
Definition: husl.c:169
float * LUV_XYZ(float *tuple)
Definition: husl.c:260
float lab_e
Definition: husl.c:25
float refX
Definition: husl.c:20
float * XYZ_LUV(float *tuple)
Definition: husl.c:239
float * rgbPrepare(float *tuple)
Definition: husl.c:180
void RGBtoHUSL(float *h, float *s, float *l, float r, float g, float b)
Definition: husl.c:71
float * RGB_XYZ(float *tuple)
Definition: husl.c:215
string b
Definition: busy_node.py:4
float m_inv[3][3]
Definition: husl.c:19
float round_(float num, int places)
Definition: husl.c:135
float m[3][3]
Definition: husl.c:18
float * LUV_LCH(float *tuple)
Definition: husl.c:287
float refV
Definition: husl.c:24
float refZ
Definition: husl.c:22
float fromLinear(float c)
Definition: husl.c:160
float * XYZ_RGB(float *tuple)
Definition: husl.c:201
float values[3]
Definition: husl.c:29


rosmon_core
Author(s): Max Schwarz
autogenerated on Wed Jul 10 2019 03:10:12