Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Garcia <danielgarcia@gmail.com>2016-01-23 10:40:10 +0300
committerDaniel Garcia <danielgarcia@gmail.com>2016-01-23 10:40:10 +0300
commit6d6aca7330c4c2e1b29cf791dbf2550692da59d2 (patch)
treedebfea01124507eb37ff9d91b506205f0822cf88
parent566e69235963dafb00fbb7cbc5a7d4f09f3ed3b1 (diff)
parentce4bfbc878d5be4cf5aecd9268bd2a4520a41363 (diff)
Merge branch 'master' of https://github.com/FastLED/FastLED
-rw-r--r--hsv2rgb.cpp191
1 files changed, 131 insertions, 60 deletions
diff --git a/hsv2rgb.cpp b/hsv2rgb.cpp
index 17c20c4c..49056d51 100644
--- a/hsv2rgb.cpp
+++ b/hsv2rgb.cpp
@@ -286,22 +286,22 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb)
// Level Y2 is a strong boost.
const uint8_t Y1 = 1;
const uint8_t Y2 = 0;
-
+
// G2: Whether to divide all greens by two.
// Depends GREATLY on your particular LEDs
const uint8_t G2 = 0;
-
+
// Gscale: what to scale green down by.
// Depends GREATLY on your particular LEDs
const uint8_t Gscale = 0;
-
-
+
+
uint8_t hue = hsv.hue;
uint8_t sat = hsv.sat;
uint8_t val = hsv.val;
-
+
uint8_t offset = hue & 0x1F; // 0..31
-
+
// offset8 = offset * 8
uint8_t offset8 = offset;
{
@@ -319,11 +319,11 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb)
offset8 <<= 3;
#endif
}
-
+
uint8_t third = scale8( offset8, (256 / 3));
-
+
uint8_t r, g, b;
-
+
if( ! (hue & 0x80) ) {
// 0XX
if( ! (hue & 0x40) ) {
@@ -397,7 +397,7 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb)
uint8_t twothirds = scale8( offset8, ((256 * 2) / 3));
g = K171 - twothirds;
b = K85 + twothirds;
-
+
} else {
// 101
//case 5: // B -> P
@@ -405,7 +405,7 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb)
g = 0;
FORCE_REFERENCE(g);
b = K255 - third;
-
+
}
} else {
if( ! (hue & 0x20) ) {
@@ -415,7 +415,7 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb)
g = 0;
FORCE_REFERENCE(g);
b = K171 - third;
-
+
} else {
// 111
//case 7: // K -> R
@@ -423,38 +423,53 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb)
g = 0;
FORCE_REFERENCE(g);
b = K85 - third;
-
+
}
}
}
-
+
// This is one of the good places to scale the green down,
// although the client can scale green down as well.
if( G2 ) g = g >> 1;
if( Gscale ) g = scale8_video_LEAVING_R1_DIRTY( g, Gscale);
-
+
// Scale down colors if we're desaturated at all
// and add the brightness_floor to r, g, and b.
if( sat != 255 ) {
-
- nscale8x3_video( r, g, b, sat);
-
- uint8_t desat = 255 - sat;
- desat = scale8( desat, desat);
-
- uint8_t brightness_floor = desat;
- r += brightness_floor;
- g += brightness_floor;
- b += brightness_floor;
+ if( sat == 0) {
+ r = 255; b = 255; g = 255;
+ } else {
+ //nscale8x3_video( r, g, b, sat);
+ if( r ) r = scale8_LEAVING_R1_DIRTY( r, sat) + 1;
+ if( g ) g = scale8_LEAVING_R1_DIRTY( g, sat) + 1;
+ if( b ) b = scale8_LEAVING_R1_DIRTY( b, sat) + 1;
+ cleanup_R1();
+
+ uint8_t desat = 255 - sat;
+ desat = scale8( desat, desat);
+
+ uint8_t brightness_floor = desat;
+ r += brightness_floor;
+ g += brightness_floor;
+ b += brightness_floor;
+ }
}
-
+
// Now scale everything down if we're at value < 255.
if( val != 255 ) {
-
+
val = scale8_video_LEAVING_R1_DIRTY( val, val);
- nscale8x3_video( r, g, b, val);
+ if( val == 0 ) {
+ r=0; g=0; b=0;
+ } else {
+ // nscale8x3_video( r, g, b, val);
+ if( r ) r = scale8_LEAVING_R1_DIRTY( r, val) + 1;
+ if( g ) g = scale8_LEAVING_R1_DIRTY( g, val) + 1;
+ if( b ) b = scale8_LEAVING_R1_DIRTY( b, val) + 1;
+ cleanup_R1();
+ }
}
-
+
// Here we have the old AVR "missing std X+n" problem again
// It turns out that fixing it winds up costing more than
// not fixing it.
@@ -498,41 +513,72 @@ CHSV rgb2hsv_approximate( const CRGB& rgb)
uint8_t g = rgb.g;
uint8_t b = rgb.b;
uint8_t h, s, v;
-
+
// find desaturation
uint8_t desat = 255;
if( r < desat) desat = r;
if( g < desat) desat = g;
if( b < desat) desat = b;
-
+
// remove saturation from all channels
r -= desat;
g -= desat;
b -= desat;
-
+
+ //Serial.print("desat="); Serial.print(desat); Serial.println("");
+
+ //uint8_t orig_desat = sqrt16( desat * 256);
+ //Serial.print("orig_desat="); Serial.print(orig_desat); Serial.println("");
+
+ // saturation is opposite of desaturation
+ s = 255 - desat;
+ //Serial.print("s.1="); Serial.print(s); Serial.println("");
+
+ if( s != 255 ) {
+ // undo 'dimming' of saturation
+ s = 255 - sqrt16( (255-s) * 256);
+ }
+ // without lib8tion: float ... ew ... sqrt... double ew, or rather, ew ^ 0.5
+ // if( s != 255 ) s = (255 - (256.0 * sqrt( (float)(255-s) / 256.0)));
+ //Serial.print("s.2="); Serial.print(s); Serial.println("");
+
+
// at least one channel is now zero
-
// if all three channels are zero, we had a
// shade of gray.
-
- uint16_t total = r + g + b;
-
- if( total == 0) {
+ if( (r + g + b) == 0) {
// we pick hue zero for no special reason
- return CHSV( 0, 0, desat);
+ return CHSV( 0, 0, 255 - s);
}
-
- // since this wasn't a pure shade of gray,
- // the interesting question is what hue is it
-
- // scale all channels up to a total of 255
- if( total != 255) {
+
+ // scale all channels up to compensate for desaturation
+ if( s < 255) {
+ if( s == 0) s = 1;
+ uint32_t scaleup = 65535 / (s);
+ r = ((uint32_t)(r) * scaleup) / 256;
+ g = ((uint32_t)(g) * scaleup) / 256;
+ b = ((uint32_t)(b) * scaleup) / 256;
+ }
+ //Serial.print("r.2="); Serial.print(r); Serial.println("");
+ //Serial.print("g.2="); Serial.print(g); Serial.println("");
+ //Serial.print("b.2="); Serial.print(b); Serial.println("");
+
+ uint16_t total = r + g + b;
+
+ //Serial.print("total="); Serial.print(total); Serial.println("");
+
+ // scale all channels up to compensate for low values
+ if( total < 255) {
+ if( total == 0) total = 1;
uint32_t scaleup = 65535 / (total);
r = ((uint32_t)(r) * scaleup) / 256;
g = ((uint32_t)(g) * scaleup) / 256;
b = ((uint32_t)(b) * scaleup) / 256;
}
-
+ //Serial.print("r.3="); Serial.print(r); Serial.println("");
+ //Serial.print("g.3="); Serial.print(g); Serial.println("");
+ //Serial.print("b.3="); Serial.print(b); Serial.println("");
+
if( total > 255 ) {
v = 255;
} else {
@@ -541,35 +587,44 @@ CHSV rgb2hsv_approximate( const CRGB& rgb)
if( v != 255) v = sqrt16( v * 256);
// without lib8tion: float ... ew ... sqrt... double ew, or rather, ew ^ 0.5
// if( v != 255) v = (256.0 * sqrt( (float)(v) / 256.0));
-
+
}
-
- // saturation is opposite of desaturation
- s = 255 - desat;
+
+ //Serial.print("v="); Serial.print(v); Serial.println("");
+
+
+#if 0
+
+ //#else
if( v != 255) {
// this part could probably use refinement/rethinking,
// (but it doesn't overflow & wrap anymore)
uint16_t s16;
s16 = (s * 256);
s16 /= v;
+ //Serial.print("s16="); Serial.print(s16); Serial.println("");
if( s16 < 256) {
s = s16;
} else {
s = 255; // clamp to prevent overflow
}
}
-
- // undo 'dimming' of saturation
- if( s != 255 ) s = 255 - sqrt16( (255-s) * 256);
- // without lib8tion: float ... ew ... sqrt... double ew, or rather, ew ^ 0.5
- // if( s != 255 ) s = (255 - (256.0 * sqrt( (float)(255-s) / 256.0)));
-
+#endif
+
+ //Serial.print("s.3="); Serial.print(s); Serial.println("");
+
+
+ // since this wasn't a pure shade of gray,
+ // the interesting question is what hue is it
+
+
+
// start with which channel is highest
// (ties don't matter)
uint8_t highest = r;
if( g > highest) highest = g;
if( b > highest) highest = b;
-
+
if( highest == r ) {
// Red is highest.
// Hue could be Purple/Pink-Red,Red-Orange,Orange-Yellow
@@ -586,14 +641,22 @@ CHSV rgb2hsv_approximate( const CRGB& rgb)
h = HUE_ORANGE;
h += scale8( qsub8((g - 85) + (171 - r), 4), FIXFRAC8(32,85)); //221
}
-
+
} else if ( highest == g) {
// Green is highest
// Hue could be Yellow-Green, Green-Aqua
if( b == 0) {
// if Blue is zero, we're in Yellow-Green
+ // G = 171..255
+ // R = 171.. 0
h = HUE_YELLOW;
- h += scale8( qadd8( qadd8((g - 128), (128 - r)), 4), FIXFRAC8(32,255)); //
+ uint8_t radj = scale8( qsub8(171,r), 47); //171..0 -> 0..171 -> 0..31
+ uint8_t gadj = scale8( qsub8(g,171), 96); //171..255 -> 0..84 -> 0..31;
+ uint8_t rgadj = radj + gadj;
+ uint8_t hueadv = rgadj / 2;
+ h += hueadv;
+ //h += scale8( qadd8( 4, qadd8((g - 128), (128 - r))),
+ // FIXFRAC8(32,255)); //
} else {
// if Blue is nonzero we're in Green-Aqua
if( (g-b) > b) {
@@ -604,7 +667,7 @@ CHSV rgb2hsv_approximate( const CRGB& rgb)
h += scale8( qsub8(b, 85), FIXFRAC8(8,42));
}
}
-
+
} else /* highest == b */ {
// Blue is highest
// Hue could be Aqua/Blue-Blue, Blue-Purple, Purple-Pink
@@ -622,9 +685,17 @@ CHSV rgb2hsv_approximate( const CRGB& rgb)
h += scale8( qsub8(r, 85), FIXFRAC8(32,85));
}
}
-
+
h += 1;
return CHSV( h, s, v);
}
+// Examples that need work:
+// 0,192,192
+// 192,64,64
+// 224,32,32
+// 252,0,126
+// 252,252,0
+// 252,252,126
+
FASTLED_NAMESPACE_END