| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file crgb.h | ||
| 2 | /// Defines the red, green, and blue (RGB) pixel struct | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <stdint.h> | ||
| 7 | |||
| 8 | #include "chsv.h" | ||
| 9 | #include "fl/namespace.h" | ||
| 10 | #include "color.h" | ||
| 11 | #include "lib8tion/types.h" | ||
| 12 | #include "fl/force_inline.h" | ||
| 13 | //#include "fl/template_magic.h" | ||
| 14 | |||
| 15 | |||
| 16 | FASTLED_NAMESPACE_BEGIN | ||
| 17 | |||
| 18 | // Whether to allow HD_COLOR_MIXING | ||
| 19 | #ifndef FASTLED_HD_COLOR_MIXING | ||
| 20 | #ifdef __AVR__ | ||
| 21 | // Saves some memory on these constrained devices. | ||
| 22 | #define FASTLED_HD_COLOR_MIXING 0 | ||
| 23 | #else | ||
| 24 | #define FASTLED_HD_COLOR_MIXING 1 | ||
| 25 | #endif // __AVR__ | ||
| 26 | #endif // FASTLED_HD_COLOR_MIXING | ||
| 27 | |||
| 28 | |||
| 29 | struct CRGB; | ||
| 30 | |||
| 31 | /// @defgroup PixelTypes Pixel Data Types (CRGB/CHSV) | ||
| 32 | /// @brief Structs that hold pixel color data | ||
| 33 | /// @{ | ||
| 34 | |||
| 35 | /// Forward declaration of hsv2rgb_rainbow here, | ||
| 36 | /// to avoid circular dependencies. | ||
| 37 | /// | ||
| 38 | /// Convert an HSV value to RGB using a visually balanced rainbow. | ||
| 39 | /// This "rainbow" yields better yellow and orange than a straight | ||
| 40 | /// mathematical "spectrum". | ||
| 41 | /// | ||
| 42 | ///  | ||
| 43 | /// | ||
| 44 | /// @param hsv CHSV struct to convert to RGB. Max hue supported is HUE_MAX_RAINBOW | ||
| 45 | /// @param rgb CRGB struct to store the result of the conversion (will be modified) | ||
| 46 | void hsv2rgb_rainbow( const struct CHSV& hsv, struct CRGB& rgb); | ||
| 47 | |||
| 48 | |||
| 49 | /// Representation of an RGB pixel (Red, Green, Blue) | ||
| 50 | struct CRGB { | ||
| 51 | union { | ||
| 52 | struct { | ||
| 53 | union { | ||
| 54 | uint8_t r; ///< Red channel value | ||
| 55 | uint8_t red; ///< @copydoc r | ||
| 56 | }; | ||
| 57 | union { | ||
| 58 | uint8_t g; ///< Green channel value | ||
| 59 | uint8_t green; ///< @copydoc g | ||
| 60 | }; | ||
| 61 | union { | ||
| 62 | uint8_t b; ///< Blue channel value | ||
| 63 | uint8_t blue; ///< @copydoc b | ||
| 64 | }; | ||
| 65 | }; | ||
| 66 | /// Access the red, green, and blue data as an array. | ||
| 67 | /// Where: | ||
| 68 | /// * `raw[0]` is the red value | ||
| 69 | /// * `raw[1]` is the green value | ||
| 70 | /// * `raw[2]` is the blue value | ||
| 71 | uint8_t raw[3]; | ||
| 72 | }; | ||
| 73 | |||
| 74 | static CRGB blend(const CRGB& p1, const CRGB& p2, fract8 amountOfP2); | ||
| 75 | static CRGB blendAlphaMaxChannel(const CRGB& upper, const CRGB& lower); | ||
| 76 | |||
| 77 | /// Array access operator to index into the CRGB object | ||
| 78 | /// @param x the index to retrieve (0-2) | ||
| 79 | /// @returns the CRGB::raw value for the given index | ||
| 80 | FASTLED_FORCE_INLINE uint8_t& operator[] (uint8_t x) | ||
| 81 | { | ||
| 82 | 23133 | return raw[x]; | |
| 83 | } | ||
| 84 | |||
| 85 | /// Array access operator to index into the CRGB object | ||
| 86 | /// @param x the index to retrieve (0-2) | ||
| 87 | /// @returns the CRGB::raw value for the given index | ||
| 88 | FASTLED_FORCE_INLINE const uint8_t& operator[] (uint8_t x) const | ||
| 89 | { | ||
| 90 | return raw[x]; | ||
| 91 | } | ||
| 92 | |||
| 93 | /// Default constructor | ||
| 94 | /// @warning Default values are UNITIALIZED! | ||
| 95 | FASTLED_FORCE_INLINE CRGB() = default; | ||
| 96 | |||
| 97 | /// Allow construction from red, green, and blue | ||
| 98 | /// @param ir input red value | ||
| 99 | /// @param ig input green value | ||
| 100 | /// @param ib input blue value | ||
| 101 | 308897 | constexpr CRGB(uint8_t ir, uint8_t ig, uint8_t ib) noexcept | |
| 102 | 308897 | : r(ir), g(ig), b(ib) | |
| 103 | { | ||
| 104 | 308897 | } | |
| 105 | |||
| 106 | /// Allow construction from 32-bit (really 24-bit) bit 0xRRGGBB color code | ||
| 107 | /// @param colorcode a packed 24 bit color code | ||
| 108 | 225821 | constexpr CRGB(uint32_t colorcode) noexcept | |
| 109 | 225821 | : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) | |
| 110 | { | ||
| 111 | 225821 | } | |
| 112 | |||
| 113 | constexpr uint32_t as_uint32_t() const noexcept { | ||
| 114 | return uint32_t(0xff000000) | | ||
| 115 | (uint32_t{r} << 16) | | ||
| 116 | (uint32_t{g} << 8) | | ||
| 117 | uint32_t{b}; | ||
| 118 | } | ||
| 119 | |||
| 120 | /// Allow construction from a LEDColorCorrection enum | ||
| 121 | /// @param colorcode an LEDColorCorrect enumeration value | ||
| 122 | constexpr CRGB(LEDColorCorrection colorcode) noexcept | ||
| 123 | : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) | ||
| 124 | { | ||
| 125 | } | ||
| 126 | |||
| 127 | /// Allow construction from a ColorTemperature enum | ||
| 128 | /// @param colorcode an ColorTemperature enumeration value | ||
| 129 | constexpr CRGB(ColorTemperature colorcode) noexcept | ||
| 130 | : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) | ||
| 131 | { | ||
| 132 | } | ||
| 133 | |||
| 134 | /// Allow copy construction | ||
| 135 | FASTLED_FORCE_INLINE CRGB(const CRGB& rhs) = default; | ||
| 136 | |||
| 137 | /// Allow construction from a CHSV color | ||
| 138 | FASTLED_FORCE_INLINE CRGB(const CHSV& rhs) | ||
| 139 | 17565 | { | |
| 140 |
11/24✓ Branch 0 taken 2212 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 23 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 23 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 23 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 23 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 23 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 31 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 7511 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 184 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 7511 times.
✗ Branch 23 not taken.
|
17565 | hsv2rgb_rainbow( rhs, *this); |
| 141 | 17565 | } | |
| 142 | |||
| 143 | /// Allow assignment from one RGB struct to another | ||
| 144 | FASTLED_FORCE_INLINE CRGB& operator= (const CRGB& rhs) = default; | ||
| 145 | |||
| 146 | /// Allow assignment from 32-bit (really 24-bit) 0xRRGGBB color code | ||
| 147 | /// @param colorcode a packed 24 bit color code | ||
| 148 | FASTLED_FORCE_INLINE CRGB& operator= (const uint32_t colorcode) | ||
| 149 | { | ||
| 150 | 194708 | r = (colorcode >> 16) & 0xFF; | |
| 151 | 194708 | g = (colorcode >> 8) & 0xFF; | |
| 152 | 194708 | b = (colorcode >> 0) & 0xFF; | |
| 153 | 194708 | return *this; | |
| 154 | } | ||
| 155 | |||
| 156 | /// Allow assignment from red, green, and blue | ||
| 157 | /// @param nr new red value | ||
| 158 | /// @param ng new green value | ||
| 159 | /// @param nb new blue value | ||
| 160 | FASTLED_FORCE_INLINE CRGB& setRGB (uint8_t nr, uint8_t ng, uint8_t nb) | ||
| 161 | { | ||
| 162 | r = nr; | ||
| 163 | g = ng; | ||
| 164 | b = nb; | ||
| 165 | return *this; | ||
| 166 | } | ||
| 167 | |||
| 168 | /// Allow assignment from hue, saturation, and value | ||
| 169 | /// @param hue color hue | ||
| 170 | /// @param sat color saturation | ||
| 171 | /// @param val color value (brightness) | ||
| 172 | FASTLED_FORCE_INLINE CRGB& setHSV (uint8_t hue, uint8_t sat, uint8_t val) | ||
| 173 | { | ||
| 174 | hsv2rgb_rainbow( CHSV(hue, sat, val), *this); | ||
| 175 | return *this; | ||
| 176 | } | ||
| 177 | |||
| 178 | /// Allow assignment from just a hue. | ||
| 179 | /// Saturation and value (brightness) are set automatically to max. | ||
| 180 | /// @param hue color hue | ||
| 181 | FASTLED_FORCE_INLINE CRGB& setHue (uint8_t hue) | ||
| 182 | { | ||
| 183 | hsv2rgb_rainbow( CHSV(hue, 255, 255), *this); | ||
| 184 | return *this; | ||
| 185 | } | ||
| 186 | |||
| 187 | /// Allow assignment from HSV color | ||
| 188 | FASTLED_FORCE_INLINE CRGB& operator= (const CHSV& rhs) | ||
| 189 | { | ||
| 190 |
3/6✓ Branch 0 taken 84546 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 98 times.
✗ Branch 5 not taken.
|
84661 | hsv2rgb_rainbow( rhs, *this); |
| 191 | 84661 | return *this; | |
| 192 | } | ||
| 193 | |||
| 194 | /// Allow assignment from 32-bit (really 24-bit) 0xRRGGBB color code | ||
| 195 | /// @param colorcode a packed 24 bit color code | ||
| 196 | FASTLED_FORCE_INLINE CRGB& setColorCode (uint32_t colorcode) | ||
| 197 | { | ||
| 198 | r = (colorcode >> 16) & 0xFF; | ||
| 199 | g = (colorcode >> 8) & 0xFF; | ||
| 200 | b = (colorcode >> 0) & 0xFF; | ||
| 201 | return *this; | ||
| 202 | } | ||
| 203 | |||
| 204 | |||
| 205 | /// Add one CRGB to another, saturating at 0xFF for each channel | ||
| 206 | CRGB& operator+= (const CRGB& rhs); | ||
| 207 | |||
| 208 | /// Add a constant to each channel, saturating at 0xFF. | ||
| 209 | /// @note This is NOT an operator+= overload because the compiler | ||
| 210 | /// can't usefully decide when it's being passed a 32-bit | ||
| 211 | /// constant (e.g. CRGB::Red) and an 8-bit one (CRGB::Blue) | ||
| 212 | FASTLED_FORCE_INLINE CRGB& addToRGB (uint8_t d); | ||
| 213 | |||
| 214 | /// Subtract one CRGB from another, saturating at 0x00 for each channel | ||
| 215 | FASTLED_FORCE_INLINE CRGB& operator-= (const CRGB& rhs); | ||
| 216 | |||
| 217 | /// Subtract a constant from each channel, saturating at 0x00. | ||
| 218 | /// @note This is NOT an operator+= overload because the compiler | ||
| 219 | /// can't usefully decide when it's being passed a 32-bit | ||
| 220 | /// constant (e.g. CRGB::Red) and an 8-bit one (CRGB::Blue) | ||
| 221 | FASTLED_FORCE_INLINE CRGB& subtractFromRGB(uint8_t d); | ||
| 222 | |||
| 223 | /// Subtract a constant of '1' from each channel, saturating at 0x00 | ||
| 224 | FASTLED_FORCE_INLINE CRGB& operator-- (); | ||
| 225 | |||
| 226 | /// @copydoc operator-- | ||
| 227 | FASTLED_FORCE_INLINE CRGB operator-- (int ); | ||
| 228 | |||
| 229 | /// Add a constant of '1' from each channel, saturating at 0xFF | ||
| 230 | FASTLED_FORCE_INLINE CRGB& operator++ (); | ||
| 231 | |||
| 232 | /// @copydoc operator++ | ||
| 233 | FASTLED_FORCE_INLINE CRGB operator++ (int ); | ||
| 234 | |||
| 235 | /// Divide each of the channels by a constant | ||
| 236 | FASTLED_FORCE_INLINE CRGB& operator/= (uint8_t d ) | ||
| 237 | { | ||
| 238 | r /= d; | ||
| 239 | g /= d; | ||
| 240 | b /= d; | ||
| 241 | return *this; | ||
| 242 | } | ||
| 243 | |||
| 244 | /// Right shift each of the channels by a constant | ||
| 245 | FASTLED_FORCE_INLINE CRGB& operator>>= (uint8_t d) | ||
| 246 | { | ||
| 247 | ✗ | r >>= d; | |
| 248 | ✗ | g >>= d; | |
| 249 | ✗ | b >>= d; | |
| 250 | ✗ | return *this; | |
| 251 | } | ||
| 252 | |||
| 253 | /// Multiply each of the channels by a constant, | ||
| 254 | /// saturating each channel at 0xFF. | ||
| 255 | FASTLED_FORCE_INLINE CRGB& operator*= (uint8_t d); | ||
| 256 | |||
| 257 | /// Scale down a RGB to N/256ths of it's current brightness using | ||
| 258 | /// "video" dimming rules. "Video" dimming rules means that unless the scale factor | ||
| 259 | /// is ZERO each channel is guaranteed NOT to dim down to zero. If it's already | ||
| 260 | /// nonzero, it'll stay nonzero, even if that means the hue shifts a little | ||
| 261 | /// at low brightness levels. | ||
| 262 | /// @see nscale8x3_video | ||
| 263 | FASTLED_FORCE_INLINE CRGB& nscale8_video (uint8_t scaledown); | ||
| 264 | |||
| 265 | /// %= is a synonym for nscale8_video(). Think of it is scaling down | ||
| 266 | /// by "a percentage" | ||
| 267 | FASTLED_FORCE_INLINE CRGB& operator%= (uint8_t scaledown); | ||
| 268 | |||
| 269 | /// fadeLightBy is a synonym for nscale8_video(), as a fade instead of a scale | ||
| 270 | /// @param fadefactor the amount to fade, sent to nscale8_video() as (255 - fadefactor) | ||
| 271 | FASTLED_FORCE_INLINE CRGB& fadeLightBy (uint8_t fadefactor ); | ||
| 272 | |||
| 273 | /// Scale down a RGB to N/256ths of its current brightness, using | ||
| 274 | /// "plain math" dimming rules. "Plain math" dimming rules means that the low light | ||
| 275 | /// levels may dim all the way to 100% black. | ||
| 276 | /// @see nscale8x3 | ||
| 277 | CRGB& nscale8 (uint8_t scaledown ); | ||
| 278 | |||
| 279 | /// Scale down a RGB to N/256ths of its current brightness, using | ||
| 280 | /// "plain math" dimming rules. "Plain math" dimming rules means that the low light | ||
| 281 | /// levels may dim all the way to 100% black. | ||
| 282 | /// @see ::scale8 | ||
| 283 | FASTLED_FORCE_INLINE CRGB& nscale8 (const CRGB & scaledown ); | ||
| 284 | |||
| 285 | constexpr CRGB nscale8_constexpr (const CRGB scaledown ) const; | ||
| 286 | |||
| 287 | |||
| 288 | /// Return a CRGB object that is a scaled down version of this object | ||
| 289 | FASTLED_FORCE_INLINE CRGB scale8 (uint8_t scaledown ) const; | ||
| 290 | |||
| 291 | /// Return a CRGB object that is a scaled down version of this object | ||
| 292 | FASTLED_FORCE_INLINE CRGB scale8 (const CRGB & scaledown ) const; | ||
| 293 | |||
| 294 | /// fadeToBlackBy is a synonym for nscale8(), as a fade instead of a scale | ||
| 295 | /// @param fadefactor the amount to fade, sent to nscale8() as (255 - fadefactor) | ||
| 296 | CRGB& fadeToBlackBy (uint8_t fadefactor ); | ||
| 297 | |||
| 298 | /// "or" operator brings each channel up to the higher of the two values | ||
| 299 | FASTLED_FORCE_INLINE CRGB& operator|= (const CRGB& rhs ) | ||
| 300 | { | ||
| 301 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 7511 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 24 times.
|
7695 | if( rhs.r > r) r = rhs.r; |
| 302 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 7511 times.
✓ Branch 2 taken 154 times.
✓ Branch 3 taken 30 times.
|
7695 | if( rhs.g > g) g = rhs.g; |
| 303 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 7511 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 88 times.
|
7695 | if( rhs.b > b) b = rhs.b; |
| 304 | 7695 | return *this; | |
| 305 | } | ||
| 306 | |||
| 307 | /// @copydoc operator|= | ||
| 308 | FASTLED_FORCE_INLINE CRGB& operator|= (uint8_t d ) | ||
| 309 | { | ||
| 310 | if( d > r) r = d; | ||
| 311 | if( d > g) g = d; | ||
| 312 | if( d > b) b = d; | ||
| 313 | return *this; | ||
| 314 | } | ||
| 315 | |||
| 316 | /// "and" operator brings each channel down to the lower of the two values | ||
| 317 | FASTLED_FORCE_INLINE CRGB& operator&= (const CRGB& rhs ) | ||
| 318 | { | ||
| 319 | if( rhs.r < r) r = rhs.r; | ||
| 320 | if( rhs.g < g) g = rhs.g; | ||
| 321 | if( rhs.b < b) b = rhs.b; | ||
| 322 | return *this; | ||
| 323 | } | ||
| 324 | |||
| 325 | /// @copydoc operator&= | ||
| 326 | FASTLED_FORCE_INLINE CRGB& operator&= (uint8_t d ) | ||
| 327 | { | ||
| 328 | if( d < r) r = d; | ||
| 329 | if( d < g) g = d; | ||
| 330 | if( d < b) b = d; | ||
| 331 | return *this; | ||
| 332 | } | ||
| 333 | |||
| 334 | /// This allows testing a CRGB for zero-ness | ||
| 335 | 136475 | constexpr explicit operator bool() const | |
| 336 | { | ||
| 337 |
6/6✓ Branch 0 taken 118923 times.
✓ Branch 1 taken 17552 times.
✓ Branch 2 taken 118289 times.
✓ Branch 3 taken 634 times.
✓ Branch 4 taken 14192 times.
✓ Branch 5 taken 104097 times.
|
136475 | return r || g || b; |
| 338 | } | ||
| 339 | |||
| 340 | /// Converts a CRGB to a 32-bit color having an alpha of 255. | ||
| 341 | 3898 | constexpr explicit operator uint32_t() const | |
| 342 | { | ||
| 343 | return uint32_t(0xff000000) | | ||
| 344 | 3898 | (uint32_t{r} << 16) | | |
| 345 | 3898 | (uint32_t{g} << 8) | | |
| 346 | 3898 | uint32_t{b}; | |
| 347 | } | ||
| 348 | |||
| 349 | /// Invert each channel | ||
| 350 | constexpr CRGB operator-() const | ||
| 351 | { | ||
| 352 | return CRGB(255 - r, 255 - g, 255 - b); | ||
| 353 | } | ||
| 354 | |||
| 355 | #if (defined SmartMatrix_h || defined SmartMatrix3_h) | ||
| 356 | /// Convert to an rgb24 object, used with the SmartMatrix library | ||
| 357 | /// @see https://github.com/pixelmatix/SmartMatrix | ||
| 358 | operator rgb24() const { | ||
| 359 | rgb24 ret; | ||
| 360 | ret.red = r; | ||
| 361 | ret.green = g; | ||
| 362 | ret.blue = b; | ||
| 363 | return ret; | ||
| 364 | } | ||
| 365 | #endif | ||
| 366 | |||
| 367 | /// Get the "luma" of a CRGB object. In other words, roughly how much | ||
| 368 | /// light the CRGB pixel is putting out (from 0 to 255). | ||
| 369 | uint8_t getLuma() const; | ||
| 370 | |||
| 371 | |||
| 372 | |||
| 373 | /// Get the average of the R, G, and B values | ||
| 374 | FASTLED_FORCE_INLINE uint8_t getAverageLight() const; | ||
| 375 | |||
| 376 | /// Maximize the brightness of this CRGB object. | ||
| 377 | /// This makes the individual color channels as bright as possible | ||
| 378 | /// while keeping the same value differences between channels. | ||
| 379 | /// @note This does not keep the same ratios between channels, | ||
| 380 | /// just the same difference in absolute values. | ||
| 381 | FASTLED_FORCE_INLINE void maximizeBrightness( uint8_t limit = 255 ) { | ||
| 382 | uint8_t max = red; | ||
| 383 | if( green > max) max = green; | ||
| 384 | if( blue > max) max = blue; | ||
| 385 | |||
| 386 | // stop div/0 when color is black | ||
| 387 | if(max > 0) { | ||
| 388 | uint16_t factor = ((uint16_t)(limit) * 256) / max; | ||
| 389 | red = (red * factor) / 256; | ||
| 390 | green = (green * factor) / 256; | ||
| 391 | blue = (blue * factor) / 256; | ||
| 392 | } | ||
| 393 | } | ||
| 394 | |||
| 395 | /// Calculates the combined color adjustment to the LEDs at a given scale, color correction, and color temperature | ||
| 396 | /// @param scale the scale value for the RGB data (i.e. brightness) | ||
| 397 | /// @param colorCorrection color correction to apply | ||
| 398 | /// @param colorTemperature color temperature to apply | ||
| 399 | /// @returns a CRGB object representing the adjustment, including color correction and color temperature | ||
| 400 | static CRGB computeAdjustment(uint8_t scale, const CRGB & colorCorrection, const CRGB & colorTemperature); | ||
| 401 | |||
| 402 | /// Return a new CRGB object after performing a linear interpolation between this object and the passed in object | ||
| 403 | CRGB lerp8( const CRGB& other, fract8 amountOf2) const; | ||
| 404 | |||
| 405 | /// @copydoc lerp8 | ||
| 406 | FASTLED_FORCE_INLINE CRGB lerp16( const CRGB& other, fract16 frac) const; | ||
| 407 | /// Returns 0 or 1, depending on the lowest bit of the sum of the color components. | ||
| 408 | FASTLED_FORCE_INLINE uint8_t getParity() | ||
| 409 | { | ||
| 410 | uint8_t sum = r + g + b; | ||
| 411 | return (sum & 0x01); | ||
| 412 | } | ||
| 413 | |||
| 414 | /// Adjusts the color in the smallest way possible | ||
| 415 | /// so that the parity of the coloris now the desired value. | ||
| 416 | /// This allows you to "hide" one bit of information in the color. | ||
| 417 | /// | ||
| 418 | /// Ideally, we find one color channel which already | ||
| 419 | /// has data in it, and modify just that channel by one. | ||
| 420 | /// We don't want to light up a channel that's black | ||
| 421 | /// if we can avoid it, and if the pixel is 'grayscale', | ||
| 422 | /// (meaning that R==G==B), we modify all three channels | ||
| 423 | /// at once, to preserve the neutral hue. | ||
| 424 | /// | ||
| 425 | /// There's no such thing as a free lunch; in many cases | ||
| 426 | /// this "hidden bit" may actually be visible, but this | ||
| 427 | /// code makes reasonable efforts to hide it as much | ||
| 428 | /// as is reasonably possible. | ||
| 429 | /// | ||
| 430 | /// Also, an effort is made to make it such that | ||
| 431 | /// repeatedly setting the parity to different values | ||
| 432 | /// will not cause the color to "drift". Toggling | ||
| 433 | /// the parity twice should generally result in the | ||
| 434 | /// original color again. | ||
| 435 | /// | ||
| 436 | FASTLED_FORCE_INLINE void setParity( uint8_t parity) | ||
| 437 | { | ||
| 438 | uint8_t curparity = getParity(); | ||
| 439 | |||
| 440 | if( parity == curparity) return; | ||
| 441 | |||
| 442 | if( parity ) { | ||
| 443 | // going 'up' | ||
| 444 | if( (b > 0) && (b < 255)) { | ||
| 445 | if( r == g && g == b) { | ||
| 446 | ++r; | ||
| 447 | ++g; | ||
| 448 | } | ||
| 449 | ++b; | ||
| 450 | } else if( (r > 0) && (r < 255)) { | ||
| 451 | ++r; | ||
| 452 | } else if( (g > 0) && (g < 255)) { | ||
| 453 | ++g; | ||
| 454 | } else { | ||
| 455 | if( r == g && g == b) { | ||
| 456 | r ^= 0x01; | ||
| 457 | g ^= 0x01; | ||
| 458 | } | ||
| 459 | b ^= 0x01; | ||
| 460 | } | ||
| 461 | } else { | ||
| 462 | // going 'down' | ||
| 463 | if( b > 1) { | ||
| 464 | if( r == g && g == b) { | ||
| 465 | --r; | ||
| 466 | --g; | ||
| 467 | } | ||
| 468 | --b; | ||
| 469 | } else if( g > 1) { | ||
| 470 | --g; | ||
| 471 | } else if( r > 1) { | ||
| 472 | --r; | ||
| 473 | } else { | ||
| 474 | if( r == g && g == b) { | ||
| 475 | r ^= 0x01; | ||
| 476 | g ^= 0x01; | ||
| 477 | } | ||
| 478 | b ^= 0x01; | ||
| 479 | } | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 483 | /// Predefined RGB colors | ||
| 484 | typedef enum { | ||
| 485 | AliceBlue=0xF0F8FF, ///< @htmlcolorblock{F0F8FF} | ||
| 486 | Amethyst=0x9966CC, ///< @htmlcolorblock{9966CC} | ||
| 487 | AntiqueWhite=0xFAEBD7, ///< @htmlcolorblock{FAEBD7} | ||
| 488 | Aqua=0x00FFFF, ///< @htmlcolorblock{00FFFF} | ||
| 489 | Aquamarine=0x7FFFD4, ///< @htmlcolorblock{7FFFD4} | ||
| 490 | Azure=0xF0FFFF, ///< @htmlcolorblock{F0FFFF} | ||
| 491 | Beige=0xF5F5DC, ///< @htmlcolorblock{F5F5DC} | ||
| 492 | Bisque=0xFFE4C4, ///< @htmlcolorblock{FFE4C4} | ||
| 493 | Black=0x000000, ///< @htmlcolorblock{000000} | ||
| 494 | BlanchedAlmond=0xFFEBCD, ///< @htmlcolorblock{FFEBCD} | ||
| 495 | Blue=0x0000FF, ///< @htmlcolorblock{0000FF} | ||
| 496 | BlueViolet=0x8A2BE2, ///< @htmlcolorblock{8A2BE2} | ||
| 497 | Brown=0xA52A2A, ///< @htmlcolorblock{A52A2A} | ||
| 498 | BurlyWood=0xDEB887, ///< @htmlcolorblock{DEB887} | ||
| 499 | CadetBlue=0x5F9EA0, ///< @htmlcolorblock{5F9EA0} | ||
| 500 | Chartreuse=0x7FFF00, ///< @htmlcolorblock{7FFF00} | ||
| 501 | Chocolate=0xD2691E, ///< @htmlcolorblock{D2691E} | ||
| 502 | Coral=0xFF7F50, ///< @htmlcolorblock{FF7F50} | ||
| 503 | CornflowerBlue=0x6495ED, ///< @htmlcolorblock{6495ED} | ||
| 504 | Cornsilk=0xFFF8DC, ///< @htmlcolorblock{FFF8DC} | ||
| 505 | Crimson=0xDC143C, ///< @htmlcolorblock{DC143C} | ||
| 506 | Cyan=0x00FFFF, ///< @htmlcolorblock{00FFFF} | ||
| 507 | DarkBlue=0x00008B, ///< @htmlcolorblock{00008B} | ||
| 508 | DarkCyan=0x008B8B, ///< @htmlcolorblock{008B8B} | ||
| 509 | DarkGoldenrod=0xB8860B, ///< @htmlcolorblock{B8860B} | ||
| 510 | DarkGray=0xA9A9A9, ///< @htmlcolorblock{A9A9A9} | ||
| 511 | DarkGrey=0xA9A9A9, ///< @htmlcolorblock{A9A9A9} | ||
| 512 | DarkGreen=0x006400, ///< @htmlcolorblock{006400} | ||
| 513 | DarkKhaki=0xBDB76B, ///< @htmlcolorblock{BDB76B} | ||
| 514 | DarkMagenta=0x8B008B, ///< @htmlcolorblock{8B008B} | ||
| 515 | DarkOliveGreen=0x556B2F, ///< @htmlcolorblock{556B2F} | ||
| 516 | DarkOrange=0xFF8C00, ///< @htmlcolorblock{FF8C00} | ||
| 517 | DarkOrchid=0x9932CC, ///< @htmlcolorblock{9932CC} | ||
| 518 | DarkRed=0x8B0000, ///< @htmlcolorblock{8B0000} | ||
| 519 | DarkSalmon=0xE9967A, ///< @htmlcolorblock{E9967A} | ||
| 520 | DarkSeaGreen=0x8FBC8F, ///< @htmlcolorblock{8FBC8F} | ||
| 521 | DarkSlateBlue=0x483D8B, ///< @htmlcolorblock{483D8B} | ||
| 522 | DarkSlateGray=0x2F4F4F, ///< @htmlcolorblock{2F4F4F} | ||
| 523 | DarkSlateGrey=0x2F4F4F, ///< @htmlcolorblock{2F4F4F} | ||
| 524 | DarkTurquoise=0x00CED1, ///< @htmlcolorblock{00CED1} | ||
| 525 | DarkViolet=0x9400D3, ///< @htmlcolorblock{9400D3} | ||
| 526 | DeepPink=0xFF1493, ///< @htmlcolorblock{FF1493} | ||
| 527 | DeepSkyBlue=0x00BFFF, ///< @htmlcolorblock{00BFFF} | ||
| 528 | DimGray=0x696969, ///< @htmlcolorblock{696969} | ||
| 529 | DimGrey=0x696969, ///< @htmlcolorblock{696969} | ||
| 530 | DodgerBlue=0x1E90FF, ///< @htmlcolorblock{1E90FF} | ||
| 531 | FireBrick=0xB22222, ///< @htmlcolorblock{B22222} | ||
| 532 | FloralWhite=0xFFFAF0, ///< @htmlcolorblock{FFFAF0} | ||
| 533 | ForestGreen=0x228B22, ///< @htmlcolorblock{228B22} | ||
| 534 | Fuchsia=0xFF00FF, ///< @htmlcolorblock{FF00FF} | ||
| 535 | Gainsboro=0xDCDCDC, ///< @htmlcolorblock{DCDCDC} | ||
| 536 | GhostWhite=0xF8F8FF, ///< @htmlcolorblock{F8F8FF} | ||
| 537 | Gold=0xFFD700, ///< @htmlcolorblock{FFD700} | ||
| 538 | Goldenrod=0xDAA520, ///< @htmlcolorblock{DAA520} | ||
| 539 | Gray=0x808080, ///< @htmlcolorblock{808080} | ||
| 540 | Grey=0x808080, ///< @htmlcolorblock{808080} | ||
| 541 | Green=0x008000, ///< @htmlcolorblock{008000} | ||
| 542 | GreenYellow=0xADFF2F, ///< @htmlcolorblock{ADFF2F} | ||
| 543 | Honeydew=0xF0FFF0, ///< @htmlcolorblock{F0FFF0} | ||
| 544 | HotPink=0xFF69B4, ///< @htmlcolorblock{FF69B4} | ||
| 545 | IndianRed=0xCD5C5C, ///< @htmlcolorblock{CD5C5C} | ||
| 546 | Indigo=0x4B0082, ///< @htmlcolorblock{4B0082} | ||
| 547 | Ivory=0xFFFFF0, ///< @htmlcolorblock{FFFFF0} | ||
| 548 | Khaki=0xF0E68C, ///< @htmlcolorblock{F0E68C} | ||
| 549 | Lavender=0xE6E6FA, ///< @htmlcolorblock{E6E6FA} | ||
| 550 | LavenderBlush=0xFFF0F5, ///< @htmlcolorblock{FFF0F5} | ||
| 551 | LawnGreen=0x7CFC00, ///< @htmlcolorblock{7CFC00} | ||
| 552 | LemonChiffon=0xFFFACD, ///< @htmlcolorblock{FFFACD} | ||
| 553 | LightBlue=0xADD8E6, ///< @htmlcolorblock{ADD8E6} | ||
| 554 | LightCoral=0xF08080, ///< @htmlcolorblock{F08080} | ||
| 555 | LightCyan=0xE0FFFF, ///< @htmlcolorblock{E0FFFF} | ||
| 556 | LightGoldenrodYellow=0xFAFAD2, ///< @htmlcolorblock{FAFAD2} | ||
| 557 | LightGreen=0x90EE90, ///< @htmlcolorblock{90EE90} | ||
| 558 | LightGrey=0xD3D3D3, ///< @htmlcolorblock{D3D3D3} | ||
| 559 | LightPink=0xFFB6C1, ///< @htmlcolorblock{FFB6C1} | ||
| 560 | LightSalmon=0xFFA07A, ///< @htmlcolorblock{FFA07A} | ||
| 561 | LightSeaGreen=0x20B2AA, ///< @htmlcolorblock{20B2AA} | ||
| 562 | LightSkyBlue=0x87CEFA, ///< @htmlcolorblock{87CEFA} | ||
| 563 | LightSlateGray=0x778899, ///< @htmlcolorblock{778899} | ||
| 564 | LightSlateGrey=0x778899, ///< @htmlcolorblock{778899} | ||
| 565 | LightSteelBlue=0xB0C4DE, ///< @htmlcolorblock{B0C4DE} | ||
| 566 | LightYellow=0xFFFFE0, ///< @htmlcolorblock{FFFFE0} | ||
| 567 | Lime=0x00FF00, ///< @htmlcolorblock{00FF00} | ||
| 568 | LimeGreen=0x32CD32, ///< @htmlcolorblock{32CD32} | ||
| 569 | Linen=0xFAF0E6, ///< @htmlcolorblock{FAF0E6} | ||
| 570 | Magenta=0xFF00FF, ///< @htmlcolorblock{FF00FF} | ||
| 571 | Maroon=0x800000, ///< @htmlcolorblock{800000} | ||
| 572 | MediumAquamarine=0x66CDAA, ///< @htmlcolorblock{66CDAA} | ||
| 573 | MediumBlue=0x0000CD, ///< @htmlcolorblock{0000CD} | ||
| 574 | MediumOrchid=0xBA55D3, ///< @htmlcolorblock{BA55D3} | ||
| 575 | MediumPurple=0x9370DB, ///< @htmlcolorblock{9370DB} | ||
| 576 | MediumSeaGreen=0x3CB371, ///< @htmlcolorblock{3CB371} | ||
| 577 | MediumSlateBlue=0x7B68EE, ///< @htmlcolorblock{7B68EE} | ||
| 578 | MediumSpringGreen=0x00FA9A, ///< @htmlcolorblock{00FA9A} | ||
| 579 | MediumTurquoise=0x48D1CC, ///< @htmlcolorblock{48D1CC} | ||
| 580 | MediumVioletRed=0xC71585, ///< @htmlcolorblock{C71585} | ||
| 581 | MidnightBlue=0x191970, ///< @htmlcolorblock{191970} | ||
| 582 | MintCream=0xF5FFFA, ///< @htmlcolorblock{F5FFFA} | ||
| 583 | MistyRose=0xFFE4E1, ///< @htmlcolorblock{FFE4E1} | ||
| 584 | Moccasin=0xFFE4B5, ///< @htmlcolorblock{FFE4B5} | ||
| 585 | NavajoWhite=0xFFDEAD, ///< @htmlcolorblock{FFDEAD} | ||
| 586 | Navy=0x000080, ///< @htmlcolorblock{000080} | ||
| 587 | OldLace=0xFDF5E6, ///< @htmlcolorblock{FDF5E6} | ||
| 588 | Olive=0x808000, ///< @htmlcolorblock{808000} | ||
| 589 | OliveDrab=0x6B8E23, ///< @htmlcolorblock{6B8E23} | ||
| 590 | Orange=0xFFA500, ///< @htmlcolorblock{FFA500} | ||
| 591 | OrangeRed=0xFF4500, ///< @htmlcolorblock{FF4500} | ||
| 592 | Orchid=0xDA70D6, ///< @htmlcolorblock{DA70D6} | ||
| 593 | PaleGoldenrod=0xEEE8AA, ///< @htmlcolorblock{EEE8AA} | ||
| 594 | PaleGreen=0x98FB98, ///< @htmlcolorblock{98FB98} | ||
| 595 | PaleTurquoise=0xAFEEEE, ///< @htmlcolorblock{AFEEEE} | ||
| 596 | PaleVioletRed=0xDB7093, ///< @htmlcolorblock{DB7093} | ||
| 597 | PapayaWhip=0xFFEFD5, ///< @htmlcolorblock{FFEFD5} | ||
| 598 | PeachPuff=0xFFDAB9, ///< @htmlcolorblock{FFDAB9} | ||
| 599 | Peru=0xCD853F, ///< @htmlcolorblock{CD853F} | ||
| 600 | Pink=0xFFC0CB, ///< @htmlcolorblock{FFC0CB} | ||
| 601 | Plaid=0xCC5533, ///< @htmlcolorblock{CC5533} | ||
| 602 | Plum=0xDDA0DD, ///< @htmlcolorblock{DDA0DD} | ||
| 603 | PowderBlue=0xB0E0E6, ///< @htmlcolorblock{B0E0E6} | ||
| 604 | Purple=0x800080, ///< @htmlcolorblock{800080} | ||
| 605 | Red=0xFF0000, ///< @htmlcolorblock{FF0000} | ||
| 606 | RosyBrown=0xBC8F8F, ///< @htmlcolorblock{BC8F8F} | ||
| 607 | RoyalBlue=0x4169E1, ///< @htmlcolorblock{4169E1} | ||
| 608 | SaddleBrown=0x8B4513, ///< @htmlcolorblock{8B4513} | ||
| 609 | Salmon=0xFA8072, ///< @htmlcolorblock{FA8072} | ||
| 610 | SandyBrown=0xF4A460, ///< @htmlcolorblock{F4A460} | ||
| 611 | SeaGreen=0x2E8B57, ///< @htmlcolorblock{2E8B57} | ||
| 612 | Seashell=0xFFF5EE, ///< @htmlcolorblock{FFF5EE} | ||
| 613 | Sienna=0xA0522D, ///< @htmlcolorblock{A0522D} | ||
| 614 | Silver=0xC0C0C0, ///< @htmlcolorblock{C0C0C0} | ||
| 615 | SkyBlue=0x87CEEB, ///< @htmlcolorblock{87CEEB} | ||
| 616 | SlateBlue=0x6A5ACD, ///< @htmlcolorblock{6A5ACD} | ||
| 617 | SlateGray=0x708090, ///< @htmlcolorblock{708090} | ||
| 618 | SlateGrey=0x708090, ///< @htmlcolorblock{708090} | ||
| 619 | Snow=0xFFFAFA, ///< @htmlcolorblock{FFFAFA} | ||
| 620 | SpringGreen=0x00FF7F, ///< @htmlcolorblock{00FF7F} | ||
| 621 | SteelBlue=0x4682B4, ///< @htmlcolorblock{4682B4} | ||
| 622 | Tan=0xD2B48C, ///< @htmlcolorblock{D2B48C} | ||
| 623 | Teal=0x008080, ///< @htmlcolorblock{008080} | ||
| 624 | Thistle=0xD8BFD8, ///< @htmlcolorblock{D8BFD8} | ||
| 625 | Tomato=0xFF6347, ///< @htmlcolorblock{FF6347} | ||
| 626 | Turquoise=0x40E0D0, ///< @htmlcolorblock{40E0D0} | ||
| 627 | Violet=0xEE82EE, ///< @htmlcolorblock{EE82EE} | ||
| 628 | Wheat=0xF5DEB3, ///< @htmlcolorblock{F5DEB3} | ||
| 629 | White=0xFFFFFF, ///< @htmlcolorblock{FFFFFF} | ||
| 630 | WhiteSmoke=0xF5F5F5, ///< @htmlcolorblock{F5F5F5} | ||
| 631 | Yellow=0xFFFF00, ///< @htmlcolorblock{FFFF00} | ||
| 632 | YellowGreen=0x9ACD32, ///< @htmlcolorblock{9ACD32} | ||
| 633 | |||
| 634 | // LED RGB color that roughly approximates | ||
| 635 | // the color of incandescent fairy lights, | ||
| 636 | // assuming that you're using FastLED | ||
| 637 | // color correction on your LEDs (recommended). | ||
| 638 | FairyLight=0xFFE42D, ///< @htmlcolorblock{FFE42D} | ||
| 639 | |||
| 640 | // If you are using no color correction, use this | ||
| 641 | FairyLightNCC=0xFF9D2A ///< @htmlcolorblock{FFE42D} | ||
| 642 | |||
| 643 | } HTMLColorCode; | ||
| 644 | }; | ||
| 645 | |||
| 646 | |||
| 647 | /// Check if two CRGB objects have the same color data | ||
| 648 | FASTLED_FORCE_INLINE bool operator== (const CRGB& lhs, const CRGB& rhs) | ||
| 649 | { | ||
| 650 |
18/18✓ Branch 0 taken 13488 times.
✓ Branch 1 taken 8292 times.
✓ Branch 2 taken 13230 times.
✓ Branch 3 taken 258 times.
✓ Branch 4 taken 5902 times.
✓ Branch 5 taken 7328 times.
✓ Branch 6 taken 8982 times.
✓ Branch 7 taken 9674 times.
✓ Branch 8 taken 6692 times.
✓ Branch 9 taken 2290 times.
✓ Branch 10 taken 6328 times.
✓ Branch 11 taken 364 times.
✓ Branch 12 taken 82676 times.
✓ Branch 13 taken 945 times.
✓ Branch 14 taken 82657 times.
✓ Branch 15 taken 19 times.
✓ Branch 16 taken 82142 times.
✓ Branch 17 taken 515 times.
|
124057 | return (lhs.r == rhs.r) && (lhs.g == rhs.g) && (lhs.b == rhs.b); |
| 651 | } | ||
| 652 | |||
| 653 | /// Check if two CRGB objects do *not* have the same color data | ||
| 654 | FASTLED_FORCE_INLINE bool operator!= (const CRGB& lhs, const CRGB& rhs) | ||
| 655 | { | ||
| 656 | 105401 | return !(lhs == rhs); | |
| 657 | } | ||
| 658 | |||
| 659 | /// Check if two CHSV objects have the same color data | ||
| 660 | FASTLED_FORCE_INLINE bool operator== (const CHSV& lhs, const CHSV& rhs) | ||
| 661 | { | ||
| 662 | return (lhs.h == rhs.h) && (lhs.s == rhs.s) && (lhs.v == rhs.v); | ||
| 663 | } | ||
| 664 | |||
| 665 | /// Check if two CHSV objects do *not* have the same color data | ||
| 666 | FASTLED_FORCE_INLINE bool operator!= (const CHSV& lhs, const CHSV& rhs) | ||
| 667 | { | ||
| 668 | return !(lhs == rhs); | ||
| 669 | } | ||
| 670 | |||
| 671 | /// Check if the sum of the color channels in one CRGB object is less than another | ||
| 672 | FASTLED_FORCE_INLINE bool operator< (const CRGB& lhs, const CRGB& rhs) | ||
| 673 | { | ||
| 674 | uint16_t sl, sr; | ||
| 675 | sl = lhs.r + lhs.g + lhs.b; | ||
| 676 | sr = rhs.r + rhs.g + rhs.b; | ||
| 677 | return sl < sr; | ||
| 678 | } | ||
| 679 | |||
| 680 | /// Check if the sum of the color channels in one CRGB object is greater than another | ||
| 681 | FASTLED_FORCE_INLINE bool operator> (const CRGB& lhs, const CRGB& rhs) | ||
| 682 | { | ||
| 683 | uint16_t sl, sr; | ||
| 684 | sl = lhs.r + lhs.g + lhs.b; | ||
| 685 | sr = rhs.r + rhs.g + rhs.b; | ||
| 686 | return sl > sr; | ||
| 687 | } | ||
| 688 | |||
| 689 | /// Check if the sum of the color channels in one CRGB object is greater than or equal to another | ||
| 690 | FASTLED_FORCE_INLINE bool operator>= (const CRGB& lhs, const CRGB& rhs) | ||
| 691 | { | ||
| 692 | uint16_t sl, sr; | ||
| 693 | sl = lhs.r + lhs.g + lhs.b; | ||
| 694 | sr = rhs.r + rhs.g + rhs.b; | ||
| 695 | return sl >= sr; | ||
| 696 | } | ||
| 697 | |||
| 698 | /// Check if the sum of the color channels in one CRGB object is less than or equal to another | ||
| 699 | FASTLED_FORCE_INLINE bool operator<= (const CRGB& lhs, const CRGB& rhs) | ||
| 700 | { | ||
| 701 | uint16_t sl, sr; | ||
| 702 | sl = lhs.r + lhs.g + lhs.b; | ||
| 703 | sr = rhs.r + rhs.g + rhs.b; | ||
| 704 | return sl <= sr; | ||
| 705 | } | ||
| 706 | |||
| 707 | |||
| 708 | |||
| 709 | /// @copydoc CRGB::operator/= | ||
| 710 | FASTLED_FORCE_INLINE CRGB operator/( const CRGB& p1, uint8_t d) | ||
| 711 | { | ||
| 712 | return CRGB( p1.r/d, p1.g/d, p1.b/d); | ||
| 713 | } | ||
| 714 | |||
| 715 | |||
| 716 | /// Combine two CRGB objects, taking the smallest value of each channel | ||
| 717 | FASTLED_FORCE_INLINE CRGB operator&( const CRGB& p1, const CRGB& p2) | ||
| 718 | { | ||
| 719 | return CRGB( p1.r < p2.r ? p1.r : p2.r, | ||
| 720 | p1.g < p2.g ? p1.g : p2.g, | ||
| 721 | p1.b < p2.b ? p1.b : p2.b); | ||
| 722 | } | ||
| 723 | |||
| 724 | /// Combine two CRGB objects, taking the largest value of each channel | ||
| 725 | FASTLED_FORCE_INLINE CRGB operator|( const CRGB& p1, const CRGB& p2) | ||
| 726 | { | ||
| 727 | return CRGB( p1.r > p2.r ? p1.r : p2.r, | ||
| 728 | p1.g > p2.g ? p1.g : p2.g, | ||
| 729 | p1.b > p2.b ? p1.b : p2.b); | ||
| 730 | } | ||
| 731 | |||
| 732 | /// @copydoc CRGB::operator+= | ||
| 733 | FASTLED_FORCE_INLINE CRGB operator+( const CRGB& p1, const CRGB& p2); | ||
| 734 | |||
| 735 | /// @copydoc CRGB::operator-= | ||
| 736 | FASTLED_FORCE_INLINE CRGB operator-( const CRGB& p1, const CRGB& p2); | ||
| 737 | |||
| 738 | /// @copydoc CRGB::operator*= | ||
| 739 | FASTLED_FORCE_INLINE CRGB operator*( const CRGB& p1, uint8_t d); | ||
| 740 | |||
| 741 | /// Scale using CRGB::nscale8_video() | ||
| 742 | FASTLED_FORCE_INLINE CRGB operator%( const CRGB& p1, uint8_t d); | ||
| 743 | |||
| 744 | /// @} PixelTypes | ||
| 745 | |||
| 746 | |||
| 747 | FASTLED_NAMESPACE_END | ||
| 748 | |||
| 749 | |||
| 750 |