Blender  V2.93
math_color.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  *
19  * The Original Code is: some of this file.
20  */
21 
26 #include "BLI_math.h"
27 #include "BLI_utildefines.h"
28 
29 #include "BLI_strict_flags.h"
30 
31 void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b)
32 {
33  float nr, ng, nb;
34 
35  nr = fabsf(h * 6.0f - 3.0f) - 1.0f;
36  ng = 2.0f - fabsf(h * 6.0f - 2.0f);
37  nb = 2.0f - fabsf(h * 6.0f - 4.0f);
38 
39  CLAMP(nr, 0.0f, 1.0f);
40  CLAMP(nb, 0.0f, 1.0f);
41  CLAMP(ng, 0.0f, 1.0f);
42 
43  *r_r = ((nr - 1.0f) * s + 1.0f) * v;
44  *r_g = ((ng - 1.0f) * s + 1.0f) * v;
45  *r_b = ((nb - 1.0f) * s + 1.0f) * v;
46 }
47 
48 void hsl_to_rgb(float h, float s, float l, float *r_r, float *r_g, float *r_b)
49 {
50  float nr, ng, nb, chroma;
51 
52  nr = fabsf(h * 6.0f - 3.0f) - 1.0f;
53  ng = 2.0f - fabsf(h * 6.0f - 2.0f);
54  nb = 2.0f - fabsf(h * 6.0f - 4.0f);
55 
56  CLAMP(nr, 0.0f, 1.0f);
57  CLAMP(nb, 0.0f, 1.0f);
58  CLAMP(ng, 0.0f, 1.0f);
59 
60  chroma = (1.0f - fabsf(2.0f * l - 1.0f)) * s;
61 
62  *r_r = (nr - 0.5f) * chroma + l;
63  *r_g = (ng - 0.5f) * chroma + l;
64  *r_b = (nb - 0.5f) * chroma + l;
65 }
66 
67 /* convenience function for now */
68 void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
69 {
70  hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
71 }
72 
73 /* convenience function for now */
74 void hsl_to_rgb_v(const float hsl[3], float r_rgb[3])
75 {
76  hsl_to_rgb(hsl[0], hsl[1], hsl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
77 }
78 
79 void rgb_to_yuv(float r, float g, float b, float *r_y, float *r_u, float *r_v, int colorspace)
80 {
81  float y, u, v;
82 
83  switch (colorspace) {
84  case BLI_YUV_ITU_BT601:
85  y = 0.299f * r + 0.587f * g + 0.114f * b;
86  u = -0.147f * r - 0.289f * g + 0.436f * b;
87  v = 0.615f * r - 0.515f * g - 0.100f * b;
88  break;
89  case BLI_YUV_ITU_BT709:
90  default:
91  BLI_assert(colorspace == BLI_YUV_ITU_BT709);
92  y = 0.2126f * r + 0.7152f * g + 0.0722f * b;
93  u = -0.09991f * r - 0.33609f * g + 0.436f * b;
94  v = 0.615f * r - 0.55861f * g - 0.05639f * b;
95  break;
96  }
97 
98  *r_y = y;
99  *r_u = u;
100  *r_v = v;
101 }
102 
103 void yuv_to_rgb(float y, float u, float v, float *r_r, float *r_g, float *r_b, int colorspace)
104 {
105  float r, g, b;
106 
107  switch (colorspace) {
108  case BLI_YUV_ITU_BT601:
109  r = y + 1.140f * v;
110  g = y - 0.394f * u - 0.581f * v;
111  b = y + 2.032f * u;
112  break;
113  case BLI_YUV_ITU_BT709:
114  default:
115  BLI_assert(colorspace == BLI_YUV_ITU_BT709);
116  r = y + 1.28033f * v;
117  g = y - 0.21482f * u - 0.38059f * v;
118  b = y + 2.12798f * u;
119  break;
120  }
121 
122  *r_r = r;
123  *r_g = g;
124  *r_b = b;
125 }
126 
127 /* The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f
128  *
129  * Output YCC have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */
130 void rgb_to_ycc(float r, float g, float b, float *r_y, float *r_cb, float *r_cr, int colorspace)
131 {
132  float sr, sg, sb;
133  float y = 128.0f, cr = 128.0f, cb = 128.0f;
134 
135  sr = 255.0f * r;
136  sg = 255.0f * g;
137  sb = 255.0f * b;
138 
139  switch (colorspace) {
140  case BLI_YCC_ITU_BT601:
141  y = (0.257f * sr) + (0.504f * sg) + (0.098f * sb) + 16.0f;
142  cb = (-0.148f * sr) - (0.291f * sg) + (0.439f * sb) + 128.0f;
143  cr = (0.439f * sr) - (0.368f * sg) - (0.071f * sb) + 128.0f;
144  break;
145  case BLI_YCC_ITU_BT709:
146  y = (0.183f * sr) + (0.614f * sg) + (0.062f * sb) + 16.0f;
147  cb = (-0.101f * sr) - (0.338f * sg) + (0.439f * sb) + 128.0f;
148  cr = (0.439f * sr) - (0.399f * sg) - (0.040f * sb) + 128.0f;
149  break;
150  case BLI_YCC_JFIF_0_255:
151  y = (0.299f * sr) + (0.587f * sg) + (0.114f * sb);
152  cb = (-0.16874f * sr) - (0.33126f * sg) + (0.5f * sb) + 128.0f;
153  cr = (0.5f * sr) - (0.41869f * sg) - (0.08131f * sb) + 128.0f;
154  break;
155  default:
156  BLI_assert(!"invalid colorspace");
157  break;
158  }
159 
160  *r_y = y;
161  *r_cb = cb;
162  *r_cr = cr;
163 }
164 
165 /* YCC input have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */
166 /* RGB outputs are in the range 0 - 1.0f */
167 
168 /* FIXME comment above must be wrong because BLI_YCC_ITU_BT601 y 16.0 cr 16.0 -> r -0.7009 */
169 void ycc_to_rgb(float y, float cb, float cr, float *r_r, float *r_g, float *r_b, int colorspace)
170 {
171  float r = 128.0f, g = 128.0f, b = 128.0f;
172 
173  switch (colorspace) {
174  case BLI_YCC_ITU_BT601:
175  r = 1.164f * (y - 16.0f) + 1.596f * (cr - 128.0f);
176  g = 1.164f * (y - 16.0f) - 0.813f * (cr - 128.0f) - 0.392f * (cb - 128.0f);
177  b = 1.164f * (y - 16.0f) + 2.017f * (cb - 128.0f);
178  break;
179  case BLI_YCC_ITU_BT709:
180  r = 1.164f * (y - 16.0f) + 1.793f * (cr - 128.0f);
181  g = 1.164f * (y - 16.0f) - 0.534f * (cr - 128.0f) - 0.213f * (cb - 128.0f);
182  b = 1.164f * (y - 16.0f) + 2.115f * (cb - 128.0f);
183  break;
184  case BLI_YCC_JFIF_0_255:
185  r = y + 1.402f * cr - 179.456f;
186  g = y - 0.34414f * cb - 0.71414f * cr + 135.45984f;
187  b = y + 1.772f * cb - 226.816f;
188  break;
189  default:
190  BLI_assert(0);
191  break;
192  }
193  *r_r = r / 255.0f;
194  *r_g = g / 255.0f;
195  *r_b = b / 255.0f;
196 }
197 
198 void hex_to_rgb(const char *hexcol, float *r_r, float *r_g, float *r_b)
199 {
200  unsigned int ri, gi, bi;
201 
202  if (hexcol[0] == '#') {
203  hexcol++;
204  }
205 
206  if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi) == 3) {
207  /* six digit hex colors */
208  }
209  else if (sscanf(hexcol, "%01x%01x%01x", &ri, &gi, &bi) == 3) {
210  /* three digit hex colors (#123 becomes #112233) */
211  ri += ri << 4;
212  gi += gi << 4;
213  bi += bi << 4;
214  }
215  else {
216  /* avoid using un-initialized vars */
217  *r_r = *r_g = *r_b = 0.0f;
218  return;
219  }
220 
221  *r_r = (float)ri * (1.0f / 255.0f);
222  *r_g = (float)gi * (1.0f / 255.0f);
223  *r_b = (float)bi * (1.0f / 255.0f);
224  CLAMP(*r_r, 0.0f, 1.0f);
225  CLAMP(*r_g, 0.0f, 1.0f);
226  CLAMP(*r_b, 0.0f, 1.0f);
227 }
228 
229 void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
230 {
231  float k = 0.0f;
232  float chroma;
233  float min_gb;
234 
235  if (g < b) {
236  SWAP(float, g, b);
237  k = -1.0f;
238  }
239  min_gb = b;
240  if (r < g) {
241  SWAP(float, r, g);
242  k = -2.0f / 6.0f - k;
243  min_gb = min_ff(g, b);
244  }
245 
246  chroma = r - min_gb;
247 
248  *r_h = fabsf(k + (g - b) / (6.0f * chroma + 1e-20f));
249  *r_s = chroma / (r + 1e-20f);
250  *r_v = r;
251 }
252 
253 /* convenience function for now */
254 void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
255 {
256  rgb_to_hsv(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]);
257 }
258 
259 void rgb_to_hsl(float r, float g, float b, float *r_h, float *r_s, float *r_l)
260 {
261  const float cmax = max_fff(r, g, b);
262  const float cmin = min_fff(r, g, b);
263  float h, s, l = min_ff(1.0, (cmax + cmin) / 2.0f);
264 
265  if (cmax == cmin) {
266  h = s = 0.0f; /* achromatic */
267  }
268  else {
269  float d = cmax - cmin;
270  s = l > 0.5f ? d / (2.0f - cmax - cmin) : d / (cmax + cmin);
271  if (cmax == r) {
272  h = (g - b) / d + (g < b ? 6.0f : 0.0f);
273  }
274  else if (cmax == g) {
275  h = (b - r) / d + 2.0f;
276  }
277  else {
278  h = (r - g) / d + 4.0f;
279  }
280  }
281  h /= 6.0f;
282 
283  *r_h = h;
284  *r_s = s;
285  *r_l = l;
286 }
287 
288 void rgb_to_hsl_compat(float r, float g, float b, float *r_h, float *r_s, float *r_l)
289 {
290  const float orig_s = *r_s;
291  const float orig_h = *r_h;
292 
293  rgb_to_hsl(r, g, b, r_h, r_s, r_l);
294 
295  if (*r_l <= 0.0f) {
296  *r_h = orig_h;
297  *r_s = orig_s;
298  }
299  else if (*r_s <= 0.0f) {
300  *r_h = orig_h;
301  *r_s = orig_s;
302  }
303 
304  if (*r_h == 0.0f && orig_h >= 1.0f) {
305  *r_h = 1.0f;
306  }
307 }
308 
309 void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3])
310 {
311  rgb_to_hsl_compat(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]);
312 }
313 
314 /* convenience function for now */
315 void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
316 {
317  rgb_to_hsl(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]);
318 }
319 
320 void rgb_to_hsv_compat(float r, float g, float b, float *r_h, float *r_s, float *r_v)
321 {
322  const float orig_h = *r_h;
323  const float orig_s = *r_s;
324 
325  rgb_to_hsv(r, g, b, r_h, r_s, r_v);
326 
327  if (*r_v <= 1e-8) {
328  /* Very low v values will affect the hs values, correct them in post. */
329  *r_h = orig_h;
330  *r_s = orig_s;
331  }
332  else if (*r_s <= 1e-8) {
333  *r_h = orig_h;
334  }
335 
336  if (*r_h == 0.0f && orig_h >= 1.0f) {
337  *r_h = 1.0f;
338  }
339 }
340 
341 /* convenience function for now */
342 void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3])
343 {
344  rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]);
345 }
346 
347 /* clamp hsv to usable values */
348 void hsv_clamp_v(float hsv[3], float v_max)
349 {
350  if (UNLIKELY(hsv[0] < 0.0f || hsv[0] > 1.0f)) {
351  hsv[0] = hsv[0] - floorf(hsv[0]);
352  }
353  CLAMP(hsv[1], 0.0f, 1.0f);
354  CLAMP(hsv[2], 0.0f, v_max);
355 }
356 
363 unsigned int hsv_to_cpack(float h, float s, float v)
364 {
365  unsigned int r, g, b;
366  float rf, gf, bf;
367  unsigned int col;
368 
369  hsv_to_rgb(h, s, v, &rf, &gf, &bf);
370 
371  r = (unsigned int)(rf * 255.0f);
372  g = (unsigned int)(gf * 255.0f);
373  b = (unsigned int)(bf * 255.0f);
374 
375  col = (r + (g * 256) + (b * 256 * 256));
376  return col;
377 }
378 
379 unsigned int rgb_to_cpack(float r, float g, float b)
380 {
381  unsigned int ir, ig, ib;
382 
383  ir = (unsigned int)floorf(255.0f * max_ff(r, 0.0f));
384  ig = (unsigned int)floorf(255.0f * max_ff(g, 0.0f));
385  ib = (unsigned int)floorf(255.0f * max_ff(b, 0.0f));
386 
387  if (ir > 255) {
388  ir = 255;
389  }
390  if (ig > 255) {
391  ig = 255;
392  }
393  if (ib > 255) {
394  ib = 255;
395  }
396 
397  return (ir + (ig * 256) + (ib * 256 * 256));
398 }
399 
400 void cpack_to_rgb(unsigned int col, float *r_r, float *r_g, float *r_b)
401 {
402  *r_r = ((float)(((col)) & 0xFF)) * (1.0f / 255.0f);
403  *r_g = ((float)(((col) >> 8) & 0xFF)) * (1.0f / 255.0f);
404  *r_b = ((float)(((col) >> 16) & 0xFF)) * (1.0f / 255.0f);
405 }
406 
407 void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
408 {
409  r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
410  r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
411  r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
412 }
413 
414 void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
415 {
416  r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
417  r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
418  r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
419  r_col[3] = ((float)col_ub[3]) * (1.0f / 255.0f);
420 }
421 
422 void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
423 {
424  unit_float_to_uchar_clamp_v3(r_col, col_f);
425 }
426 
427 void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
428 {
429  unit_float_to_uchar_clamp_v4(r_col, col_f);
430 }
431 
432 /* ********************************* color transforms ********************************* */
433 
434 float srgb_to_linearrgb(float c)
435 {
436  if (c < 0.04045f) {
437  return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f);
438  }
439 
440  return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
441 }
442 
443 float linearrgb_to_srgb(float c)
444 {
445  if (c < 0.0031308f) {
446  return (c < 0.0f) ? 0.0f : c * 12.92f;
447  }
448 
449  return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
450 }
451 
452 void minmax_rgb(short c[3])
453 {
454  if (c[0] > 255) {
455  c[0] = 255;
456  }
457  else if (c[0] < 0) {
458  c[0] = 0;
459  }
460 
461  if (c[1] > 255) {
462  c[1] = 255;
463  }
464  else if (c[1] < 0) {
465  c[1] = 0;
466  }
467 
468  if (c[2] > 255) {
469  c[2] = 255;
470  }
471  else if (c[2] < 0) {
472  c[2] = 0;
473  }
474 }
475 
476 /* If the requested RGB shade contains a negative weight for
477  * one of the primaries, it lies outside the color gamut
478  * accessible from the given triple of primaries. Desaturate
479  * it by adding white, equal quantities of R, G, and B, enough
480  * to make RGB all positive. The function returns 1 if the
481  * components were modified, zero otherwise.*/
482 int constrain_rgb(float *r, float *g, float *b)
483 {
484  /* Amount of white needed */
485  const float w = -min_ffff(0.0f, *r, *g, *b);
486 
487  /* Add just enough white to make r, g, b all positive. */
488  if (w > 0.0f) {
489  *r += w;
490  *g += w;
491  *b += w;
492 
493  return 1; /* Color modified to fit RGB gamut */
494  }
495 
496  return 0; /* Color within RGB gamut */
497 }
498 
499 /* ********************** lift/gamma/gain / ASC-CDL conversion ********************************* */
500 
501 void lift_gamma_gain_to_asc_cdl(const float *lift,
502  const float *gamma,
503  const float *gain,
504  float *offset,
505  float *slope,
506  float *power)
507 {
508  int c;
509  for (c = 0; c < 3; c++) {
510  offset[c] = lift[c] * gain[c];
511  slope[c] = gain[c] * (1.0f - lift[c]);
512  if (gamma[c] == 0) {
513  power[c] = FLT_MAX;
514  }
515  else {
516  power[c] = 1.0f / gamma[c];
517  }
518  }
519 }
520 
521 /* ************************************* other ************************************************* */
522 
523 /* Applies an hue offset to a float rgb color */
524 void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset)
525 {
526  float hsv[3];
527 
528  rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2);
529 
530  hsv[0] += hue_offset;
531  if (hsv[0] > 1.0f) {
532  hsv[0] -= 1.0f;
533  }
534  else if (hsv[0] < 0.0f) {
535  hsv[0] += 1.0f;
536  }
537 
538  hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
539 }
540 
541 /* Applies an hue offset to a byte rgb color */
542 void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset)
543 {
544  float rgb_float[3];
545 
546  rgb_uchar_to_float(rgb_float, rgb);
547  rgb_float_set_hue_float_offset(rgb_float, hue_offset);
548  rgb_float_to_uchar(rgb, rgb_float);
549 }
550 
551 /* fast sRGB conversion
552  * LUT from linear float to 16-bit short
553  * based on http://mysite.verizon.net/spitzak/conversion/
554  */
555 
557 unsigned short BLI_color_to_srgb_table[0x10000];
558 
559 static unsigned short hipart(const float f)
560 {
561  union {
562  float f;
563  unsigned short us[2];
564  } tmp;
565 
566  tmp.f = f;
567 
568 #ifdef __BIG_ENDIAN__
569  return tmp.us[0];
570 #else
571  return tmp.us[1];
572 #endif
573 }
574 
575 static float index_to_float(const unsigned short i)
576 {
577 
578  union {
579  float f;
580  unsigned short us[2];
581  } tmp;
582 
583  /* positive and negative zeros, and all gradual underflow, turn into zero: */
584  if (i < 0x80 || (i >= 0x8000 && i < 0x8080)) {
585  return 0;
586  }
587  /* All NaN's and infinity turn into the largest possible legal float: */
588  if (i >= 0x7f80 && i < 0x8000) {
589  return FLT_MAX;
590  }
591  if (i >= 0xff80) {
592  return -FLT_MAX;
593  }
594 
595 #ifdef __BIG_ENDIAN__
596  tmp.us[0] = i;
597  tmp.us[1] = 0x8000;
598 #else
599  tmp.us[0] = 0x8000;
600  tmp.us[1] = i;
601 #endif
602 
603  return tmp.f;
604 }
605 
607 {
608  static bool initialized = false;
609  unsigned int i, b;
610 
611  if (initialized) {
612  return;
613  }
614  initialized = true;
615 
616  /* Fill in the lookup table to convert floats to bytes: */
617  for (i = 0; i < 0x10000; i++) {
618  float f = linearrgb_to_srgb(index_to_float((unsigned short)i)) * 255.0f;
619  if (f <= 0) {
621  }
622  else if (f < 255) {
623  BLI_color_to_srgb_table[i] = (unsigned short)(f * 0x100 + 0.5f);
624  }
625  else {
626  BLI_color_to_srgb_table[i] = 0xff00;
627  }
628  }
629 
630  /* Fill in the lookup table to convert bytes to float: */
631  for (b = 0; b <= 255; b++) {
632  float f = srgb_to_linearrgb(((float)b) * (1.0f / 255.0f));
634  i = hipart(f);
635  /* replace entries so byte->float->byte does not change the data: */
636  BLI_color_to_srgb_table[i] = (unsigned short)(b * 0x100);
637  }
638 }
639 
640 /* ****************************** blackbody ******************************** */
641 
642 /* Calculate color in range 800..12000 using an approximation
643  * a/x+bx+c for R and G and ((at + b)t + c)t + d) for B
644  * Max absolute error for RGB is (0.00095, 0.00077, 0.00057),
645  * which is enough to get the same 8 bit/channel color.
646  */
647 
648 static const float blackbody_table_r[6][3] = {
649  {2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f},
650  {3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f},
651  {4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f},
652  {4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f},
653  {4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f},
654  {3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f},
655 };
656 
657 static const float blackbody_table_g[6][3] = {
658  {-7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f},
659  {-1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f},
660  {-1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f},
661  {-1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f},
662  {-1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f},
663  {-5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f},
664 };
665 
666 static const float blackbody_table_b[6][4] = {
667  {0.0f, 0.0f, 0.0f, 0.0f},
668  {0.0f, 0.0f, 0.0f, 0.0f},
669  {0.0f, 0.0f, 0.0f, 0.0f},
670  {-2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f},
671  {-2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f},
672  {6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f},
673 };
674 
675 static void blackbody_temperature_to_rgb(float rgb[3], float t)
676 {
677  if (t >= 12000.0f) {
678  rgb[0] = 0.826270103f;
679  rgb[1] = 0.994478524f;
680  rgb[2] = 1.56626022f;
681  }
682  else if (t < 965.0f) {
683  rgb[0] = 4.70366907f;
684  rgb[1] = 0.0f;
685  rgb[2] = 0.0f;
686  }
687  else {
688  int i = (t >= 6365.0f) ?
689  5 :
690  (t >= 3315.0f) ? 4 :
691  (t >= 1902.0f) ? 3 : (t >= 1449.0f) ? 2 : (t >= 1167.0f) ? 1 : 0;
692 
693  const float *r = blackbody_table_r[i];
694  const float *g = blackbody_table_g[i];
695  const float *b = blackbody_table_b[i];
696 
697  const float t_inv = 1.0f / t;
698  rgb[0] = r[0] * t_inv + r[1] * t + r[2];
699  rgb[1] = g[0] * t_inv + g[1] * t + g[2];
700  rgb[2] = ((b[0] * t + b[1]) * t + b[2]) * t + b[3];
701  }
702 }
703 
704 void blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max)
705 {
706  for (int i = 0; i < width; i++) {
707  float temperature = min + (max - min) / (float)width * (float)i;
708 
709  float rgb[3];
710  blackbody_temperature_to_rgb(rgb, temperature);
711 
712  copy_v3_v3(&r_table[i * 4], rgb);
713  r_table[i * 4 + 3] = 0.0f;
714  }
715 }
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
MINLINE float min_ffff(float a, float b, float c, float d)
MINLINE float min_ff(float a, float b)
MINLINE float min_fff(float a, float b, float c)
#define BLI_YUV_ITU_BT709
#define BLI_YCC_JFIF_0_255
#define BLI_YCC_ITU_BT601
#define BLI_YUV_ITU_BT601
#define BLI_YCC_ITU_BT709
MINLINE void copy_v3_v3(float r[3], const float a[3])
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
#define SWAP(type, a, b)
#define UNLIKELY(x)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Group RGB to Bright Vector Camera CLAMP
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
uint col
static bool initialized
Definition: gpu_init_exit.c:41
#define powf(x, y)
#define floorf(x)
#define fabsf(x)
#define unit_float_to_uchar_clamp_v4(v1, v2)
#define unit_float_to_uchar_clamp_v3(v1, v2)
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
Definition: math_color.c:68
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
Definition: math_color.c:254
static void blackbody_temperature_to_rgb(float rgb[3], float t)
Definition: math_color.c:675
void rgb_to_hsl(float r, float g, float b, float *r_h, float *r_s, float *r_l)
Definition: math_color.c:259
static const float blackbody_table_g[6][3]
Definition: math_color.c:657
void rgb_to_hsl_compat(float r, float g, float b, float *r_h, float *r_s, float *r_l)
Definition: math_color.c:288
void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3])
Definition: math_color.c:342
static const float blackbody_table_b[6][4]
Definition: math_color.c:666
unsigned int rgb_to_cpack(float r, float g, float b)
Definition: math_color.c:379
unsigned short BLI_color_to_srgb_table[0x10000]
Definition: math_color.c:557
int constrain_rgb(float *r, float *g, float *b)
Definition: math_color.c:482
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
Definition: math_color.c:229
unsigned int hsv_to_cpack(float h, float s, float v)
Definition: math_color.c:363
void hsl_to_rgb_v(const float hsl[3], float r_rgb[3])
Definition: math_color.c:74
void BLI_init_srgb_conversion(void)
Definition: math_color.c:606
void ycc_to_rgb(float y, float cb, float cr, float *r_r, float *r_g, float *r_b, int colorspace)
Definition: math_color.c:169
void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b)
Definition: math_color.c:31
void minmax_rgb(short c[3])
Definition: math_color.c:452
void rgb_to_ycc(float r, float g, float b, float *r_y, float *r_cb, float *r_cr, int colorspace)
Definition: math_color.c:130
static const float blackbody_table_r[6][3]
Definition: math_color.c:648
void rgb_to_yuv(float r, float g, float b, float *r_y, float *r_u, float *r_v, int colorspace)
Definition: math_color.c:79
void rgb_to_hsv_compat(float r, float g, float b, float *r_h, float *r_s, float *r_v)
Definition: math_color.c:320
void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
Definition: math_color.c:414
void blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max)
Definition: math_color.c:704
static unsigned short hipart(const float f)
Definition: math_color.c:559
void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
Definition: math_color.c:427
void hsv_clamp_v(float hsv[3], float v_max)
Definition: math_color.c:348
void hsl_to_rgb(float h, float s, float l, float *r_r, float *r_g, float *r_b)
Definition: math_color.c:48
void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset)
Definition: math_color.c:542
float srgb_to_linearrgb(float c)
Definition: math_color.c:434
void hex_to_rgb(const char *hexcol, float *r_r, float *r_g, float *r_b)
Definition: math_color.c:198
float BLI_color_from_srgb_table[256]
Definition: math_color.c:556
float linearrgb_to_srgb(float c)
Definition: math_color.c:443
void lift_gamma_gain_to_asc_cdl(const float *lift, const float *gamma, const float *gain, float *offset, float *slope, float *power)
Definition: math_color.c:501
void yuv_to_rgb(float y, float u, float v, float *r_r, float *r_g, float *r_b, int colorspace)
Definition: math_color.c:103
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
Definition: math_color.c:315
void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
Definition: math_color.c:407
void cpack_to_rgb(unsigned int col, float *r_r, float *r_g, float *r_b)
Definition: math_color.c:400
void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3])
Definition: math_color.c:309
void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
Definition: math_color.c:422
static float index_to_float(const unsigned short i)
Definition: math_color.c:575
void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset)
Definition: math_color.c:524
static unsigned c
Definition: RandGen.cpp:97
#define min(a, b)
Definition: sort.c:51
float max