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