1#define FASTLED_INTERNAL
2#define __PROG_TYPES_COMPAT__
9#include "platforms/is_platform.h"
23 if (amountOfOverlay == 0) {
27 if (amountOfOverlay == 255) {
34 fract8 amountOfKeep = 255 - amountOfOverlay;
36 existing.red = scale8_LEAVING_R1_DIRTY( existing.red, amountOfKeep)
37 + scale8_LEAVING_R1_DIRTY( overlay.red, amountOfOverlay);
38 existing.green = scale8_LEAVING_R1_DIRTY( existing.green, amountOfKeep)
39 + scale8_LEAVING_R1_DIRTY( overlay.green, amountOfOverlay);
40 existing.blue = scale8_LEAVING_R1_DIRTY( existing.blue, amountOfKeep)
41 + scale8_LEAVING_R1_DIRTY( overlay.blue, amountOfOverlay);
46 existing.red = blend8(existing.red, overlay.red, amountOfOverlay);
47 existing.green = blend8(existing.green, overlay.green, amountOfOverlay);
48 existing.blue = blend8(existing.blue, overlay.blue, amountOfOverlay);
56 for (fl::u16 i = count; i; --i) {
57 nblend(*existing, *overlay, amountOfOverlay);
65 nblend(nu, p2, amountOfP2);
71 for (fl::u16 i = 0; i < count; ++i) {
72 dest[i] =
blend(src1[i], src2[i], amountOfsrc2);
79 if (amountOfOverlay == 0) {
83 if (amountOfOverlay == 255) {
88 fract8 amountOfKeep = 255 - amountOfOverlay;
90 fl::u8 huedelta8 = overlay.hue - existing.hue;
94 if (huedelta8 > 127) {
101 if (huedelta8 < 128) {
107 existing.hue = existing.hue + scale8(huedelta8, amountOfOverlay);
110 huedelta8 = -huedelta8;
111 existing.hue = existing.hue - scale8(huedelta8, amountOfOverlay);
114 existing.sat = scale8_LEAVING_R1_DIRTY(existing.sat, amountOfKeep) +
115 scale8_LEAVING_R1_DIRTY(overlay.sat, amountOfOverlay);
116 existing.val = scale8_LEAVING_R1_DIRTY(existing.val, amountOfKeep) +
117 scale8_LEAVING_R1_DIRTY(overlay.val, amountOfOverlay);
126 if (existing == overlay)
128 for (fl::u16 i = count; i; --i) {
129 nblend(*existing, *overlay, amountOfOverlay, directionCode);
138 nblend(nu, p2, amountOfP2, directionCode);
144 for (fl::u16 i = 0; i < count; ++i) {
145 dest[i] =
blend(src1[i], src2[i], amountOfsrc2, directionCode);
151 for (fl::u16 i = 0; i < num_leds; ++i) {
173 for (fl::u16 i = 0; i < num_leds; ++i) {
184 for (fl::u16 i = 0; i < numLeds; ++i) {
185 leds[i].r = scale8_LEAVING_R1_DIRTY(
leds[i].r, fr);
186 leds[i].g = scale8_LEAVING_R1_DIRTY(
leds[i].g, fg);
208 fl::u8 t192 = scale8_video(temperature, 191);
212 fl::u8 heatramp = t192 & 0x3F;
220 heatcolor.b = heatramp;
222 }
else if (t192 & 0x40) {
225 heatcolor.g = heatramp;
230 heatcolor.r = heatramp;
244#if defined(FL_IS_AVR)
272 return static_cast<fl::u16
>(channel) << 8;
276 fl::u32 segment_size) {
277 const fl::u32 a_raw =
static_cast<fl::u32
>(a) << 8;
278 const fl::u32 b_raw =
static_cast<fl::u32
>(b) << 8;
279 return static_cast<fl::u16
>(
280 (a_raw * (segment_size - frac) + b_raw * frac) / segment_size);
290 const fl::u32 scaled =
291 (
static_cast<fl::u32
>(channel) *
scale.raw()) >> 8;
292 return scaled > 0xFFFFu ? fl::u16(0xFFFF) :
static_cast<fl::u16
>(scaled);
304template <fl::u8 PaletteBits,
typename Reader>
307 TBlendType blendType) {
308 const fl::u8 frac_bits = 16 - PaletteBits;
309 const fl::u8 palette_last = (
fl::u8(1) << PaletteBits) - 1;
310 const fl::u32 segment_size = fl::u32(1) << frac_bits;
311 const fl::u8 entry_index =
static_cast<fl::u8>(index >> frac_bits);
313 static_cast<fl::u16
>(index & (segment_size - fl::u32(1)));
315 const CRGB rgb1 = reader.read(entry_index);
317 if (frac && blendType != NOBLEND) {
319 if (entry_index == palette_last) {
320 rgb2 = blendType == LINEARBLEND_NOWRAP ? rgb1 : reader.read(0);
322 rgb2 = reader.read(entry_index + 1);
325 rgb1.red, rgb2.red, frac, segment_size)),
327 rgb1.green, rgb2.green, frac, segment_size)),
329 rgb1.blue, rgb2.blue, frac, segment_size)));
343 fl::u8 index_5bit = (index >> 11);
347 const CRGB *entry = &(pal[0]) + index_5bit;
349 fl::u8 green1 = entry->green;
350 fl::u8 blue1 = entry->blue;
354 if (index_5bit == 31) {
363 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
364 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
365 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
369 fl::u8 green2 = entry->green;
370 fl::u8 blue2 = entry->blue;
371 red2 = scale8_LEAVING_R1_DIRTY(red2,
offset);
372 green2 = scale8_LEAVING_R1_DIRTY(green2,
offset);
373 blue2 = scale8_LEAVING_R1_DIRTY(blue2,
offset);
385 return CRGB(red1, green1, blue1);
390 return ColorFromPaletteHDImpl<5>(
397 if (blendType == LINEARBLEND_NOWRAP) {
398 index =
map8(index, 0, 239);
404 fl::u8 lo4 = index & 0x0F;
412 const CRGB *entry = (
CRGB *)((
fl::u8 *)(&(pal[0])) + hi4XsizeofCRGB);
417 fl::u8 green1 = entry->green;
418 fl::u8 blue1 = entry->blue;
433 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
434 red2 = scale8_LEAVING_R1_DIRTY(red2, f2);
437 fl::u8 green2 = entry->green;
438 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
439 green2 = scale8_LEAVING_R1_DIRTY(green2, f2);
442 fl::u8 blue2 = entry->blue;
443 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
444 blue2 = scale8_LEAVING_R1_DIRTY(blue2, f2);
457 red1 = scale8_LEAVING_R1_DIRTY(red1,
brightness);
458#if !(FASTLED_SCALE8_FIXED == 1)
463 green1 = scale8_LEAVING_R1_DIRTY(green1,
brightness);
464#if !(FASTLED_SCALE8_FIXED == 1)
469 blue1 = scale8_LEAVING_R1_DIRTY(blue1,
brightness);
470#if !(FASTLED_SCALE8_FIXED == 1)
482 return CRGB(red1, green1, blue1);
488 fl::u8 index_4bit = index >> 12;
492 const CRGB *entry = &(pal[0]) + index_4bit;
494 fl::u8 green1 = entry->green;
495 fl::u8 blue1 = entry->blue;
499 if (index_4bit == 15) {
508 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
509 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
510 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
514 fl::u8 green2 = entry->green;
515 fl::u8 blue2 = entry->blue;
516 red2 = scale8_LEAVING_R1_DIRTY(red2,
offset);
517 green2 = scale8_LEAVING_R1_DIRTY(green2,
offset);
518 blue2 = scale8_LEAVING_R1_DIRTY(blue2,
offset);
530 return CRGB(red1, green1, blue1);
535 return ColorFromPaletteHDImpl<4>(
543 fl::u8 index_4bit = index >> 12;
549 fl::u8 green1 = entry.green;
550 fl::u8 blue1 = entry.blue;
554 if (index_4bit == 15) {
563 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
564 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
565 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
569 fl::u8 green2 = entry.green;
570 fl::u8 blue2 = entry.blue;
571 red2 = scale8_LEAVING_R1_DIRTY(red2,
offset);
572 green2 = scale8_LEAVING_R1_DIRTY(green2,
offset);
573 blue2 = scale8_LEAVING_R1_DIRTY(blue2,
offset);
585 return CRGB(red1, green1, blue1);
590 return ColorFromPaletteHDImpl<4>(
598 fl::u8 index_5bit = (index >> 11);
604 fl::u8 green1 = entry.green;
605 fl::u8 blue1 = entry.blue;
609 if (index_5bit == 31) {
618 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
619 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
620 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
624 fl::u8 green2 = entry.green;
625 fl::u8 blue2 = entry.blue;
626 red2 = scale8_LEAVING_R1_DIRTY(red2,
offset);
627 green2 = scale8_LEAVING_R1_DIRTY(green2,
offset);
628 blue2 = scale8_LEAVING_R1_DIRTY(blue2,
offset);
640 return CRGB(red1, green1, blue1);
645 return ColorFromPaletteHDImpl<5>(
652 if (blendType == LINEARBLEND_NOWRAP) {
653 index =
map8(index, 0, 239);
659 fl::u8 lo4 = index & 0x0F;
664 fl::u8 green1 = entry.green;
665 fl::u8 blue1 = entry.blue;
681 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
682 red2 = scale8_LEAVING_R1_DIRTY(red2, f2);
685 fl::u8 green2 = entry.green;
686 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
687 green2 = scale8_LEAVING_R1_DIRTY(green2, f2);
690 fl::u8 blue2 = entry.blue;
691 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
692 blue2 = scale8_LEAVING_R1_DIRTY(blue2, f2);
705 red1 = scale8_LEAVING_R1_DIRTY(red1,
brightness);
706#if !(FASTLED_SCALE8_FIXED == 1)
711 green1 = scale8_LEAVING_R1_DIRTY(green1,
brightness);
712#if !(FASTLED_SCALE8_FIXED == 1)
717 blue1 = scale8_LEAVING_R1_DIRTY(blue1,
brightness);
718#if !(FASTLED_SCALE8_FIXED == 1)
730 return CRGB(red1, green1, blue1);
735 if (blendType == LINEARBLEND_NOWRAP) {
736 index =
map8(index, 0, 247);
741#if defined(FL_IS_AVR)
748 fl::u8 lo3 = index & 0x07;
756 const CRGB *entry = (
CRGB *)((
fl::u8 *)(&(pal[0])) + hi5XsizeofCRGB);
759 fl::u8 green1 = entry->green;
760 fl::u8 blue1 = entry->blue;
776 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
777 red2 = scale8_LEAVING_R1_DIRTY(red2, f2);
780 fl::u8 green2 = entry->green;
781 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
782 green2 = scale8_LEAVING_R1_DIRTY(green2, f2);
785 fl::u8 blue2 = entry->blue;
786 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
787 blue2 = scale8_LEAVING_R1_DIRTY(blue2, f2);
800 red1 = scale8_LEAVING_R1_DIRTY(red1,
brightness);
801#if !(FASTLED_SCALE8_FIXED == 1)
806 green1 = scale8_LEAVING_R1_DIRTY(green1,
brightness);
807#if !(FASTLED_SCALE8_FIXED == 1)
812 blue1 = scale8_LEAVING_R1_DIRTY(blue1,
brightness);
813#if !(FASTLED_SCALE8_FIXED == 1)
825 return CRGB(red1, green1, blue1);
830 if (blendType == LINEARBLEND_NOWRAP) {
831 index =
map8(index, 0, 247);
836#if defined(FL_IS_AVR)
843 fl::u8 lo3 = index & 0x07;
848 fl::u8 green1 = entry.green;
849 fl::u8 blue1 = entry.blue;
865 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
866 red2 = scale8_LEAVING_R1_DIRTY(red2, f2);
869 fl::u8 green2 = entry.green;
870 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
871 green2 = scale8_LEAVING_R1_DIRTY(green2, f2);
874 fl::u8 blue2 = entry.blue;
875 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
876 blue2 = scale8_LEAVING_R1_DIRTY(blue2, f2);
889 red1 = scale8_LEAVING_R1_DIRTY(red1,
brightness);
890#if !(FASTLED_SCALE8_FIXED == 1)
895 green1 = scale8_LEAVING_R1_DIRTY(green1,
brightness);
896#if !(FASTLED_SCALE8_FIXED == 1)
901 blue1 = scale8_LEAVING_R1_DIRTY(blue1,
brightness);
902#if !(FASTLED_SCALE8_FIXED == 1)
914 return CRGB(red1, green1, blue1);
919 const CRGB *entry = &(pal[0]) + index;
922 fl::u8 green = entry->green;
923 fl::u8 blue = entry->blue;
927 red = scale8_video_LEAVING_R1_DIRTY(red,
brightness);
928 green = scale8_video_LEAVING_R1_DIRTY(green,
brightness);
929 blue = scale8_video_LEAVING_R1_DIRTY(blue,
brightness);
933 return CRGB(red, green, blue);
939 fl::u8 index_8bit = index >> 8;
943 const CRGB *entry = &(pal[0]) + index_8bit;
945 fl::u8 green1 = entry->green;
946 fl::u8 blue1 = entry->blue;
950 if (index_8bit == 255) {
959 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
960 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
961 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
965 fl::u8 green2 = entry->green;
966 fl::u8 blue2 = entry->blue;
967 red2 = scale8_LEAVING_R1_DIRTY(red2,
offset);
968 green2 = scale8_LEAVING_R1_DIRTY(green2,
offset);
969 blue2 = scale8_LEAVING_R1_DIRTY(blue2,
offset);
981 return CRGB(red1, green1, blue1);
986 return ColorFromPaletteHDImpl<8>(
993 if (blendType == LINEARBLEND_NOWRAP) {
994 index =
map8(index, 0, 239);
1000 fl::u8 lo4 = index & 0x0F;
1003 const CHSV *entry = &(pal[0]) + hi4;
1005 fl::u8 hue1 = entry->hue;
1006 fl::u8 sat1 = entry->sat;
1007 fl::u8 val1 = entry->val;
1022 fl::u8 hue2 = entry->hue;
1023 fl::u8 sat2 = entry->sat;
1024 fl::u8 val2 = entry->val;
1037 if (sat1 == 0 || val1 == 0) {
1043 if (sat2 == 0 || val2 == 0) {
1047 sat1 = scale8_LEAVING_R1_DIRTY(sat1, f1);
1048 val1 = scale8_LEAVING_R1_DIRTY(val1, f1);
1050 sat2 = scale8_LEAVING_R1_DIRTY(sat2, f2);
1051 val2 = scale8_LEAVING_R1_DIRTY(val2, f2);
1060 if (deltaHue & 0x80) {
1062 hue1 -= scale8(256 - deltaHue, f2);
1065 hue1 += scale8(deltaHue, f2);
1075 return CHSV(hue1, sat1, val1);
1080 if (blendType == LINEARBLEND_NOWRAP) {
1081 index =
map8(index, 0, 247);
1086#if defined(FL_IS_AVR)
1093 fl::u8 lo3 = index & 0x07;
1096 const CHSV *entry = (
CHSV *)((
fl::u8 *)(&(pal[0])) + hi5XsizeofCHSV);
1098 fl::u8 hue1 = entry->hue;
1099 fl::u8 sat1 = entry->sat;
1100 fl::u8 val1 = entry->val;
1115 fl::u8 hue2 = entry->hue;
1116 fl::u8 sat2 = entry->sat;
1117 fl::u8 val2 = entry->val;
1130 if (sat1 == 0 || val1 == 0) {
1136 if (sat2 == 0 || val2 == 0) {
1140 sat1 = scale8_LEAVING_R1_DIRTY(sat1, f1);
1141 val1 = scale8_LEAVING_R1_DIRTY(val1, f1);
1143 sat2 = scale8_LEAVING_R1_DIRTY(sat2, f2);
1144 val2 = scale8_LEAVING_R1_DIRTY(val2, f2);
1153 if (deltaHue & 0x80) {
1155 hue1 -= scale8(256 - deltaHue, f2);
1158 hue1 += scale8(deltaHue, f2);
1168 return CHSV(hue1, sat1, val1);
1173 CHSV hsv = *(&(pal[0]) + index);
1176 hsv.value = scale8_video(hsv.value,
brightness);
1184template <
typename TSrcPalette,
typename TDestPalette>
1186 TDestPalette &destpal) {
1187 const fl::u16 src_size =
sizeof(srcpal.entries) /
sizeof(srcpal.entries[0]);
1188 const fl::u16 dest_size =
1189 sizeof(destpal.entries) /
sizeof(destpal.entries[0]);
1190 const fl::u16 repeat = dest_size / src_size;
1191 for (fl::u16 i = 0; i < src_size; ++i) {
1192 const fl::u16 start = i * repeat;
1193 for (fl::u16 j = 0; j < repeat; ++j) {
1194 destpal[
static_cast<fl::u8>(start + j)] = srcpal[
static_cast<fl::u8>(i)];
1199template <
typename TSrcPalette,
typename TDestPalette>
1201 TDestPalette &destpal) {
1202 const fl::u16 dest_size =
1203 sizeof(destpal.entries) /
sizeof(destpal.entries[0]);
1204 for (fl::u16 i = 0; i < dest_size; ++i) {
1205 destpal[
static_cast<fl::u8>(i)] =
1213 class CRGBPalette256 &destpal256) {
1218 class CHSVPalette256 &destpal256) {
1223 class CRGBPalette32 &destpal32) {
1228 class CHSVPalette32 &destpal32) {
1233 class CRGBPalette256 &destpal256) {
1238 class CHSVPalette256 &destpal256) {
1244void SetupPartyColors(CRGBPalette16& pal)
1257 p1 = (
fl::u8 *)current.entries;
1258 p2 = (
fl::u8 *)target.entries;
1260 const fl::u8 totalChannels =
sizeof(CRGBPalette16);
1261 for (
fl::u8 i = 0; i < totalChannels; ++i) {
1263 if (p1[i] == p2[i]) {
1268 if (p1[i] < p2[i]) {
1275 if (p1[i] > p2[i]) {
1278 if (p1[i] > p2[i]) {
1284 if (changes >= maxChanges) {
1297 constexpr fl::s16x16 inv_255_fp(1.0f / 255.0f);
1303 const fl::u32 scaled =
1304 (
static_cast<fl::u32
>(r.
raw()) * 255u + 0x8000u) >> 16;
1340 for (fl::u16 i = 0; i < count; ++i) {
1346 float gammaG,
float gammaB) {
1347 for (fl::u16 i = 0; i < count; ++i) {
fl::UISlider brightness("Brightness", BRIGHTNESS, 0, 255)
fl::UISlider scale("Scale", 4,.1, 4,.1)
@ HUE_PURPLE
Purple (270°)
constexpr i32 raw() const FL_NOEXCEPT
static FASTLED_FORCE_INLINE s16x16 pow(s16x16 base, s16x16 exp) FL_NOEXCEPT
static constexpr FASTLED_FORCE_INLINE u8x8 from_raw(u16 raw) FL_NOEXCEPT
@ FORWARD_HUES
Hue always goes clockwise around the color wheel.
@ BACKWARD_HUES
Hue always goes counter-clockwise around the color wheel.
fl::u32 TProgmemRGBPalette32[32]
CRGBPalette32 entries stored in PROGMEM memory.
fl::u32 TProgmemRGBPalette16[16]
CRGBPalette16 entries stored in PROGMEM memory.
fl::UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
#define FL_PGM_READ_DWORD_NEAR(x)
Read a double word (32-bit) from PROGMEM memory.
Utility functions for color fill, palettes, blending, and more.
Internal FastLED header for implementation files.
void fill_gradient(T *targetArray, u16 startpos, CHSV startcolor, u16 endpos, CHSV endcolor, TGradientDirectionCode directionCode=SHORTEST_HUES) FL_NOEXCEPT
Fill a range of LEDs with a smooth HSV gradient between two HSV colors.
LIB8STATIC fl::u8 map8(fl::u8 in, fl::u8 rangeStart, fl::u8 rangeEnd)
Map from one full-range 8-bit value into a narrower range of 8-bit values, possibly a range of hues.
void scale_rgb_hd(CRGB16 &rgb, fl::u8x8 brightness)
fl::u16 promote_channel_to_hd(fl::u8 channel)
CRGB16 promote_rgb_to_hd(const CRGB &rgb)
fl::u16 lerp_channel_to_hd(fl::u8 a, fl::u8 b, fl::u16 frac, fl::u32 segment_size)
fl::u16 scale_hd_channel(fl::u16 channel, fl::u8x8 scale)
CRGB16 ColorFromPaletteHDImpl(const Reader &reader, fl::u16 index, fl::u8x8 brightness, TBlendType blendType)
void UpscalePaletteInterpolated(const TSrcPalette &srcpal, TDestPalette &destpal)
void UpscalePaletteRepeat(const TSrcPalette &srcpal, TDestPalette &destpal)
u8 fract8
Fixed-Point Fractional Types.
TGradientDirectionCode
Hue direction for calculating fill gradients.
@ SHORTEST_HUES
Hue goes whichever way is shortest.
@ LONGEST_HUES
Hue goes whichever way is longest.
@ FORWARD_HUES
Hue always goes clockwise around the color wheel.
@ BACKWARD_HUES
Hue always goes counter-clockwise around the color wheel.
void fadeUsingColor(CRGB *leds, fl::u16 numLeds, const CRGB &colormask)
void UpscalePalette(const class CRGBPalette16 &srcpal16, class CRGBPalette256 &destpal256)
void fadeToBlackBy(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy)
CRGB ColorFromPalette(const CRGBPalette16 &pal, fl::u8 index, fl::u8 brightness, TBlendType blendType)
void nscale8(CRGB *leds, fl::u16 num_leds, fl::u8 scale)
void fade_raw(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy)
void fade_video(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy)
CRGB ColorFromPaletteExtended(const CRGBPalette32 &pal, fl::u16 index, fl::u8 brightness, TBlendType blendType)
CRGB16 ColorFromPaletteHD(const CRGBPalette32 &pal, fl::u16 index, fl::u8x8 brightness, TBlendType blendType)
fl::u8 applyGamma_video(fl::u8 brightness, float gamma)
expected< T, E > result
Alias for expected (Rust-style naming)
CRGB blend(const CRGB &p1, const CRGB &p2, fract8 amountOfP2)
CRGB & nblend(CRGB &existing, const CRGB &overlay, fract8 amountOfOverlay)
CRGB HeatColor(fl::u8 temperature)
fl::u8 lsrX4(fl::u8 dividend)
Helper function to divide a number by 16, aka four logical shift right (LSR)'s.
constexpr u32 gamma(float g) FL_NOEXCEPT
void fadeLightBy(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy)
CRGB & napplyGamma_video(CRGB &rgb, float gamma)
void nblendPaletteTowardPalette(CRGBPalette16 ¤t, CRGBPalette16 &target, fl::u8 maxChanges)
void nscale8_video(CRGB *leds, fl::u16 num_leds, fl::u8 scale)
Base definition for an LED controller.
Representation of an 8-bit RGB pixel (Red, Green, Blue)
CRGB read(fl::u8 index) const
fl::span< const fl::u32, Size > entries
CRGB read(fl::u8 index) const
fl::span< const CRGB, Size > entries