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:
authorMark Kriegsman <kriegsman@tr.org>2014-10-11 16:21:14 +0400
committerMark Kriegsman <kriegsman@tr.org>2014-10-11 16:21:14 +0400
commitc18ee923241103a33f2024582bb4785f3ac5ea81 (patch)
tree78af7c9990fc45aa77701ba6b7d7cf8c97fe9144
parentbaf6dfaf9eb1ea4e57956398f42555d0d0e3d828 (diff)
Added CHSVPalette16, CHSVPalette256, and map_data_into_colors_through_palette( data, NUM_LEDS, leds, palette), which saves typing, and lets you focus on 'data' and 'palette' separately.
-rw-r--r--colorpalettes.cpp16
-rw-r--r--colorpalettes.h16
-rw-r--r--colorutils.cpp103
-rw-r--r--colorutils.h274
4 files changed, 352 insertions, 57 deletions
diff --git a/colorpalettes.cpp b/colorpalettes.cpp
index 9591279a..8cec8980 100644
--- a/colorpalettes.cpp
+++ b/colorpalettes.cpp
@@ -24,7 +24,7 @@
// use each one, so you only 'pay for' those you actually use.
-extern const TProgmemPalette16 CloudColors_p PROGMEM =
+extern const TProgmemRGBPalette16 CloudColors_p PROGMEM =
{
CRGB::Blue,
CRGB::DarkBlue,
@@ -47,7 +47,7 @@ extern const TProgmemPalette16 CloudColors_p PROGMEM =
CRGB::SkyBlue
};
-extern const TProgmemPalette16 LavaColors_p PROGMEM =
+extern const TProgmemRGBPalette16 LavaColors_p PROGMEM =
{
CRGB::Black,
CRGB::Maroon,
@@ -70,7 +70,7 @@ extern const TProgmemPalette16 LavaColors_p PROGMEM =
};
-extern const TProgmemPalette16 OceanColors_p PROGMEM =
+extern const TProgmemRGBPalette16 OceanColors_p PROGMEM =
{
CRGB::MidnightBlue,
CRGB::DarkBlue,
@@ -93,7 +93,7 @@ extern const TProgmemPalette16 OceanColors_p PROGMEM =
CRGB::LightSkyBlue
};
-extern const TProgmemPalette16 ForestColors_p PROGMEM =
+extern const TProgmemRGBPalette16 ForestColors_p PROGMEM =
{
CRGB::DarkGreen,
CRGB::DarkGreen,
@@ -117,7 +117,7 @@ extern const TProgmemPalette16 ForestColors_p PROGMEM =
};
// HSV Rainbow
-extern const TProgmemPalette16 RainbowColors_p PROGMEM =
+extern const TProgmemRGBPalette16 RainbowColors_p PROGMEM =
{
0xFF0000, 0xD52A00, 0xAB5500, 0xAB7F00,
0xABAB00, 0x56D500, 0x00FF00, 0x00D52A,
@@ -127,7 +127,7 @@ extern const TProgmemPalette16 RainbowColors_p PROGMEM =
// HSV Rainbow colors with alternatating stripes of black
#define RainbowStripesColors_p RainbowStripeColors_p
-extern const TProgmemPalette16 RainbowStripeColors_p PROGMEM =
+extern const TProgmemRGBPalette16 RainbowStripeColors_p PROGMEM =
{
0xFF0000, 0x000000, 0xAB5500, 0x000000,
0xABAB00, 0x000000, 0x00FF00, 0x000000,
@@ -139,7 +139,7 @@ extern const TProgmemPalette16 RainbowStripeColors_p PROGMEM =
// Basically, everything but the greens, which tend to make
// people's skin look unhealthy. This palette is good for
// lighting at a club or party, where it'll be shining on people.
-extern const TProgmemPalette16 PartyColors_p PROGMEM =
+extern const TProgmemRGBPalette16 PartyColors_p PROGMEM =
{
0x5500AB, 0x84007C, 0xB5004B, 0xE5001B,
0xE81700, 0xB84700, 0xAB7700, 0xABAB00,
@@ -153,7 +153,7 @@ extern const TProgmemPalette16 PartyColors_p PROGMEM =
// the usual 0-255, as the last 15 colors will be
// 'wrapping around' from the hot end to the cold end,
// which looks wrong.
-extern const TProgmemPalette16 HeatColors_p PROGMEM =
+extern const TProgmemRGBPalette16 HeatColors_p PROGMEM =
{
0x000000,
0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000,
diff --git a/colorpalettes.h b/colorpalettes.h
index b9622694..340349d4 100644
--- a/colorpalettes.h
+++ b/colorpalettes.h
@@ -13,23 +13,23 @@
// use each one, so you only 'pay for' those you actually use.
-extern const TProgmemPalette16 CloudColors_p PROGMEM;
-extern const TProgmemPalette16 LavaColors_p PROGMEM;
-extern const TProgmemPalette16 OceanColors_p PROGMEM;
-extern const TProgmemPalette16 ForestColors_p PROGMEM;
+extern const TProgmemRGBPalette16 CloudColors_p PROGMEM;
+extern const TProgmemRGBPalette16 LavaColors_p PROGMEM;
+extern const TProgmemRGBPalette16 OceanColors_p PROGMEM;
+extern const TProgmemRGBPalette16 ForestColors_p PROGMEM;
// HSV Rainbow
-extern const TProgmemPalette16 RainbowColors_p PROGMEM;
+extern const TProgmemRGBPalette16 RainbowColors_p PROGMEM;
// HSV Rainbow colors with alternatating stripes of black
#define RainbowStripesColors_p RainbowStripeColors_p
-extern const TProgmemPalette16 RainbowStripeColors_p PROGMEM;
+extern const TProgmemRGBPalette16 RainbowStripeColors_p PROGMEM;
// HSV color ramp: blue purple ping red orange yellow (and back)
// Basically, everything but the greens, which tend to make
// people's skin look unhealthy. This palette is good for
// lighting at a club or party, where it'll be shining on people.
-extern const TProgmemPalette16 PartyColors_p PROGMEM;
+extern const TProgmemRGBPalette16 PartyColors_p PROGMEM;
// Approximate "black body radiation" palette, akin to
// the FastLED 'HeatColor' function.
@@ -37,6 +37,6 @@ extern const TProgmemPalette16 PartyColors_p PROGMEM;
// the usual 0-255, as the last 15 colors will be
// 'wrapping around' from the hot end to the cold end,
// which looks wrong.
-extern const TProgmemPalette16 HeatColors_p PROGMEM;
+extern const TProgmemRGBPalette16 HeatColors_p PROGMEM;
#endif
diff --git a/colorutils.cpp b/colorutils.cpp
index 6a12fb11..781651a8 100644
--- a/colorutils.cpp
+++ b/colorutils.cpp
@@ -456,41 +456,98 @@ CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, uint8_t brightn
}
-void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256)
+CHSV ColorFromPalette( const struct CHSVPalette16& pal, uint8_t index, uint8_t brightness, TBlendType blendType)
{
- for( int i = 0; i < 256; i++) {
- destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i);
+ uint8_t hi4 = index >> 4;
+ uint8_t lo4 = index & 0x0F;
+
+ // CRGB rgb1 = pal[ hi4];
+ const CHSV* entry = &(pal[0]) + hi4;
+
+ uint8_t hue1 = entry->hue;
+ uint8_t sat1 = entry->sat;
+ uint8_t val1 = entry->val;
+
+ uint8_t blend = lo4 && (blendType != NOBLEND);
+
+ if( blend ) {
+
+ if( hi4 == 15 ) {
+ entry = &(pal[0]);
+ } else {
+ entry++;
+ }
+
+ uint8_t f2 = lo4 << 4;
+ uint8_t f1 = 256 - f2;
+
+ uint8_t hue2 = entry->hue;
+ uint8_t sat2 = entry->sat;
+ uint8_t val2 = entry->val;
+
+ sat1 = scale8_LEAVING_R1_DIRTY( sat1, f1);
+ val1 = scale8_LEAVING_R1_DIRTY( val1, f1);
+
+ sat2 = scale8_LEAVING_R1_DIRTY( sat2, f2);
+ val2 = scale8_LEAVING_R1_DIRTY( val2, f2);
+
+ // cleanup_R1();
+
+ // These sums can't overflow, so no qadd8 needed.
+ sat1 += sat2;
+ val1 += val2;
+
+ uint8_t deltaHue = (uint8_t)(hue2 - hue1);
+ if( deltaHue & 0x80 ) {
+ // go backwards
+ hue1 -= scale8( 256 - deltaHue, f2);
+ } else {
+ // go forwards
+ hue1 += scale8( deltaHue, f2);
+ }
+
+ cleanup_R1();
+ }
+
+ if( brightness != 255) {
+ val1 = scale8_video( val1, brightness);
}
+
+ return CHSV( hue1, sat1, val1);
}
-#if 0
-// replaced by PartyColors_p
-void SetupPartyColors(CRGBPalette16& pal)
-{
- fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 18,255,255), FORWARD_HUES);
- fill_gradient( pal, 8, CHSV( HUE_ORANGE,255,255), 15, CHSV(HUE_BLUE + 18,255,255), BACKWARD_HUES);
-}
-#endif
-void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex,
- const CRGBPalette16& pal, uint8_t brightness, TBlendType blendType)
+CHSV ColorFromPalette( const struct CHSVPalette256& pal, uint8_t index, uint8_t brightness, TBlendType)
{
- uint8_t colorIndex = startIndex;
- for( uint16_t i = 0; i < N; i++) {
- L[i] = ColorFromPalette( pal, colorIndex, brightness, blendType);
- colorIndex += incIndex;
+ CHSV hsv;// = *( &(pal[0]) + index );
+
+ if( brightness != 255) {
+ hsv.value = scale8_video( hsv.value, brightness);
}
+
+ return hsv;
}
-void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex,
- const CRGBPalette256& pal, uint8_t brightness, TBlendType blendType)
+void UpscalePalette(const struct CRGBPalette16& srcpal16, struct CRGBPalette256& destpal256)
{
- uint8_t colorIndex = startIndex;
- for( uint16_t i = 0; i < N; i++) {
- L[i] = ColorFromPalette( pal, colorIndex, brightness, blendType);
- colorIndex += incIndex;
+ for( int i = 0; i < 256; i++) {
+ destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i);
}
}
+void UpscalePalette(const struct CHSVPalette16& srcpal16, struct CHSVPalette256& destpal256)
+{
+ for( int i = 0; i < 256; i++) {
+ destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i);
+ }
+}
+#if 0
+// replaced by PartyColors_p
+void SetupPartyColors(CRGBPalette16& pal)
+{
+ fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 18,255,255), FORWARD_HUES);
+ fill_gradient( pal, 8, CHSV( HUE_ORANGE,255,255), 15, CHSV(HUE_BLUE + 18,255,255), BACKWARD_HUES);
+}
+#endif
diff --git a/colorutils.h b/colorutils.h
index c2e1ec65..1a3a8d85 100644
--- a/colorutils.h
+++ b/colorutils.h
@@ -253,7 +253,7 @@ CRGB HeatColor( uint8_t temperature);
// Palettes
//
-// Palettes map an 8-bit value (0..255) to an RGB color.
+// RGB Palettes map an 8-bit value (0..255) to an RGB color.
//
// You can create any color palette you wish; a couple of starters
// are provided: Forest, Clouds, Lava, Ocean, Rainbow, and Rainbow Stripes.
@@ -309,11 +309,189 @@ CRGB HeatColor( uint8_t temperature);
class CRGBPalette16;
class CRGBPalette256;
-typedef prog_uint32_t TProgmemPalette16[16];
+class CHSVPalette16;
+class CHSVPalette256;
+typedef prog_uint32_t TProgmemRGBPalette16[16];
+typedef prog_uint32_t TProgmemHSVPalette16[16];
+#define TProgmemPalette16 TProgmemRGBPalette16
// Convert a 16-entry palette to a 256-entry palette
-void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256);
+void UpscalePalette(const struct CRGBPalette16& srcpal16, struct CRGBPalette256& destpal256);
+void UpscalePalette(const struct CHSVPalette16& srcpal16, struct CHSVPalette256& destpal256);
+class CHSVPalette16 {
+public:
+ CHSV entries[16];
+ CHSVPalette16() {};
+ CHSVPalette16( const CHSV& c00,const CHSV& c01,const CHSV& c02,const CHSV& c03,
+ const CHSV& c04,const CHSV& c05,const CHSV& c06,const CHSV& c07,
+ const CHSV& c08,const CHSV& c09,const CHSV& c10,const CHSV& c11,
+ const CHSV& c12,const CHSV& c13,const CHSV& c14,const CHSV& c15 )
+ {
+ entries[0]=c00; entries[1]=c01; entries[2]=c02; entries[3]=c03;
+ entries[4]=c04; entries[5]=c05; entries[6]=c06; entries[7]=c07;
+ entries[8]=c08; entries[9]=c09; entries[10]=c10; entries[11]=c11;
+ entries[12]=c12; entries[13]=c13; entries[14]=c14; entries[15]=c15;
+ };
+
+ CHSVPalette16( const CHSVPalette16& rhs)
+ {
+ memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries));
+ }
+ CHSVPalette16& operator=( const CHSVPalette16& rhs)
+ {
+ memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries));
+ return *this;
+ }
+
+ CHSVPalette16( const TProgmemHSVPalette16& rhs)
+ {
+ for( uint8_t i = 0; i < 16; i++) {
+ CRGB xyz = pgm_read_dword_near( rhs + i);
+ entries[i].hue = xyz.red;
+ entries[i].sat = xyz.green;
+ entries[i].val = xyz.blue;
+ }
+ }
+ CHSVPalette16& operator=( const TProgmemHSVPalette16& rhs)
+ {
+ for( uint8_t i = 0; i < 16; i++) {
+ CRGB xyz = pgm_read_dword_near( rhs + i);
+ entries[i].hue = xyz.red;
+ entries[i].sat = xyz.green;
+ entries[i].val = xyz.blue;
+ }
+ return *this;
+ }
+
+ inline CHSV& operator[] (uint8_t x) __attribute__((always_inline))
+ {
+ return entries[x];
+ }
+ inline const CHSV& operator[] (uint8_t x) const __attribute__((always_inline))
+ {
+ return entries[x];
+ }
+
+ inline CHSV& operator[] (int x) __attribute__((always_inline))
+ {
+ return entries[(uint8_t)x];
+ }
+ inline const CHSV& operator[] (int x) const __attribute__((always_inline))
+ {
+ return entries[(uint8_t)x];
+ }
+
+ operator CHSV*()
+ {
+ return &(entries[0]);
+ }
+
+ CHSVPalette16( const CHSV& c1)
+ {
+ fill_solid( &(entries[0]), 16, c1);
+ }
+ CHSVPalette16( const CHSV& c1, const CHSV& c2)
+ {
+ fill_gradient( &(entries[0]), 16, c1, c2);
+ }
+ CHSVPalette16( const CHSV& c1, const CHSV& c2, const CHSV& c3)
+ {
+ fill_gradient( &(entries[0]), 16, c1, c2, c3);
+ }
+ CHSVPalette16( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4)
+ {
+ fill_gradient( &(entries[0]), 16, c1, c2, c3, c4);
+ }
+
+};
+
+class CHSVPalette256 {
+public:
+ CHSV entries[256];
+ CHSVPalette256() {};
+ CHSVPalette256( const CHSV& c00,const CHSV& c01,const CHSV& c02,const CHSV& c03,
+ const CHSV& c04,const CHSV& c05,const CHSV& c06,const CHSV& c07,
+ const CHSV& c08,const CHSV& c09,const CHSV& c10,const CHSV& c11,
+ const CHSV& c12,const CHSV& c13,const CHSV& c14,const CHSV& c15 )
+ {
+ CHSVPalette16 p16(c00,c01,c02,c03,c04,c05,c06,c07,
+ c08,c09,c10,c11,c12,c13,c14,c15);
+ *this = p16;
+ };
+
+ CHSVPalette256( const CHSVPalette256& rhs)
+ {
+ memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries));
+ }
+ CHSVPalette256& operator=( const CHSVPalette256& rhs)
+ {
+ memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries));
+ return *this;
+ }
+
+ CHSVPalette256( const CHSVPalette16& rhs16)
+ {
+ UpscalePalette( rhs16, *this);
+ }
+ CHSVPalette256& operator=( const CHSVPalette16& rhs16)
+ {
+ UpscalePalette( rhs16, *this);
+ return *this;
+ }
+
+ CHSVPalette256( const TProgmemRGBPalette16& rhs)
+ {
+ CHSVPalette16 p16(rhs);
+ *this = p16;
+ }
+ CHSVPalette256& operator=( const TProgmemRGBPalette16& rhs)
+ {
+ CHSVPalette16 p16(rhs);
+ *this = p16;
+ return *this;
+ }
+
+ inline CHSV& operator[] (uint8_t x) __attribute__((always_inline))
+ {
+ return entries[x];
+ }
+ inline const CHSV& operator[] (uint8_t x) const __attribute__((always_inline))
+ {
+ return entries[x];
+ }
+
+ inline CHSV& operator[] (int x) __attribute__((always_inline))
+ {
+ return entries[(uint8_t)x];
+ }
+ inline const CHSV& operator[] (int x) const __attribute__((always_inline))
+ {
+ return entries[(uint8_t)x];
+ }
+
+ operator CHSV*()
+ {
+ return &(entries[0]);
+ }
+
+ CHSVPalette256( const CHSV& c1)
+ {
+ fill_solid( &(entries[0]), 256, c1);
+ }
+ CHSVPalette256( const CHSV& c1, const CHSV& c2)
+ {
+ fill_gradient( &(entries[0]), 256, c1, c2);
+ }
+ CHSVPalette256( const CHSV& c1, const CHSV& c2, const CHSV& c3)
+ {
+ fill_gradient( &(entries[0]), 256, c1, c2, c3);
+ }
+ CHSVPalette256( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4)
+ {
+ fill_gradient( &(entries[0]), 256, c1, c2, c3, c4);
+ }
+};
class CRGBPalette16 {
public:
@@ -340,13 +518,27 @@ public:
return *this;
}
- CRGBPalette16( const TProgmemPalette16& rhs)
+ CRGBPalette16( const CHSVPalette16& rhs)
+ {
+ for( uint8_t i = 0; i < 16; i++) {
+ entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion
+ }
+ }
+ CRGBPalette16& operator=( const CHSVPalette16& rhs)
+ {
+ for( uint8_t i = 0; i < 16; i++) {
+ entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion
+ }
+ return *this;
+ }
+
+ CRGBPalette16( const TProgmemRGBPalette16& rhs)
{
for( uint8_t i = 0; i < 16; i++) {
entries[i] = pgm_read_dword_near( rhs + i);
}
}
- CRGBPalette16& operator=( const TProgmemPalette16& rhs)
+ CRGBPalette16& operator=( const TProgmemRGBPalette16& rhs)
{
for( uint8_t i = 0; i < 16; i++) {
entries[i] = pgm_read_dword_near( rhs + i);
@@ -438,6 +630,20 @@ public:
return *this;
}
+ CRGBPalette256( const CHSVPalette256& rhs)
+ {
+ for( int i = 0; i < 256; i++) {
+ entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion
+ }
+ }
+ CRGBPalette256& operator=( const CHSVPalette256& rhs)
+ {
+ for( int i = 0; i < 256; i++) {
+ entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion
+ }
+ return *this;
+ }
+
CRGBPalette256( const CRGBPalette16& rhs16)
{
UpscalePalette( rhs16, *this);
@@ -448,12 +654,12 @@ public:
return *this;
}
- CRGBPalette256( const TProgmemPalette16& rhs)
+ CRGBPalette256( const TProgmemRGBPalette16& rhs)
{
CRGBPalette16 p16(rhs);
*this = p16;
}
- CRGBPalette256& operator=( const TProgmemPalette16& rhs)
+ CRGBPalette256& operator=( const TProgmemRGBPalette16& rhs)
{
CRGBPalette16 p16(rhs);
*this = p16;
@@ -519,6 +725,9 @@ public:
};
+
+
+
typedef enum { NOBLEND=0, BLEND=1 } TBlendType;
CRGB ColorFromPalette( const CRGBPalette16& pal,
@@ -531,20 +740,49 @@ CRGB ColorFromPalette( const CRGBPalette256& pal,
uint8_t brightness=255,
TBlendType blendType=NOBLEND );
+CHSV ColorFromPalette( const CHSVPalette16& pal,
+ uint8_t index,
+ uint8_t brightness=255,
+ TBlendType blendType=BLEND);
-// Fill a range of LEDs with a sequece of entryies from a palette
-void fill_palette(CRGB* L, uint16_t N,
- uint8_t startIndex, uint8_t incIndex,
- const CRGBPalette16& pal,
- uint8_t brightness=255,
- TBlendType blendType=BLEND);
+CHSV ColorFromPalette( const CHSVPalette256& pal,
+ uint8_t index,
+ uint8_t brightness=255,
+ TBlendType blendType=NOBLEND );
-void fill_palette(CRGB* L, uint16_t N,
- uint8_t startIndex, uint8_t incIndex,
- const CRGBPalette256& pal,
- uint8_t brightness=255,
- TBlendType blendType=NOBLEND);
+// Fill a range of LEDs with a sequece of entryies from a palette
+template <typename PALETTE>
+void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex,
+ const PALETTE& pal, uint8_t brightness, TBlendType blendType)
+{
+ uint8_t colorIndex = startIndex;
+ for( uint16_t i = 0; i < N; i++) {
+ L[i] = ColorFromPalette( pal, colorIndex, brightness, blendType);
+ colorIndex += incIndex;
+ }
+}
+template <typename PALETTE>
+void map_data_into_colors_through_palette(
+ uint8_t *dataArray, uint16_t dataCount,
+ CRGB* targetColorArray,
+ const PALETTE& pal,
+ uint8_t brightness=255,
+ uint8_t opacity=255,
+ TBlendType blendType=BLEND)
+{
+ for( uint16_t i = 0; i < dataCount; i++) {
+ uint8_t d = dataArray[i];
+ CRGB rgb = ColorFromPalette( pal, d, brightness, blendType);
+ if( opacity == 255 ) {
+ targetColorArray[i] = rgb;
+ } else {
+ targetColorArray[i].nscale8( 256 - opacity);
+ rgb.nscale8_video( opacity);
+ targetColorArray[i] += rgb;
+ }
+ }
+}
#endif