1 #define FASTLED_INTERNAL
6 FASTLED_NAMESPACE_BEGIN
50 void hsv2rgb_raw_C (
const struct CHSV & hsv,
struct CRGB & rgb);
51 void hsv2rgb_raw_avr(
const struct CHSV & hsv,
struct CRGB & rgb);
53 #if defined(__AVR__) && !defined( LIB8_ATTINY )
54 void hsv2rgb_raw(
const struct CHSV & hsv,
struct CRGB & rgb)
56 hsv2rgb_raw_avr( hsv, rgb);
59 void hsv2rgb_raw(
const struct CHSV & hsv,
struct CRGB & rgb)
61 hsv2rgb_raw_C( hsv, rgb);
67 #define APPLY_DIMMING(X) (X)
68 #define HSV_SECTION_6 (0x20)
69 #define HSV_SECTION_3 (0x40)
71 void hsv2rgb_raw_C (
const struct CHSV & hsv,
struct CRGB & rgb)
78 uint8_t value = APPLY_DIMMING( hsv.val);
79 uint8_t saturation = hsv.sat;
83 uint8_t invsat = APPLY_DIMMING( 255 - saturation);
84 uint8_t brightness_floor = (value * invsat) / 256;
89 uint8_t color_amplitude = value - brightness_floor;
93 uint8_t section = hsv.hue / HSV_SECTION_3;
94 uint8_t offset = hsv.hue % HSV_SECTION_3;
96 uint8_t rampup = offset;
97 uint8_t rampdown = (HSV_SECTION_3 - 1) - offset;
129 uint8_t rampup_amp_adj = (rampup * color_amplitude) / (256 / 4);
130 uint8_t rampdown_amp_adj = (rampdown * color_amplitude) / (256 / 4);
133 uint8_t rampup_adj_with_floor = rampup_amp_adj + brightness_floor;
134 uint8_t rampdown_adj_with_floor = rampdown_amp_adj + brightness_floor;
140 rgb.r = brightness_floor;
141 rgb.g = rampdown_adj_with_floor;
142 rgb.b = rampup_adj_with_floor;
145 rgb.r = rampup_adj_with_floor;
146 rgb.g = brightness_floor;
147 rgb.b = rampdown_adj_with_floor;
151 rgb.r = rampdown_adj_with_floor;
152 rgb.g = rampup_adj_with_floor;
153 rgb.b = brightness_floor;
159 #if defined(__AVR__) && !defined( LIB8_ATTINY )
160 void hsv2rgb_raw_avr(
const struct CHSV & hsv,
struct CRGB & rgb)
162 uint8_t hue, saturation, value;
165 saturation = hsv.sat;
169 saturation = 255 - saturation;
170 uint8_t invsat = APPLY_DIMMING( saturation );
173 value = APPLY_DIMMING( value );
177 uint8_t brightness_floor;
180 "mul %[value], %[invsat] \n"
181 "mov %[brightness_floor], r1 \n"
182 : [brightness_floor]
"=r" (brightness_floor)
183 : [value]
"r" (value),
184 [invsat]
"r" (invsat)
191 uint8_t color_amplitude = value - brightness_floor;
195 uint8_t offset = hsv.hue & (HSV_SECTION_3 - 1);
196 uint8_t rampup = offset * 4;
200 uint8_t rampup_amp_adj;
201 uint8_t rampdown_amp_adj;
204 "mul %[rampup], %[color_amplitude] \n"
205 "mov %[rampup_amp_adj], r1 \n"
207 "mul %[rampup], %[color_amplitude] \n"
208 "mov %[rampdown_amp_adj], r1 \n"
209 : [rampup_amp_adj]
"=&r" (rampup_amp_adj),
210 [rampdown_amp_adj]
"=&r" (rampdown_amp_adj),
211 [rampup]
"+r" (rampup)
212 : [color_amplitude]
"r" (color_amplitude)
218 uint8_t rampup_adj_with_floor = rampup_amp_adj + brightness_floor;
219 uint8_t rampdown_adj_with_floor = rampdown_amp_adj + brightness_floor;
228 asm volatile(
"" : : :
"r26",
"r27" );
233 rgb.r = rampup_adj_with_floor;
234 rgb.g = brightness_floor;
235 rgb.b = rampdown_adj_with_floor;
239 rgb.r = brightness_floor;
240 rgb.g = rampdown_adj_with_floor;
241 rgb.b = rampup_adj_with_floor;
244 rgb.r = rampdown_adj_with_floor;
245 rgb.g = rampup_adj_with_floor;
246 rgb.b = brightness_floor;
256 void hsv2rgb_spectrum(
const CHSV& hsv,
CRGB& rgb)
259 hsv2.hue =
scale8( hsv2.hue, 192);
260 hsv2rgb_raw(hsv2, rgb);
270 #define FORCE_REFERENCE(var) asm volatile( "" : : "r" (var) )
288 const uint8_t Y1 = 1;
289 const uint8_t Y2 = 0;
293 const uint8_t G2 = 0;
297 const uint8_t Gscale = 0;
300 uint8_t hue = hsv.hue;
301 uint8_t sat = hsv.sat;
302 uint8_t val = hsv.val;
304 uint8_t offset = hue & 0x1F;
307 uint8_t offset8 = offset;
324 uint8_t third =
scale8( offset8, (256 / 3));
328 if( ! (hue & 0x80) ) {
330 if( ! (hue & 0x40) ) {
333 if( ! (hue & 0x20) ) {
352 uint8_t twothirds =
scale8( offset8, ((256 * 2) / 3));
361 if( ! (hue & 0x20) ) {
366 uint8_t twothirds =
scale8( offset8, ((256 * 2) / 3));
367 r = K171 - twothirds;
390 if( ! (hue & 0x40) ) {
392 if( ! ( hue & 0x20) ) {
398 uint8_t twothirds =
scale8( offset8, ((256 * 2) / 3));
399 g = K171 - twothirds;
412 if( ! (hue & 0x20) ) {
441 r = 255; b = 255; g = 255;
444 #if (FASTLED_SCALE8_FIXED==1)
455 uint8_t desat = 255 - sat;
456 desat =
scale8( desat, desat);
458 uint8_t brightness_floor = desat;
459 r += brightness_floor;
460 g += brightness_floor;
461 b += brightness_floor;
473 #if (FASTLED_SCALE8_FIXED==1)
498 void hsv2rgb_raw(
const struct CHSV * phsv,
struct CRGB * prgb,
int numLeds) {
499 for(
int i = 0; i < numLeds; i++) {
500 hsv2rgb_raw(phsv[i], prgb[i]);
505 for(
int i = 0; i < numLeds; i++) {
510 void hsv2rgb_spectrum(
const struct CHSV* phsv,
struct CRGB * prgb,
int numLeds) {
511 for(
int i = 0; i < numLeds; i++) {
512 hsv2rgb_spectrum(phsv[i], prgb[i]);
518 #define FIXFRAC8(N,D) (((N)*256)/(D))
523 CHSV rgb2hsv_approximate(
const CRGB& rgb)
532 if( r < desat) desat = r;
533 if( g < desat) desat = g;
534 if( b < desat) desat = b;
552 s = 255 -
sqrt16( (255-s) * 256);
562 if( (r + g + b) == 0) {
564 return CHSV( 0, 0, 255 - s);
570 uint32_t scaleup = 65535 / (s);
571 r = ((uint32_t)(r) * scaleup) / 256;
572 g = ((uint32_t)(g) * scaleup) / 256;
573 b = ((uint32_t)(b) * scaleup) / 256;
579 uint16_t total = r + g + b;
585 if( total == 0) total = 1;
586 uint32_t scaleup = 65535 / (total);
587 r = ((uint32_t)(r) * scaleup) / 256;
588 g = ((uint32_t)(g) * scaleup) / 256;
589 b = ((uint32_t)(b) * scaleup) / 256;
598 v =
qadd8(desat,total);
600 if( v != 255) v =
sqrt16( v * 256);
638 if( g > highest) highest = g;
639 if( b > highest) highest = b;
646 h = (HUE_PURPLE + HUE_PINK) / 2;
648 }
else if ( (r - g) > g) {
651 h +=
scale8( g, FIXFRAC8(32,85));
655 h +=
scale8(
qsub8((g - 85) + (171 - r), 4), FIXFRAC8(32,85));
658 }
else if ( highest == g) {
668 uint8_t rgadj = radj + gadj;
669 uint8_t hueadv = rgadj / 2;
677 h +=
scale8( b, FIXFRAC8(32,85));
689 h = HUE_AQUA + ((HUE_BLUE - HUE_AQUA) / 4);
691 }
else if ( (b-r) > r) {
694 h +=
scale8( r, FIXFRAC8(32,85));
703 return CHSV( h, s, v);
714 FASTLED_NAMESPACE_END
Representation of an RGB pixel (Red, Green, Blue)
LIB8STATIC_ALWAYS_INLINE void cleanup_R1()
Clean up the r1 register after a series of *LEAVING_R1_DIRTY calls.
LIB8STATIC_ALWAYS_INLINE uint8_t qsub8(uint8_t i, uint8_t j)
subtract one byte from another, saturating at 0x00
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video_LEAVING_R1_DIRTY(uint8_t i, fract8 scale)
This version of scale8_video does not clean up the R1 register on AVR If you are doing several 'scale...
central include file for FastLED, defines the CFastLED class/object
LIB8STATIC_ALWAYS_INLINE uint8_t qadd8(uint8_t i, uint8_t j)
add one byte to another, saturating at 0xFF
void hsv2rgb_rainbow(const CHSV &hsv, CRGB &rgb)
Forward declaration of hsv2rgb_rainbow here, to avoid circular dependencies.
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 ...
LIB8STATIC uint8_t sqrt16(uint16_t x)
square root for 16-bit integers About three times faster and five times smaller than Arduino's genera...
Representation of an HSV pixel (hue, saturation, value (aka brightness)).
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_LEAVING_R1_DIRTY(uint8_t i, fract8 scale)
This version of scale8 does not clean up the R1 register on AVR If you are doing several 'scale8's in...