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-06-18 09:37:18 +0400
committerMark Kriegsman <kriegsman@tr.org>2014-06-18 09:37:18 +0400
commita71c5c5d341c25023ce462d52bd7fa62166e1483 (patch)
tree9064580a889e7c0390c7fee7f85a0d32298e2c22
parent36bc6b94e6e09cd5fdb653e1b0b9a12d22f6e92a (diff)
Initial Palette support.
-rw-r--r--colorutils.cpp243
-rw-r--r--colorutils.h100
-rw-r--r--preview_changes.txt1
3 files changed, 344 insertions, 0 deletions
diff --git a/colorutils.cpp b/colorutils.cpp
index 12e9b0ad..399b2372 100644
--- a/colorutils.cpp
+++ b/colorutils.cpp
@@ -1,5 +1,7 @@
#include <stdint.h>
+#include <avr/pgmspace.h>
+
#include "hsv2rgb.h"
#include "colorutils.h"
@@ -185,3 +187,244 @@ CRGB HeatColor( uint8_t temperature)
return heatcolor;
}
+
+
+
+CRGB ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightness, TInterpolationType interpolationType)
+{
+ uint8_t hi4 = index >> 4;
+ uint8_t lo4 = index & 0x0F;
+
+ // CRGB rgb1 = pal[ hi4];
+ const CRGB* entry = pal + hi4;
+ uint8_t red1 = entry->red;
+ uint8_t green1 = entry->green;
+ uint8_t blue1 = entry->blue;
+
+ uint8_t interpolate = lo4 && (interpolationType != INTERPOLATION_NONE);
+
+ if( interpolate ) {
+
+ if( hi4 == 15 ) {
+ entry = pal;
+ } else {
+ entry++;
+ }
+
+ uint8_t f2 = lo4 << 4;
+ uint8_t f1 = 256 - f2;
+
+ // rgb1.nscale8(f1);
+ red1 = scale8_LEAVING_R1_DIRTY( red1, f1);
+ green1 = scale8_LEAVING_R1_DIRTY( green1, f1);
+ blue1 = scale8_LEAVING_R1_DIRTY( blue1, f1);
+
+ // cleanup_R1();
+
+ // CRGB rgb2 = pal[ hi4];
+ // rgb2.nscale8(f2);
+ uint8_t red2 = entry->red;
+ uint8_t green2 = entry->green;
+ uint8_t blue2 = entry->blue;
+ red2 = scale8_LEAVING_R1_DIRTY( red2, f2);
+ green2 = scale8_LEAVING_R1_DIRTY( green2, f2);
+ blue2 = scale8_LEAVING_R1_DIRTY( blue2, f2);
+
+ cleanup_R1();
+
+ // These sums can't overflow, so no qadd8 needed.
+ red1 += red2;
+ green1 += green2;
+ blue1 += blue2;
+
+ }
+
+ if( brightness != 255) {
+ nscale8x3_video( red1, green1, blue1, brightness);
+ }
+
+ return CRGB( red1, green1, blue1);
+}
+
+
+CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, uint8_t brightness, TInterpolationType)
+{
+ const CRGB* entry = pal + index;
+
+ uint8_t red = entry->red;
+ uint8_t green = entry->green;
+ uint8_t blue = entry->blue;
+
+ if( brightness != 255) {
+ nscale8x3_video( red, green, blue, brightness);
+ }
+
+ return CRGB( red, green, blue);
+}
+
+typedef prog_uint32_t TProgmemPalette16[16];
+
+const TProgmemPalette16 CloudPalette_p PROGMEM =
+{
+ CRGB::Blue,
+ CRGB::DarkBlue,
+ CRGB::DarkBlue,
+ CRGB::DarkBlue,
+
+ CRGB::DarkBlue,
+ CRGB::DarkBlue,
+ CRGB::DarkBlue,
+ CRGB::DarkBlue,
+
+ CRGB::Blue,
+ CRGB::DarkBlue,
+ CRGB::SkyBlue,
+ CRGB::SkyBlue,
+
+ CRGB::LightBlue,
+ CRGB::White,
+ CRGB::LightBlue,
+ CRGB::SkyBlue
+};
+
+const TProgmemPalette16 LavaPalette_p PROGMEM =
+{
+ CRGB::Black,
+ CRGB::Maroon,
+ CRGB::Black,
+ CRGB::Maroon,
+
+ CRGB::DarkRed,
+ CRGB::Maroon,
+ CRGB::DarkRed,
+
+ CRGB::DarkRed,
+ CRGB::DarkRed,
+ CRGB::Red,
+ CRGB::Orange,
+
+ CRGB::White,
+ CRGB::Orange,
+ CRGB::Red,
+ CRGB::DarkRed
+};
+
+
+const TProgmemPalette16 OceanPalette_p PROGMEM =
+{
+ CRGB::MidnightBlue,
+ CRGB::DarkBlue,
+ CRGB::MidnightBlue,
+ CRGB::Navy,
+
+ CRGB::DarkBlue,
+ CRGB::MediumBlue,
+ CRGB::SeaGreen,
+ CRGB::Teal,
+
+ CRGB::CadetBlue,
+ CRGB::Blue,
+ CRGB::DarkCyan,
+ CRGB::CornflowerBlue,
+
+ CRGB::Aquamarine,
+ CRGB::SeaGreen,
+ CRGB::Aqua,
+ CRGB::LightSkyBlue
+};
+
+const TProgmemPalette16 ForestPalette_p PROGMEM =
+{
+ CRGB::DarkGreen,
+ CRGB::DarkGreen,
+ CRGB::DarkOliveGreen,
+ CRGB::DarkGreen,
+
+ CRGB::Green,
+ CRGB::ForestGreen,
+ CRGB::OliveDrab,
+ CRGB::Green,
+
+ CRGB::SeaGreen,
+ CRGB::MediumAquamarine,
+ CRGB::LimeGreen,
+ CRGB::YellowGreen,
+
+ CRGB::LightGreen,
+ CRGB::LawnGreen,
+ CRGB::MediumAquamarine,
+ CRGB::ForestGreen
+};
+
+
+void InitPalette(CRGBPalette16& pal, const TProgmemPalette16 ppp)
+{
+ for( uint8_t i = 0; i < 16; i++) {
+ pal[i] = pgm_read_dword_near( ppp + i);
+ }
+}
+
+void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256)
+{
+ for( int i = 0; i < 256; i++) {
+ destpal256[i] = ColorFromPalette( srcpal16, i);
+ }
+}
+
+void SetCloudPalette(CRGBPalette16& pal)
+{
+ InitPalette( pal, CloudPalette_p);
+}
+
+void SetLavaPalette(CRGBPalette16& pal)
+{
+ InitPalette( pal, LavaPalette_p);
+}
+
+void SetOceanPalette(CRGBPalette16& pal)
+{
+ InitPalette( pal, OceanPalette_p);
+}
+
+void SetForestPalette(CRGBPalette16& pal)
+{
+ InitPalette( pal, ForestPalette_p);
+}
+
+void SetRainbowPalette(CRGBPalette16& pal)
+{
+ for( uint8_t c = 0; c < 16; c += 1) {
+ uint8_t hue = c << 4;
+ pal[c] = CHSV( hue, 255, 255);
+ }
+}
+
+void SetRainbowStripesPalette(CRGBPalette16& pal)
+{
+ for( uint8_t c = 0; c < 16; c += 2) {
+ uint8_t hue = c << 4;
+ pal[c] = CHSV( hue, 255, 255);
+ pal[c+1] = CRGB::Black;
+ }
+}
+
+void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex,
+ const CRGBPalette16& pal, uint8_t brightness, TInterpolationType interpType)
+{
+ uint8_t colorIndex = startIndex;
+ for( uint16_t i = 0; i < N; i++) {
+ L[i] = ColorFromPalette( pal, colorIndex, brightness, interpType);
+ colorIndex += incIndex;
+ }
+}
+
+
+void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex,
+ const CRGBPalette256& pal, uint8_t brightness, TInterpolationType interpType)
+{
+ uint8_t colorIndex = startIndex;
+ for( uint16_t i = 0; i < N; i++) {
+ L[i] = ColorFromPalette( pal, colorIndex, brightness, interpType);
+ colorIndex += incIndex;
+ }
+}
diff --git a/colorutils.h b/colorutils.h
index 44b2855b..001b8d36 100644
--- a/colorutils.h
+++ b/colorutils.h
@@ -74,4 +74,104 @@ void nscale8( CRGB* leds, uint16_t num_leds, uint8_t scale);
// spectrum, but it's surprisingly close, and it's fast and small.
CRGB HeatColor( uint8_t temperature);
+
+// Palettes
+//
+// 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.
+//
+// Palettes come in the traditional 256-entry variety, which take
+// up 768 bytes of RAM, and lightweight 16-entry varieties. The 16-entry
+// variety automatically interpolates between its entries to produce
+// a full 256-element color map, but at a cost of only 48 bytes or RAM.
+//
+// Basic operation is like this: (example shows the 16-entry variety)
+// 1. Declare your palette storage:
+// CRGBPalette16 myPalette;
+//
+// 2. Fill myPalette with your own 16 colors, or with a preset color scheme.
+// You can specify your 16 colors a variety of ways:
+// CRGBPalette16 myPalette =
+// {
+// CRGB::Black,
+// CRGB::Black,
+// CRGB::Red,
+// CRGB::Yellow,
+// CRGB::Green,
+// CRGB::Blue,
+// CRGB::Purple,
+// CRGB::Black,
+//
+// 0x100000,
+// 0x200000,
+// 0x400000,
+// 0x800000,
+//
+// CHSV( 30,255,255),
+// CHSV( 50,255,255),
+// CHSV( 70,255,255),
+// CHSV( 90,255,255)
+// };
+//
+// Or you can initiaize your palette with a preset color scheme:
+// SetRainbowStripesPalette( myPalette);
+//
+// 3. Any time you want to set a pixel to a color from your palette, use
+// "ColorFromPalette(...)" as shown:
+//
+// uint8_t index = /* any value 0..255 */;
+// leds[i] = ColorFromPalette( myPalette, index);
+//
+// Even though your palette has only 16 explicily defined entries, you
+// can use an 'index' from 0..255. The 16 explicit palette entries will
+// be spread evenly across the 0..255 range, and the intermedate values
+// will be RGB-interpolated between adjacent explicit entries.
+//
+// It's easier to use than it sounds.
+//
+
+typedef CRGB CRGBPalette16[16];
+typedef CRGB CRGBPalette256[256];
+
+typedef enum { INTERPOLATION_NONE=0, INTERPOLATION_BLEND=1 } TInterpolationType;
+
+CRGB ColorFromPalette( const CRGBPalette16& pal,
+ uint8_t index,
+ uint8_t brightness=255,
+ TInterpolationType interpolationType=INTERPOLATION_BLEND);
+
+CRGB ColorFromPalette( const CRGBPalette256& pal,
+ uint8_t index,
+ uint8_t brightness=255,
+ TInterpolationType interpolationType=INTERPOLATION_NONE );
+
+// Preset color schemes, such as they are.
+// Try Rainbow Stripes or Lava first.
+void SetForestPalette(CRGBPalette16& pal);
+void SetCloudPalette(CRGBPalette16& pal);
+void SetLavaPalette(CRGBPalette16& pal);
+void SetOceanPalette(CRGBPalette16& pal);
+void SetRainbowPalette(CRGBPalette16& pal);
+void SetRainbowStripesPalette(CRGBPalette16& pal);
+
+
+// Convert a 16-entry palette to a 256-entry palette
+void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256);
+
+// 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,
+ TInterpolationType interpType=INTERPOLATION_BLEND);
+
+void fill_palette(CRGB* L, uint16_t N,
+ uint8_t startIndex, uint8_t incIndex,
+ const CRGBPalette256& pal,
+ uint8_t brightness=255,
+ TInterpolationType interpType=INTERPOLATION_NONE);
+
+
#endif
diff --git a/preview_changes.txt b/preview_changes.txt
index da565b0e..88a9f9bc 100644
--- a/preview_changes.txt
+++ b/preview_changes.txt
@@ -19,3 +19,4 @@
* Added fill_gradient
* Added inoise8/inoise16 and example program
* Added LEDS.countFPS() for debugging framerate counts. Bit rough at the moment, thought
+* Added Palettes and associated functions and presets