1#define FASTLED_INTERNAL
2#define __PROG_TYPES_COMPAT__
9#include "platforms/is_platform.h"
33 return value < 0.0f ? -magnitude : magnitude;
37 const float red =
static_cast<float>(
rgb.r) / 255.0f;
38 const float green =
static_cast<float>(
rgb.g) / 255.0f;
39 const float blue =
static_cast<float>(
rgb.b) / 255.0f;
41 const float l = 0.4122214708f * red + 0.5363325363f * green +
43 const float m = 0.2119034982f * red + 0.6806995451f * green +
45 const float s = 0.0883024619f * red + 0.2817188376f * green +
53 0.2104542553f * lRoot + 0.7936177850f * mRoot -
54 0.0040720468f * sRoot,
55 1.9779984951f * lRoot - 2.4285922050f * mRoot +
56 0.4505937099f * sRoot,
57 0.0259040371f * lRoot + 0.7827717662f * mRoot -
58 0.8086757660f * sRoot,
64 return static_cast<fl::u8>(scaled);
68 const float lRoot = lab.lightness + 0.3963377774f * lab.green_red +
69 0.2158037573f * lab.blue_yellow;
70 const float mRoot = lab.lightness - 0.1055613458f * lab.green_red -
71 0.0638541728f * lab.blue_yellow;
72 const float sRoot = lab.lightness - 0.0894841775f * lab.green_red -
73 1.2914855480f * lab.blue_yellow;
74 const float l = lRoot * lRoot * lRoot;
75 const float m = mRoot * mRoot * mRoot;
76 const float s = sRoot * sRoot * sRoot;
89 if (amountOfOverlay == 0) {
93 if (amountOfOverlay == 255) {
100 fract8 amountOfKeep = 255 - amountOfOverlay;
102 existing.red = scale8_LEAVING_R1_DIRTY( existing.red, amountOfKeep)
103 + scale8_LEAVING_R1_DIRTY( overlay.red, amountOfOverlay);
104 existing.green = scale8_LEAVING_R1_DIRTY( existing.green, amountOfKeep)
105 + scale8_LEAVING_R1_DIRTY( overlay.green, amountOfOverlay);
106 existing.blue = scale8_LEAVING_R1_DIRTY( existing.blue, amountOfKeep)
107 + scale8_LEAVING_R1_DIRTY( overlay.blue, amountOfOverlay);
112 existing.red = blend8(existing.red, overlay.red, amountOfOverlay);
113 existing.green = blend8(existing.green, overlay.green, amountOfOverlay);
114 existing.blue = blend8(existing.blue, overlay.blue, amountOfOverlay);
122 for (fl::u16 i = count; i; --i) {
123 nblend(*existing, *overlay, amountOfOverlay);
131 nblend(nu, p2, amountOfP2);
136 if (amountOfP2 == 0) {
return p1; }
137 if (amountOfP2 == 255) {
return p2; }
139 const Oklab first = rgbToOklab(p1);
140 const Oklab second = rgbToOklab(p2);
141 const float amount =
static_cast<float>(amountOfP2) / 255.0f;
142 const Oklab mixed = {
143 first.lightness + (second.lightness - first.lightness) * amount,
144 first.green_red + (second.green_red - first.green_red) * amount,
145 first.blue_yellow + (second.blue_yellow - first.blue_yellow) * amount,
147 return oklabToRgb(mixed);
152 for (fl::u16 i = 0; i < count; ++i) {
153 dest[i] =
blend(src1[i], src2[i], amountOfsrc2);
160 if (amountOfOverlay == 0) {
164 if (amountOfOverlay == 255) {
169 fract8 amountOfKeep = 255 - amountOfOverlay;
171 fl::u8 huedelta8 = overlay.hue - existing.hue;
175 if (huedelta8 > 127) {
182 if (huedelta8 < 128) {
188 existing.hue = existing.hue + scale8(huedelta8, amountOfOverlay);
191 huedelta8 = -huedelta8;
192 existing.hue = existing.hue - scale8(huedelta8, amountOfOverlay);
195 existing.sat = scale8_LEAVING_R1_DIRTY(existing.sat, amountOfKeep) +
196 scale8_LEAVING_R1_DIRTY(overlay.sat, amountOfOverlay);
197 existing.val = scale8_LEAVING_R1_DIRTY(existing.val, amountOfKeep) +
198 scale8_LEAVING_R1_DIRTY(overlay.val, amountOfOverlay);
207 if (existing == overlay)
209 for (fl::u16 i = count; i; --i) {
210 nblend(*existing, *overlay, amountOfOverlay, directionCode);
219 nblend(nu, p2, amountOfP2, directionCode);
225 for (fl::u16 i = 0; i < count; ++i) {
226 dest[i] =
blend(src1[i], src2[i], amountOfsrc2, directionCode);
232 for (fl::u16 i = 0; i < num_leds; ++i) {
254 for (fl::u16 i = 0; i < num_leds; ++i) {
265 for (fl::u16 i = 0; i < numLeds; ++i) {
266 leds[i].r = scale8_LEAVING_R1_DIRTY(
leds[i].r, fr);
267 leds[i].g = scale8_LEAVING_R1_DIRTY(
leds[i].
g, fg);
290 fl::u8 t192 = scale8_video(temperature, 191);
294 fl::u8 heatramp = t192 & 0x3F;
302 heatcolor.b = heatramp;
304 }
else if (t192 & 0x40) {
307 heatcolor.g = heatramp;
312 heatcolor.r = heatramp;
326#if defined(FL_IS_AVR)
354 return static_cast<fl::u16
>(channel) << 8;
359 const fl::u32 a_raw =
static_cast<fl::u32
>(a) << 8;
360 const fl::u32 b_raw =
static_cast<fl::u32
>(b) << 8;
361 return static_cast<fl::u16
>(
362 (a_raw * (segment_size - frac) + b_raw * frac) / segment_size);
372 const fl::u32 scaled =
373 (
static_cast<fl::u32
>(channel) *
scale.raw()) >> 8;
374 return scaled > 0xFFFFu ? fl::u16(0xFFFF) :
static_cast<fl::u16
>(scaled);
386template <fl::u8 PaletteBits,
typename Reader>
390 const fl::u8 frac_bits = 16 - PaletteBits;
391 const fl::u8 palette_last = (
fl::u8(1) << PaletteBits) - 1;
392 const fl::u32 segment_size = fl::u32(1) << frac_bits;
393 const fl::u8 entry_index =
static_cast<fl::u8>(index >> frac_bits);
395 static_cast<fl::u16
>(index & (segment_size - fl::u32(1)));
397 const CRGB rgb1 = reader.read(entry_index);
399 if (frac && blendType != NOBLEND) {
401 if (entry_index == palette_last) {
402 rgb2 = blendType == LINEARBLEND_NOWRAP ? rgb1 : reader.read(0);
404 rgb2 = reader.read(entry_index + 1);
407 rgb1.red, rgb2.red, frac, segment_size)),
409 rgb1.green, rgb2.green, frac, segment_size)),
411 rgb1.blue, rgb2.blue, frac, segment_size)));
425 fl::u8 index_5bit = (index >> 11);
429 const CRGB *entry = &(pal[0]) + index_5bit;
431 fl::u8 green1 = entry->green;
432 fl::u8 blue1 = entry->blue;
436 if (index_5bit == 31) {
445 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
446 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
447 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
451 fl::u8 green2 = entry->green;
452 fl::u8 blue2 = entry->blue;
453 red2 = scale8_LEAVING_R1_DIRTY(red2,
offset);
454 green2 = scale8_LEAVING_R1_DIRTY(green2,
offset);
455 blue2 = scale8_LEAVING_R1_DIRTY(blue2,
offset);
467 return CRGB(red1, green1, blue1);
472 return ColorFromPaletteHDImpl<5>(
479 if (blendType == LINEARBLEND_NOWRAP) {
480 index =
map8(index, 0, 239);
486 fl::u8 lo4 = index & 0x0F;
494 const CRGB *entry = (
CRGB *)((
fl::u8 *)(&(pal[0])) + hi4XsizeofCRGB);
499 fl::u8 green1 = entry->green;
500 fl::u8 blue1 = entry->blue;
515 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
516 red2 = scale8_LEAVING_R1_DIRTY(red2, f2);
519 fl::u8 green2 = entry->green;
520 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
521 green2 = scale8_LEAVING_R1_DIRTY(green2, f2);
524 fl::u8 blue2 = entry->blue;
525 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
526 blue2 = scale8_LEAVING_R1_DIRTY(blue2, f2);
539 red1 = scale8_LEAVING_R1_DIRTY(red1,
brightness);
540#if !(FASTLED_SCALE8_FIXED == 1)
545 green1 = scale8_LEAVING_R1_DIRTY(green1,
brightness);
546#if !(FASTLED_SCALE8_FIXED == 1)
551 blue1 = scale8_LEAVING_R1_DIRTY(blue1,
brightness);
552#if !(FASTLED_SCALE8_FIXED == 1)
564 return CRGB(red1, green1, blue1);
570 fl::u8 index_4bit = index >> 12;
574 const CRGB *entry = &(pal[0]) + index_4bit;
576 fl::u8 green1 = entry->green;
577 fl::u8 blue1 = entry->blue;
581 if (index_4bit == 15) {
590 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
591 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
592 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
596 fl::u8 green2 = entry->green;
597 fl::u8 blue2 = entry->blue;
598 red2 = scale8_LEAVING_R1_DIRTY(red2,
offset);
599 green2 = scale8_LEAVING_R1_DIRTY(green2,
offset);
600 blue2 = scale8_LEAVING_R1_DIRTY(blue2,
offset);
612 return CRGB(red1, green1, blue1);
617 return ColorFromPaletteHDImpl<4>(
625 fl::u8 index_4bit = index >> 12;
631 fl::u8 green1 = entry.green;
632 fl::u8 blue1 = entry.blue;
636 if (index_4bit == 15) {
645 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
646 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
647 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
651 fl::u8 green2 = entry.green;
652 fl::u8 blue2 = entry.blue;
653 red2 = scale8_LEAVING_R1_DIRTY(red2,
offset);
654 green2 = scale8_LEAVING_R1_DIRTY(green2,
offset);
655 blue2 = scale8_LEAVING_R1_DIRTY(blue2,
offset);
667 return CRGB(red1, green1, blue1);
672 return ColorFromPaletteHDImpl<4>(
680 fl::u8 index_5bit = (index >> 11);
686 fl::u8 green1 = entry.green;
687 fl::u8 blue1 = entry.blue;
691 if (index_5bit == 31) {
700 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
701 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
702 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
706 fl::u8 green2 = entry.green;
707 fl::u8 blue2 = entry.blue;
708 red2 = scale8_LEAVING_R1_DIRTY(red2,
offset);
709 green2 = scale8_LEAVING_R1_DIRTY(green2,
offset);
710 blue2 = scale8_LEAVING_R1_DIRTY(blue2,
offset);
722 return CRGB(red1, green1, blue1);
727 return ColorFromPaletteHDImpl<5>(
734 if (blendType == LINEARBLEND_NOWRAP) {
735 index =
map8(index, 0, 239);
741 fl::u8 lo4 = index & 0x0F;
746 fl::u8 green1 = entry.green;
747 fl::u8 blue1 = entry.blue;
763 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
764 red2 = scale8_LEAVING_R1_DIRTY(red2, f2);
767 fl::u8 green2 = entry.green;
768 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
769 green2 = scale8_LEAVING_R1_DIRTY(green2, f2);
772 fl::u8 blue2 = entry.blue;
773 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
774 blue2 = scale8_LEAVING_R1_DIRTY(blue2, f2);
787 red1 = scale8_LEAVING_R1_DIRTY(red1,
brightness);
788#if !(FASTLED_SCALE8_FIXED == 1)
793 green1 = scale8_LEAVING_R1_DIRTY(green1,
brightness);
794#if !(FASTLED_SCALE8_FIXED == 1)
799 blue1 = scale8_LEAVING_R1_DIRTY(blue1,
brightness);
800#if !(FASTLED_SCALE8_FIXED == 1)
812 return CRGB(red1, green1, blue1);
817 if (blendType == LINEARBLEND_NOWRAP) {
818 index =
map8(index, 0, 247);
823#if defined(FL_IS_AVR)
830 fl::u8 lo3 = index & 0x07;
838 const CRGB *entry = (
CRGB *)((
fl::u8 *)(&(pal[0])) + hi5XsizeofCRGB);
841 fl::u8 green1 = entry->green;
842 fl::u8 blue1 = entry->blue;
858 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
859 red2 = scale8_LEAVING_R1_DIRTY(red2, f2);
862 fl::u8 green2 = entry->green;
863 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
864 green2 = scale8_LEAVING_R1_DIRTY(green2, f2);
867 fl::u8 blue2 = entry->blue;
868 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
869 blue2 = scale8_LEAVING_R1_DIRTY(blue2, f2);
882 red1 = scale8_LEAVING_R1_DIRTY(red1,
brightness);
883#if !(FASTLED_SCALE8_FIXED == 1)
888 green1 = scale8_LEAVING_R1_DIRTY(green1,
brightness);
889#if !(FASTLED_SCALE8_FIXED == 1)
894 blue1 = scale8_LEAVING_R1_DIRTY(blue1,
brightness);
895#if !(FASTLED_SCALE8_FIXED == 1)
907 return CRGB(red1, green1, blue1);
912 if (blendType == LINEARBLEND_NOWRAP) {
913 index =
map8(index, 0, 247);
918#if defined(FL_IS_AVR)
925 fl::u8 lo3 = index & 0x07;
930 fl::u8 green1 = entry.green;
931 fl::u8 blue1 = entry.blue;
947 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
948 red2 = scale8_LEAVING_R1_DIRTY(red2, f2);
951 fl::u8 green2 = entry.green;
952 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
953 green2 = scale8_LEAVING_R1_DIRTY(green2, f2);
956 fl::u8 blue2 = entry.blue;
957 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
958 blue2 = scale8_LEAVING_R1_DIRTY(blue2, f2);
971 red1 = scale8_LEAVING_R1_DIRTY(red1,
brightness);
972#if !(FASTLED_SCALE8_FIXED == 1)
977 green1 = scale8_LEAVING_R1_DIRTY(green1,
brightness);
978#if !(FASTLED_SCALE8_FIXED == 1)
983 blue1 = scale8_LEAVING_R1_DIRTY(blue1,
brightness);
984#if !(FASTLED_SCALE8_FIXED == 1)
996 return CRGB(red1, green1, blue1);
1001 const CRGB *entry = &(pal[0]) + index;
1004 fl::u8 green = entry->green;
1005 fl::u8 blue = entry->blue;
1009 red = scale8_video_LEAVING_R1_DIRTY(red,
brightness);
1010 green = scale8_video_LEAVING_R1_DIRTY(green,
brightness);
1011 blue = scale8_video_LEAVING_R1_DIRTY(blue,
brightness);
1015 return CRGB(red, green, blue);
1021 fl::u8 index_8bit = index >> 8;
1025 const CRGB *entry = &(pal[0]) + index_8bit;
1026 fl::u8 red1 = entry->red;
1027 fl::u8 green1 = entry->green;
1028 fl::u8 blue1 = entry->blue;
1032 if (index_8bit == 255) {
1041 red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
1042 green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
1043 blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
1046 fl::u8 red2 = entry->red;
1047 fl::u8 green2 = entry->green;
1048 fl::u8 blue2 = entry->blue;
1049 red2 = scale8_LEAVING_R1_DIRTY(red2,
offset);
1050 green2 = scale8_LEAVING_R1_DIRTY(green2,
offset);
1051 blue2 = scale8_LEAVING_R1_DIRTY(blue2,
offset);
1063 return CRGB(red1, green1, blue1);
1068 return ColorFromPaletteHDImpl<8>(
1075 if (blendType == LINEARBLEND_NOWRAP) {
1076 index =
map8(index, 0, 239);
1082 fl::u8 lo4 = index & 0x0F;
1085 const CHSV *entry = &(pal[0]) + hi4;
1087 fl::u8 hue1 = entry->hue;
1088 fl::u8 sat1 = entry->sat;
1089 fl::u8 val1 = entry->val;
1104 fl::u8 hue2 = entry->hue;
1105 fl::u8 sat2 = entry->sat;
1106 fl::u8 val2 = entry->val;
1119 if (sat1 == 0 || val1 == 0) {
1125 if (sat2 == 0 || val2 == 0) {
1129 sat1 = scale8_LEAVING_R1_DIRTY(sat1, f1);
1130 val1 = scale8_LEAVING_R1_DIRTY(val1, f1);
1132 sat2 = scale8_LEAVING_R1_DIRTY(sat2, f2);
1133 val2 = scale8_LEAVING_R1_DIRTY(val2, f2);
1142 if (deltaHue & 0x80) {
1144 hue1 -= scale8(256 - deltaHue, f2);
1147 hue1 += scale8(deltaHue, f2);
1157 return CHSV(hue1, sat1, val1);
1162 if (blendType == LINEARBLEND_NOWRAP) {
1163 index =
map8(index, 0, 247);
1168#if defined(FL_IS_AVR)
1175 fl::u8 lo3 = index & 0x07;
1178 const CHSV *entry = (
CHSV *)((
fl::u8 *)(&(pal[0])) + hi5XsizeofCHSV);
1180 fl::u8 hue1 = entry->hue;
1181 fl::u8 sat1 = entry->sat;
1182 fl::u8 val1 = entry->val;
1197 fl::u8 hue2 = entry->hue;
1198 fl::u8 sat2 = entry->sat;
1199 fl::u8 val2 = entry->val;
1212 if (sat1 == 0 || val1 == 0) {
1218 if (sat2 == 0 || val2 == 0) {
1222 sat1 = scale8_LEAVING_R1_DIRTY(sat1, f1);
1223 val1 = scale8_LEAVING_R1_DIRTY(val1, f1);
1225 sat2 = scale8_LEAVING_R1_DIRTY(sat2, f2);
1226 val2 = scale8_LEAVING_R1_DIRTY(val2, f2);
1235 if (deltaHue & 0x80) {
1237 hue1 -= scale8(256 - deltaHue, f2);
1240 hue1 += scale8(deltaHue, f2);
1250 return CHSV(hue1, sat1, val1);
1255 CHSV hsv = *(&(pal[0]) + index);
1258 hsv.value = scale8_video(hsv.value,
brightness);
1266template <
typename TSrcPalette,
typename TDestPalette>
1269 const fl::u16 src_size =
sizeof(srcpal.entries) /
sizeof(srcpal.entries[0]);
1270 const fl::u16 dest_size =
1271 sizeof(destpal.entries) /
sizeof(destpal.entries[0]);
1272 const fl::u16 repeat = dest_size / src_size;
1273 for (fl::u16 i = 0; i < src_size; ++i) {
1274 const fl::u16 start = i * repeat;
1275 for (fl::u16 j = 0; j < repeat; ++j) {
1276 destpal[
static_cast<fl::u8>(start + j)] = srcpal[
static_cast<fl::u8>(i)];
1281template <
typename TSrcPalette,
typename TDestPalette>
1284 const fl::u16 dest_size =
1285 sizeof(destpal.entries) /
sizeof(destpal.entries[0]);
1286 for (fl::u16 i = 0; i < dest_size; ++i) {
1287 destpal[
static_cast<fl::u8>(i)] =
1326void SetupPartyColors(CRGBPalette16& pal)
1335 if (maxChanges == 0) {
1343 p1 = (
fl::u8 *)current.entries;
1344 p2 = (
fl::u8 *)target.entries;
1346 const fl::u8 totalChannels =
sizeof(CRGBPalette16);
1347 for (
fl::u8 i = 0; i < totalChannels; ++i) {
1349 if (p1[i] == p2[i]) {
1354 if (p1[i] < p2[i]) {
1361 if (p1[i] > p2[i]) {
1364 if (p1[i] > p2[i]) {
1370 if (changes >= maxChanges) {
1383 constexpr fl::s16x16 inv_255_fp(1.0f / 255.0f);
1389 const fl::u32 scaled =
1390 (
static_cast<fl::u32
>(r.
raw()) * 255u + 0x8000u) >> 16;
1426 for (fl::u16 i = 0; i < count; ++i) {
1433 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_NO_EXCEPT
static FASTLED_FORCE_INLINE s16x16 pow(s16x16 base, s16x16 exp) FL_NO_EXCEPT
static constexpr FASTLED_FORCE_INLINE u8x8 from_raw(u16 raw) FL_NO_EXCEPT
@ 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_NO_EXCEPT
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) FL_NO_EXCEPT
Map from one full-range 8-bit value into a narrower range of 8-bit values, possibly a range of hues.
fl::u16 scale_hd_channel(fl::u16 channel, fl::u8x8 scale) FL_NO_EXCEPT
fl::u16 lerp_channel_to_hd(fl::u8 a, fl::u8 b, fl::u16 frac, fl::u32 segment_size) FL_NO_EXCEPT
CRGB16 ColorFromPaletteHDImpl(const Reader &reader, fl::u16 index, fl::u8x8 brightness, TBlendType blendType) FL_NO_EXCEPT
CRGB oklabToRgb(const Oklab &lab) FL_NO_EXCEPT
fl::u16 promote_channel_to_hd(fl::u8 channel) FL_NO_EXCEPT
float signedCubeRoot(float value) FL_NO_EXCEPT
CRGB16 promote_rgb_to_hd(const CRGB &rgb) FL_NO_EXCEPT
void scale_rgb_hd(CRGB16 &rgb, fl::u8x8 brightness) FL_NO_EXCEPT
fl::u8 channelFromFloat(float value) FL_NO_EXCEPT
Oklab rgbToOklab(const CRGB &rgb) FL_NO_EXCEPT
void UpscalePaletteInterpolated(const TSrcPalette &srcpal, TDestPalette &destpal) FL_NO_EXCEPT
void UpscalePaletteRepeat(const TSrcPalette &srcpal, TDestPalette &destpal) FL_NO_EXCEPT
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.
u8 u8 fract8 blur_amount FL_NO_EXCEPT
void fadeUsingColor(CRGB *leds, fl::u16 numLeds, const CRGB &colormask) FL_NO_EXCEPT
constexpr int type_rank< T >::value
CRGB16 ColorFromPaletteHD(const CRGBPalette32 &pal, fl::u16 index, fl::u8x8 brightness, TBlendType blendType) FL_NO_EXCEPT
constexpr u32 gamma(float g) FL_NO_EXCEPT
constexpr enable_if< is_fixed_point< T >::value, T >::type clamp(T x, T lo, T hi) FL_NO_EXCEPT
void fadeToBlackBy(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy) FL_NO_EXCEPT
void fade_raw(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy) FL_NO_EXCEPT
u8 fract8
Fixed-Point Fractional Types.
CRGB ColorFromPaletteExtended(const CRGBPalette32 &pal, fl::u16 index, fl::u8 brightness, TBlendType blendType) FL_NO_EXCEPT
fl::u8 applyGamma_video(fl::u8 brightness, float gamma) FL_NO_EXCEPT
void nscale8(CRGB *leds, fl::u16 num_leds, fl::u8 scale) FL_NO_EXCEPT
void nscale8_video(CRGB *leds, fl::u16 num_leds, fl::u8 scale) FL_NO_EXCEPT
void fade_video(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy) FL_NO_EXCEPT
CRGB blend(const CRGB &p1, const CRGB &p2, fract8 amountOfP2) FL_NO_EXCEPT
CRGB & napplyGamma_video(CRGB &rgb, float gamma) FL_NO_EXCEPT
expected< T, E > result
Alias for expected (Rust-style naming)
fl::u8 lsrX4(fl::u8 dividend) FL_NO_EXCEPT
Helper function to divide a number by 16, aka four logical shift right (LSR)'s.
CRGB & nblend(CRGB &existing, const CRGB &overlay, fract8 amountOfOverlay) FL_NO_EXCEPT
void UpscalePalette(const class CRGBPalette16 &srcpal16, class CRGBPalette256 &destpal256) FL_NO_EXCEPT
CRGB HeatColor(fl::u8 temperature) FL_NO_EXCEPT
CRGB ColorFromPalette(const CRGBPalette16 &pal, fl::u8 index, fl::u8 brightness, TBlendType blendType) FL_NO_EXCEPT
float roundf(float value) FL_NO_EXCEPT
void nblendPaletteTowardPalette(CRGBPalette16 ¤t, CRGBPalette16 &target, fl::u8 maxChanges) FL_NO_EXCEPT
float powf(float base, float exponent) FL_NO_EXCEPT
void fadeLightBy(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy) FL_NO_EXCEPT
CRGB blend_oklab(const CRGB &p1, const CRGB &p2, fract8 amountOfP2) FL_NO_EXCEPT
constexpr enable_if< is_fixed_point< T >::value, T >::type abs(T x) FL_NO_EXCEPT
Base definition for an LED controller.
Representation of an 8-bit RGB pixel (Red, Green, Blue)
CRGB read(fl::u8 index) const FL_NO_EXCEPT
fl::span< const fl::u32, Size > entries
fl::span< const CRGB, Size > entries
CRGB read(fl::u8 index) const FL_NO_EXCEPT