FastLED 3.9.15
Loading...
Searching...
No Matches

◆ hsv2rgb_raw_C()

void hsv2rgb_raw_C ( const CHSV & hsv,
CRGB & rgb )

HSV to RGB implementation in raw C, platform independent.

Definition at line 52 of file hsv2rgb.cpp.hpp.

53{
54 // Convert hue, saturation and brightness ( HSV/HSB ) to RGB
55 // "Dimming" is used on saturation and brightness to make
56 // the output more visually linear.
57
58 // Apply dimming curves
59 fl::u8 value = APPLY_DIMMING( hsv.val); // cppcheck-suppress selfAssignment
60 fl::u8 saturation = hsv.sat;
61
62 // The brightness floor is minimum number that all of
63 // R, G, and B will be set to.
64 fl::u8 invsat = APPLY_DIMMING( 255 - saturation); // cppcheck-suppress selfAssignment
65 fl::u8 brightness_floor = (value * invsat) / 256;
66
67 // The color amplitude is the maximum amount of R, G, and B
68 // that will be added on top of the brightness_floor to
69 // create the specific hue desired.
70 fl::u8 color_amplitude = value - brightness_floor;
71
72 // Figure out which section of the hue wheel we're in,
73 // and how far offset we are withing that section
74 fl::u8 section = hsv.hue / HSV_SECTION_3; // 0..2
75 fl::u8 offset = hsv.hue % HSV_SECTION_3; // 0..63
76
77 fl::u8 rampup = offset; // 0..63
78 fl::u8 rampdown = (HSV_SECTION_3 - 1) - offset; // 63..0
79
80 // We now scale rampup and rampdown to a 0-255 range -- at least
81 // in theory, but here's where architecture-specific decsions
82 // come in to play:
83 // To scale them up to 0-255, we'd want to multiply by 4.
84 // But in the very next step, we multiply the ramps by other
85 // values and then divide the resulting product by 256.
86 // So which is faster?
87 // ((ramp * 4) * othervalue) / 256
88 // or
89 // ((ramp ) * othervalue) / 64
90 // It depends on your processor architecture.
91 // On 8-bit AVR, the "/ 256" is just a one-cycle register move,
92 // but the "/ 64" might be a multicycle shift process. So on AVR
93 // it's faster do multiply the ramp values by four, and then
94 // divide by 256.
95 // On ARM, the "/ 256" and "/ 64" are one cycle each, so it's
96 // faster to NOT multiply the ramp values by four, and just to
97 // divide the resulting product by 64 (instead of 256).
98 // Moral of the story: trust your profiler, not your insticts.
99
100 // Since there's an AVR assembly version elsewhere, we'll
101 // assume what we're on an architecture where any number of
102 // bit shifts has roughly the same cost, and we'll remove the
103 // redundant math at the source level:
104
105 // // scale up to 255 range
106 // //rampup *= 4; // 0..252
107 // //rampdown *= 4; // 0..252
108
109 // compute color-amplitude-scaled-down versions of rampup and rampdown
110 fl::u8 rampup_amp_adj = (rampup * color_amplitude) / (256 / 4);
111 fl::u8 rampdown_amp_adj = (rampdown * color_amplitude) / (256 / 4);
112
113 // add brightness_floor offset to everything
114 fl::u8 rampup_adj_with_floor = rampup_amp_adj + brightness_floor;
115 fl::u8 rampdown_adj_with_floor = rampdown_amp_adj + brightness_floor;
116
117
118 if( section ) {
119 if( section == 1) {
120 // section 1: 0x40..0x7F
121 rgb.r = brightness_floor;
122 rgb.g = rampdown_adj_with_floor;
123 rgb.b = rampup_adj_with_floor;
124 } else {
125 // section 2; 0x80..0xBF
126 rgb.r = rampup_adj_with_floor;
127 rgb.g = brightness_floor;
128 rgb.b = rampdown_adj_with_floor;
129 }
130 } else {
131 // section 0: 0x00..0x3F
132 rgb.r = rampdown_adj_with_floor;
133 rgb.g = rampup_adj_with_floor;
134 rgb.b = brightness_floor;
135 }
136}
fl::UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
#define APPLY_DIMMING(X)
Apply dimming compensation to values.
#define HSV_SECTION_3
Divide the color wheel into four sections, 64 elements each.
unsigned char u8
Definition stdint.h:131

References APPLY_DIMMING, HSV_SECTION_3, and offset().

Referenced by hsv2rgb_raw().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: