FastLED 3.10.8
Loading...
Searching...
No Matches

◆ five_bit_hd_solve16() [2/2]

void fl::detail::five_bit_hd_solve16 ( u16 r16,
u16 g16,
u16 b16,
u8 min_field,
CRGB * out,
u8 * out_field )

Definition at line 184 of file five_bit_hd_gamma.cpp.hpp.

185 {
186 // Target light per channel, in code x field units with eight fraction
187 // bits: a drive of 65535 is 255 x 31. The legacy solve's field rule is
188 // not monotonic at 16-bit resolution -- a one-step rise can move it to a
189 // field whose rounding lands lower -- so this uses its own: the smallest
190 // field f with T < 255.5 f, and codes rounded at that field. Within a
191 // field, rounding is monotonic; across a transition the new field's light
192 // is at least T - (f + 1) / 2 > 255 f, which is at least the old field's
193 // maximum. So emitted light never falls as a drive rises.
194 if (min_field < 1) {
195 min_field = 1;
196 }
197 if (min_field > 31) {
198 min_field = 31;
199 }
200 const u16 drives[3] = {r16, g16, b16};
201 u32 target[3];
202 u32 brightest = 0;
203 for (int i = 0; i < 3; ++i) {
204 target[i] = static_cast<u32>(
205 (static_cast<u64>(drives[i]) * 7905u * 256u) / 65535u); // 7905 = 255 x 31; u64 throughout (AVR int is 16 bits)
206 if (target[i] > brightest) {
207 brightest = target[i];
208 }
209 }
210 // 255.5 in eight fraction bits is 65408.
211 u32 field = brightest / 65408u + 1u;
212 if (field < min_field) {
213 field = min_field;
214 }
215 if (field > 31u) {
216 field = 31u;
217 }
218 const u32 unit = field * 256u;
219 for (int i = 0; i < 3; ++i) {
220 const u32 code = (target[i] + unit / 2u) / unit;
221 out->raw[i] = static_cast<u8>(code > 255u ? 255u : code);
222 }
223 *out_field = static_cast<u8>(field);
224}
unsigned char u8
Definition stdint.h:131
fl::u64 u64
Definition stdint.h:220

References fl::FL_NO_EXCEPT.