FastLED 3.9.3
Loading...
Searching...
No Matches
rgbw.cpp
1
2#include <stdint.h>
3
4#define FASTLED_INTERNAL
5#include "FastLED.h"
6
7#include "rgbw.h"
8
9
10FASTLED_NAMESPACE_BEGIN
11
12namespace {
13inline uint8_t min3(uint8_t a, uint8_t b, uint8_t c) {
14 if (a < b) {
15 if (a < c) {
16 return a;
17 } else {
18 return c;
19 }
20 } else {
21 if (b < c) {
22 return b;
23 } else {
24 return c;
25 }
26 }
27}
28
29inline uint8_t divide_by_3(uint8_t x) {
30 uint16_t y = (uint16_t(x) * 85) >> 8;
31 return static_cast<uint8_t>(y);
32}
33} // namespace
34
35// @brief Converts RGB to RGBW using a color transfer method
36// from color channels to 3x white.
37// @author Jonathanese
38void rgb_2_rgbw_exact(uint16_t w_color_temperature, uint8_t r, uint8_t g,
39 uint8_t b, uint8_t r_scale, uint8_t g_scale,
40 uint8_t b_scale, uint8_t *out_r, uint8_t *out_g,
41 uint8_t *out_b, uint8_t *out_w) {
42 r = scale8(r, r_scale);
43 g = scale8(g, g_scale);
44 b = scale8(b, b_scale);
45 uint8_t min_component = min3(r, g, b);
46 *out_r = r - min_component;
47 *out_g = g - min_component;
48 *out_b = b - min_component;
49 *out_w = min_component;
50}
51
52void rgb_2_rgbw_max_brightness(uint16_t w_color_temperature, uint8_t r,
53 uint8_t g, uint8_t b, uint8_t r_scale,
54 uint8_t g_scale, uint8_t b_scale, uint8_t *out_r,
55 uint8_t *out_g, uint8_t *out_b, uint8_t *out_w) {
56 *out_r = scale8(r, r_scale);
57 *out_g = scale8(g, g_scale);
58 *out_b = scale8(b, b_scale);
59 *out_w = min3(r, g, b);
60}
61
62void rgb_2_rgbw_null_white_pixel(uint16_t w_color_temperature, uint8_t r,
63 uint8_t g, uint8_t b, uint8_t r_scale,
64 uint8_t g_scale, uint8_t b_scale,
65 uint8_t *out_r, uint8_t *out_g, uint8_t *out_b,
66 uint8_t *out_w) {
67 *out_r = scale8(r, r_scale);
68 *out_g = scale8(g, g_scale);
69 *out_b = scale8(b, b_scale);
70 *out_w = 0;
71}
72
73void rgb_2_rgbw_white_boosted(uint16_t w_color_temperature, uint8_t r,
74 uint8_t g, uint8_t b, uint8_t r_scale,
75 uint8_t g_scale, uint8_t b_scale, uint8_t *out_r,
76 uint8_t *out_g, uint8_t *out_b, uint8_t *out_w) {
77 r = scale8(r, r_scale);
78 g = scale8(g, g_scale);
79 b = scale8(b, b_scale);
80 uint8_t min_component = min3(r, g, b);
81 uint8_t w;
82 bool is_min = true;
83 if (min_component <= 84) {
84 w = 3 * min_component;
85 } else {
86 w = 255;
87 is_min = false;
88 }
89 uint8_t r_prime;
90 uint8_t g_prime;
91 uint8_t b_prime;
92 if (is_min) {
93 r_prime = r - min_component;
94 g_prime = g - min_component;
95 b_prime = b - min_component;
96 } else {
97 uint8_t w3 = divide_by_3(w);
98 r_prime = r - w3;
99 g_prime = g - w3;
100 b_prime = b - w3;
101 }
102
103 *out_r = r_prime;
104 *out_g = g_prime;
105 *out_b = b_prime;
106 *out_w = w;
107}
108
109rgb_2_rgbw_function g_user_function = rgb_2_rgbw_exact;
110
111void set_rgb_2_rgbw_function(rgb_2_rgbw_function func) {
112 if (func == nullptr) {
113 g_user_function = rgb_2_rgbw_exact;
114 return;
115 }
116 g_user_function = func;
117}
118
119void rgb_2_rgbw_user_function(uint16_t w_color_temperature, uint8_t r,
120 uint8_t g, uint8_t b, uint8_t r_scale,
121 uint8_t g_scale, uint8_t b_scale, uint8_t *out_r,
122 uint8_t *out_g, uint8_t *out_b, uint8_t *out_w) {
123 g_user_function(w_color_temperature, r, g, b, r_scale, g_scale, b_scale,
124 out_r, out_g, out_b, out_w);
125}
126
127void rgbw_partial_reorder(EOrderW w_placement, uint8_t b0, uint8_t b1,
128 uint8_t b2, uint8_t w, uint8_t *out_b0,
129 uint8_t *out_b1, uint8_t *out_b2, uint8_t *out_b3) {
130
131 uint8_t out[4] = {b0, b1, b2, 0};
132 switch (w_placement) {
133 // unrolled loop for speed.
134 case W3:
135 out[3] = w;
136 break;
137 case W2:
138 out[3] = out[2]; // memmove and copy.
139 out[2] = w;
140 break;
141 case W1:
142 out[3] = out[2];
143 out[2] = out[1];
144 out[1] = w;
145 break;
146 case W0:
147 out[3] = out[2];
148 out[2] = out[1];
149 out[1] = out[0];
150 out[0] = w;
151 break;
152 }
153 *out_b0 = out[0];
154 *out_b1 = out[1];
155 *out_b2 = out[2];
156 *out_b3 = out[3];
157}
158
159FASTLED_NAMESPACE_END
central include file for FastLED, defines the CFastLED class/object
LIB8STATIC_ALWAYS_INLINE uint8_t scale8(uint8_t i, fract8 scale)
Scale one byte by a second one, which is treated as the numerator of a fraction whose denominator is ...
Definition scale8.h:34