diff --git a/ReadMe.md b/ReadMe.md
index 51017a9..ab8d6fd 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -12,6 +12,7 @@ Please read this best practices link before connecting your NeoPixels, it will s
For quick questions and support:
* [Try the new Github Discussions](https://github.com/Makuna/NeoPixelBus/discussions)
+* [Discord NeoPixelBus Invitation](https://discord.gg/c6FrysvZyV) or if you are already a member of [Discord Server NeoPixelBus](https://discord.com/channels/789177382221119519/789177382221119521)
* Or jump on Gitter
[](https://gitter.im/Makuna/NeoPixelBus?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
diff --git a/keywords.txt b/keywords.txt
index ca68e07..0508346 100644
--- a/keywords.txt
+++ b/keywords.txt
@@ -10,6 +10,8 @@ NeoPixelBus KEYWORD1
NeoPixelSegmentBus KEYWORD1
RgbwColor KEYWORD1
RgbColor KEYWORD1
+Rgb16Color KEYWORD1
+Rgb48Color KEYWORD1
HslColor KEYWORD1
HsbColor KEYWORD1
HtmlColor KEYWORD1
diff --git a/src/NeoPixelBus.h b/src/NeoPixelBus.h
index a9ec865..a80a0fd 100644
--- a/src/NeoPixelBus.h
+++ b/src/NeoPixelBus.h
@@ -51,9 +51,13 @@ License along with NeoPixel. If not, see
#include "internal/NeoSettings.h"
#include "internal/RgbColor.h"
+#include "internal/Rgb16Color.h"
+#include "internal/Rgb48Color.h"
+
#include "internal/HslColor.h"
#include "internal/HsbColor.h"
#include "internal/HtmlColor.h"
+
#include "internal/RgbwColor.h"
#include "internal/SegmentDigit.h"
diff --git a/src/internal/HsbColor.cpp b/src/internal/HsbColor.cpp
index e47912f..146ddb8 100644
--- a/src/internal/HsbColor.cpp
+++ b/src/internal/HsbColor.cpp
@@ -25,22 +25,17 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#include "RgbColor.h"
+#include "Rgb48Color.h"
#include "HsbColor.h"
-
-HsbColor::HsbColor(const RgbColor& color)
+void HsbColor::_RgbToHsb(float r, float g, float b, HsbColor* color)
{
- // convert colors to float between (0.0 - 1.0)
- float r = color.R / 255.0f;
- float g = color.G / 255.0f;
- float b = color.B / 255.0f;
-
float max = (r > g && r > b) ? r : (g > b) ? g : b;
- float min = (r < g && r < b) ? r : (g < b) ? g : b;
+ float min = (r < g&& r < b) ? r : (g < b) ? g : b;
float d = max - min;
- float h = 0.0;
+ float h = 0.0;
float v = max;
float s = (v == 0.0f) ? 0 : (d / v);
@@ -62,7 +57,27 @@ HsbColor::HsbColor(const RgbColor& color)
}
- H = h;
- S = s;
- B = v;
+ color->H = h;
+ color->S = s;
+ color->B = v;
+}
+
+HsbColor::HsbColor(const RgbColor& color)
+{
+ // convert colors to float between (0.0 - 1.0)
+ float r = color.R / 255.0f;
+ float g = color.G / 255.0f;
+ float b = color.B / 255.0f;
+
+ _RgbToHsb(r, g, b, this);
+}
+
+HsbColor::HsbColor(const Rgb48Color& color)
+{
+ // convert colors to float between (0.0 - 1.0)
+ float r = color.R / 65535.0f;
+ float g = color.G / 65535.0f;
+ float b = color.B / 65535.0f;
+
+ _RgbToHsb(r, g, b, this);
}
diff --git a/src/internal/HsbColor.h b/src/internal/HsbColor.h
index 4d0bdfa..939d5a1 100644
--- a/src/internal/HsbColor.h
+++ b/src/internal/HsbColor.h
@@ -48,6 +48,11 @@ struct HsbColor
// ------------------------------------------------------------------------
HsbColor(const RgbColor& color);
+ // ------------------------------------------------------------------------
+ // Construct a HsbColor using Rgb48Color
+ // ------------------------------------------------------------------------
+ HsbColor(const Rgb48Color& color);
+
// ------------------------------------------------------------------------
// Construct a HsbColor that will have its values set in latter operations
// CAUTION: The H,S,B members are not initialized and may not be consistent
@@ -109,5 +114,8 @@ struct HsbColor
float H;
float S;
float B;
+
+private:
+ static void _RgbToHsb(float r, float g, float b, HsbColor* color);
};
diff --git a/src/internal/HslColor.cpp b/src/internal/HslColor.cpp
index ce9b238..92ae687 100644
--- a/src/internal/HslColor.cpp
+++ b/src/internal/HslColor.cpp
@@ -26,16 +26,11 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#include "RgbColor.h"
+#include "Rgb48Color.h"
#include "HslColor.h"
-
-HslColor::HslColor(const RgbColor& color)
+void HslColor::_RgbToHsl(float r, float g, float b, HslColor* color)
{
- // convert colors to float between (0.0 - 1.0)
- float r = color.R / 255.0f;
- float g = color.G / 255.0f;
- float b = color.B / 255.0f;
-
float max = (r > g && r > b) ? r : (g > b) ? g : b;
float min = (r < g && r < b) ? r : (g < b) ? g : b;
@@ -66,7 +61,27 @@ HslColor::HslColor(const RgbColor& color)
h /= 6.0f;
}
- H = h;
- S = s;
- L = l;
+ color->H = h;
+ color->S = s;
+ color->L = l;
+}
+
+HslColor::HslColor(const RgbColor& color)
+{
+ // convert colors to float between (0.0 - 1.0)
+ float r = color.R / 255.0f;
+ float g = color.G / 255.0f;
+ float b = color.B / 255.0f;
+
+ _RgbToHsl(r, g, b, this);
+}
+
+HslColor::HslColor(const Rgb48Color& color)
+{
+ // convert colors to float between (0.0 - 1.0)
+ float r = color.R / 65535.0f;
+ float g = color.G / 65535.0f;
+ float b = color.B / 65535.0f;
+
+ _RgbToHsl(r, g, b, this);
}
diff --git a/src/internal/HslColor.h b/src/internal/HslColor.h
index f6988bd..3555a5c 100644
--- a/src/internal/HslColor.h
+++ b/src/internal/HslColor.h
@@ -49,6 +49,11 @@ struct HslColor
// ------------------------------------------------------------------------
HslColor(const RgbColor& color);
+ // ------------------------------------------------------------------------
+ // Construct a HslColor using Rgb48Color
+ // ------------------------------------------------------------------------
+ HslColor(const Rgb48Color& color);
+
// ------------------------------------------------------------------------
// Construct a HslColor that will have its values set in latter operations
// CAUTION: The H,S,L members are not initialized and may not be consistent
@@ -109,5 +114,9 @@ struct HslColor
float H;
float S;
float L;
+
+private:
+ static void _RgbToHsl(float r, float g, float b, HslColor* color);
+
};
diff --git a/src/internal/Rgb16Color.h b/src/internal/Rgb16Color.h
new file mode 100644
index 0000000..c038c4c
--- /dev/null
+++ b/src/internal/Rgb16Color.h
@@ -0,0 +1,272 @@
+/*-------------------------------------------------------------------------
+Rgb16Color provides a color object that stores in only 16 bits, aka 565 format
+
+Written by Michael C. Miller.
+
+I invest time and resources providing this open source code,
+please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
+
+-------------------------------------------------------------------------
+This file is part of the Makuna/NeoPixelBus library.
+
+NeoPixelBus is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation, either version 3 of
+the License, or (at your option) any later version.
+
+NeoPixelBus is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with NeoPixel. If not, see
+.
+-------------------------------------------------------------------------*/
+#pragma once
+
+#include
+#include "NeoSettings.h"
+#include "RgbColorBase.h"
+
+
+// ------------------------------------------------------------------------
+// Rgb16Color represents a color object that is represented by Red, Green, Blue
+// component values stored in a single 16 bit value using 565 model.
+// It contains helpful color routines to manipulate the color.
+// ------------------------------------------------------------------------
+struct Rgb16Color : RgbColorBase
+{
+ typedef NeoRgbCurrentSettings SettingsObject;
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb16Color using R, G, B values (0-255)
+ // ------------------------------------------------------------------------
+ Rgb16Color(uint8_t r, uint8_t g, uint8_t b)
+ {
+ setR(r);
+ setG(g);
+ setB(b);
+ };
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb16Color using a single brightness value (0-255)
+ // This works well for creating gray tone colors
+ // (0) = black, (255) = white, (128) = gray
+ // ------------------------------------------------------------------------
+ Rgb16Color(uint8_t brightness)
+ {
+ setR(brightness);
+ setG(brightness);
+ setB(brightness);
+ };
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb16Color using HtmlColor
+ // ------------------------------------------------------------------------
+ Rgb16Color(const HtmlColor& color)
+ {
+ RgbColor converted = color;
+
+ setR(converted.R);
+ setG(converted.G);
+ setB(converted.B);
+ };
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb16Color using HslColor
+ // ------------------------------------------------------------------------
+ Rgb16Color(const HslColor& color)
+ {
+ RgbColor converted = color;
+
+ setR(converted.R);
+ setG(converted.G);
+ setB(converted.B);
+ };
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb16Color using HsbColor
+ // ------------------------------------------------------------------------
+ Rgb16Color(const HsbColor& color)
+ {
+ RgbColor converted = color;
+
+ setR(converted.R);
+ setG(converted.G);
+ setB(converted.B);
+ };
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb16Color that will have its values set in latter operations
+ // CAUTION: The _c members are not initialized and may not be consistent
+ // ------------------------------------------------------------------------
+ Rgb16Color()
+ {
+ };
+
+ // ------------------------------------------------------------------------
+ // properties
+ // ------------------------------------------------------------------------
+ void setR(uint8_t r)
+ {
+ _c &= 0x07ff;
+ _c |= ((r & 0xf8) << 8);
+ };
+ uint8_t getR() const
+ {
+ return (_c & 0xf800) >> 8;
+ };
+
+ void setG(uint8_t g)
+ {
+ _c &= 0xf81f;
+ _c |= ((g & 0xfe) << 3);
+ };
+ uint8_t getG() const
+ {
+ return (_c & 0x07e0) >> 3;
+ };
+
+ void setB(uint8_t b)
+ {
+ _c &= 0xffe0;
+ _c |= ((b & 0xf8) >> 3);
+ };
+ uint8_t getB() const
+ {
+ return (_c & 0x001f) << 3;
+ };
+
+
+ // ------------------------------------------------------------------------
+ // Comparison operators
+ // ------------------------------------------------------------------------
+ bool operator==(const Rgb16Color& other) const
+ {
+ return (_c == other._c);
+ };
+
+ bool operator!=(const Rgb16Color& other) const
+ {
+ return !(*this == other);
+ };
+
+ // ------------------------------------------------------------------------
+ // CalculateBrightness will calculate the overall brightness
+ // NOTE: This is a simple linear brightness
+ // ------------------------------------------------------------------------
+ uint8_t CalculateBrightness() const
+ {
+ RgbColor converted = *this;
+ return converted.CalculateBrightness();
+ };
+
+ // ------------------------------------------------------------------------
+ // Dim will return a new color that is blended to black with the given ratio
+ // ratio - (0-255) where 255 will return the original color and 0 will return black
+ //
+ // NOTE: This is a simple linear blend
+ // ------------------------------------------------------------------------
+ Rgb16Color Dim(uint8_t ratio) const
+ {
+ RgbColor converted = *this;
+ RgbColor result = converted.Dim(ratio);
+
+ return Rgb16Color(result.R, result.G, result.B);
+ };
+
+ // ------------------------------------------------------------------------
+ // Brighten will return a new color that is blended to white with the given ratio
+ // ratio - (0-255) where 255 will return the original color and 0 will return white
+ //
+ // NOTE: This is a simple linear blend
+ // ------------------------------------------------------------------------
+ Rgb16Color Brighten(uint8_t ratio) const
+ {
+ RgbColor converted = *this;
+ RgbColor result = converted.Brighten(ratio);
+
+ return Rgb16Color(result.R, result.G, result.B);
+ };
+
+ // ------------------------------------------------------------------------
+ // Darken will adjust the color by the given delta toward black
+ // NOTE: This is a simple linear change
+ // delta - (0-255) the amount to dim the color
+ // ------------------------------------------------------------------------
+ void Darken(uint8_t delta)
+ {
+ RgbColor converted = *this;
+
+ converted.Darken(delta);
+ setR(converted.R);
+ setG(converted.G);
+ setB(converted.B);
+ };
+
+ // ------------------------------------------------------------------------
+ // Lighten will adjust the color by the given delta toward white
+ // NOTE: This is a simple linear change
+ // delta - (0-255) the amount to lighten the color
+ // ------------------------------------------------------------------------
+ void Lighten(uint8_t delta)
+ {
+ RgbColor converted = *this;
+
+ converted.Lighten(delta);
+ setR(converted.R);
+ setG(converted.G);
+ setB(converted.B);
+ };
+
+ // ------------------------------------------------------------------------
+ // LinearBlend between two colors by the amount defined by progress variable
+ // left - the color to start the blend at
+ // right - the color to end the blend at
+ // progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
+ // and a value between will blend the color weighted linearly between them
+ // ------------------------------------------------------------------------
+ static Rgb16Color LinearBlend(const Rgb16Color& left, const Rgb16Color& right, float progress)
+ {
+ RgbColor result = RgbColor::LinearBlend(left, right, progress);
+
+ return Rgb16Color(result.R, result.G, result.B);
+ };
+
+ // ------------------------------------------------------------------------
+ // BilinearBlend between four colors by the amount defined by 2d variable
+ // c00 - upper left quadrant color
+ // c01 - upper right quadrant color
+ // c10 - lower left quadrant color
+ // c11 - lower right quadrant color
+ // x - unit value (0.0 - 1.0) that defines the blend progress in horizontal space
+ // y - unit value (0.0 - 1.0) that defines the blend progress in vertical space
+ // ------------------------------------------------------------------------
+ static Rgb16Color BilinearBlend(const Rgb16Color& c00,
+ const Rgb16Color& c01,
+ const Rgb16Color& c10,
+ const Rgb16Color& c11,
+ float x,
+ float y)
+ {
+ RgbColor result = RgbColor::BilinearBlend(c00, c01, c10, c11, x, y);
+
+ return Rgb16Color(result.R, result.G, result.B);
+ };
+
+ uint32_t CalcTotalTenthMilliAmpere(const SettingsObject& settings)
+ {
+ auto total = 0;
+
+ total += getR() * settings.RedTenthMilliAmpere / 255;
+ total += getG() * settings.GreenTenthMilliAmpere / 255;
+ total += getB() * settings.BlueTenthMilliAmpere / 255;
+
+ return total;
+ };
+
+protected:
+ uint16_t _c;
+};
+
diff --git a/src/internal/Rgb48Color.cpp b/src/internal/Rgb48Color.cpp
new file mode 100644
index 0000000..3743ac5
--- /dev/null
+++ b/src/internal/Rgb48Color.cpp
@@ -0,0 +1,170 @@
+/*-------------------------------------------------------------------------
+Rgb48Color provides a color object that can be directly consumed by NeoPixelBus
+
+Written by Michael C. Miller.
+
+I invest time and resources providing this open source code,
+please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
+
+-------------------------------------------------------------------------
+This file is part of the Makuna/NeoPixelBus library.
+
+NeoPixelBus is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation, either version 3 of
+the License, or (at your option) any later version.
+
+NeoPixelBus is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with NeoPixel. If not, see
+.
+-------------------------------------------------------------------------*/
+
+#include "Rgb48Color.h"
+#include "RgbColor.h"
+#include "HslColor.h"
+#include "HsbColor.h"
+#include "HtmlColor.h"
+
+Rgb48Color::Rgb48Color(const HtmlColor& color)
+{
+ uint32_t temp = color.Color;
+
+ B = (temp & 0xff);
+ temp = temp >> 8;
+ G = (temp & 0xff);
+ temp = temp >> 8;
+ R = (temp & 0xff);
+};
+
+Rgb48Color::Rgb48Color(const HslColor& color)
+{
+ float r;
+ float g;
+ float b;
+
+ _HslToRgb(color, &r, &g, &b);
+
+ R = (uint16_t)(r * Max);
+ G = (uint16_t)(g * Max);
+ B = (uint16_t)(b * Max);
+}
+
+Rgb48Color::Rgb48Color(const HsbColor& color)
+{
+ float r;
+ float g;
+ float b;
+
+ _HsbToRgb(color, &r, &g, &b);
+
+ R = (uint16_t)(r * Max);
+ G = (uint16_t)(g * Max);
+ B = (uint16_t)(b * Max);
+}
+
+uint16_t Rgb48Color::CalculateBrightness() const
+{
+ return (uint16_t)(((uint32_t)R + (uint32_t)G + (uint32_t)B) / 3);
+}
+
+Rgb48Color Rgb48Color::Dim(uint16_t ratio) const
+{
+ // specifically avoids float math
+ return Rgb48Color(_elementDim(R, ratio), _elementDim(G, ratio), _elementDim(B, ratio));
+}
+
+Rgb48Color Rgb48Color::Brighten(uint16_t ratio) const
+{
+ // specifically avoids float math
+ return Rgb48Color(_elementBrighten(R, ratio), _elementBrighten(G, ratio), _elementBrighten(B, ratio));
+}
+
+void Rgb48Color::Darken(uint16_t delta)
+{
+ if (R > delta)
+ {
+ R -= delta;
+ }
+ else
+ {
+ R = 0;
+ }
+
+ if (G > delta)
+ {
+ G -= delta;
+ }
+ else
+ {
+ G = 0;
+ }
+
+ if (B > delta)
+ {
+ B -= delta;
+ }
+ else
+ {
+ B = 0;
+ }
+}
+
+void Rgb48Color::Lighten(uint16_t delta)
+{
+ if (R < Max - delta)
+ {
+ R += delta;
+ }
+ else
+ {
+ R = Max;
+ }
+
+ if (G < Max - delta)
+ {
+ G += delta;
+ }
+ else
+ {
+ G = Max;
+ }
+
+ if (B < Max - delta)
+ {
+ B += delta;
+ }
+ else
+ {
+ B = Max;
+ }
+}
+
+Rgb48Color Rgb48Color::LinearBlend(const Rgb48Color& left, const Rgb48Color& right, float progress)
+{
+ return Rgb48Color( left.R + ((right.R - left.R) * progress),
+ left.G + ((right.G - left.G) * progress),
+ left.B + ((right.B - left.B) * progress));
+}
+
+Rgb48Color Rgb48Color::BilinearBlend(const Rgb48Color& c00,
+ const Rgb48Color& c01,
+ const Rgb48Color& c10,
+ const Rgb48Color& c11,
+ float x,
+ float y)
+{
+ float v00 = (1.0f - x) * (1.0f - y);
+ float v10 = x * (1.0f - y);
+ float v01 = (1.0f - x) * y;
+ float v11 = x * y;
+
+ return Rgb48Color(
+ c00.R * v00 + c10.R * v10 + c01.R * v01 + c11.R * v11,
+ c00.G * v00 + c10.G * v10 + c01.G * v01 + c11.G * v11,
+ c00.B * v00 + c10.B * v10 + c01.B * v01 + c11.B * v11);
+}
\ No newline at end of file
diff --git a/src/internal/Rgb48Color.h b/src/internal/Rgb48Color.h
new file mode 100644
index 0000000..eb35142
--- /dev/null
+++ b/src/internal/Rgb48Color.h
@@ -0,0 +1,210 @@
+/*-------------------------------------------------------------------------
+Rgb48Color provides a color object that contains 16bit color elements
+
+Written by Michael C. Miller.
+
+I invest time and resources providing this open source code,
+please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
+
+-------------------------------------------------------------------------
+This file is part of the Makuna/NeoPixelBus library.
+
+NeoPixelBus is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation, either version 3 of
+the License, or (at your option) any later version.
+
+NeoPixelBus is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with NeoPixel. If not, see
+.
+-------------------------------------------------------------------------*/
+#pragma once
+
+#include
+#include "NeoSettings.h"
+#include "RgbColorBase.h"
+#include "RgbColor.h"
+
+
+// ------------------------------------------------------------------------
+// Rgb48Color represents a color object that is represented by Red, Green, Blue
+// component values. It contains helpful color routines to manipulate the
+// color.
+// ------------------------------------------------------------------------
+struct Rgb48Color : RgbColorBase
+{
+ typedef NeoRgbCurrentSettings SettingsObject;
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb48Color using R, G, B values (0-65535)
+ // ------------------------------------------------------------------------
+ Rgb48Color(uint16_t r, uint16_t g, uint16_t b) :
+ R(r), G(g), B(b)
+ {
+ };
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb48Color using a single brightness value (0-65535)
+ // This works well for creating gray tone colors
+ // (0) = black, (65535) = white, (32768) = gray
+ // ------------------------------------------------------------------------
+ Rgb48Color(uint16_t brightness) :
+ R(brightness), G(brightness), B(brightness)
+ {
+ };
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb48Color using RgbColor
+ // ------------------------------------------------------------------------
+ Rgb48Color(const RgbColor& color)
+ {
+ R = (color.R == 0) ? 0 : (color.R << 8 | 0xff);
+ G = (color.G == 0) ? 0 : (color.G << 8 | 0xff);
+ B = (color.B == 0) ? 0 : (color.B << 8 | 0xff);
+ }
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb48Color using HtmlColor
+ // ------------------------------------------------------------------------
+ Rgb48Color(const HtmlColor& color);
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb48Color using HslColor
+ // ------------------------------------------------------------------------
+ Rgb48Color(const HslColor& color);
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb48Color using HsbColor
+ // ------------------------------------------------------------------------
+ Rgb48Color(const HsbColor& color);
+
+ // ------------------------------------------------------------------------
+ // Construct a Rgb48Color that will have its values set in latter operations
+ // CAUTION: The R,G,B members are not initialized and may not be consistent
+ // ------------------------------------------------------------------------
+ Rgb48Color()
+ {
+ };
+
+ // ------------------------------------------------------------------------
+ // Comparison operators
+ // ------------------------------------------------------------------------
+ bool operator==(const Rgb48Color& other) const
+ {
+ return (R == other.R && G == other.G && B == other.B);
+ };
+
+ bool operator!=(const Rgb48Color& other) const
+ {
+ return !(*this == other);
+ };
+
+ // ------------------------------------------------------------------------
+ // CalculateBrightness will calculate the overall brightness
+ // NOTE: This is a simple linear brightness
+ // ------------------------------------------------------------------------
+ uint16_t CalculateBrightness() const;
+
+ // ------------------------------------------------------------------------
+ // Dim will return a new color that is blended to black with the given ratio
+ // ratio - (0-65535) where 65535 will return the original color and 0 will return black
+ //
+ // NOTE: This is a simple linear blend
+ // ------------------------------------------------------------------------
+ Rgb48Color Dim(uint16_t ratio) const;
+
+ // ------------------------------------------------------------------------
+ // Brighten will return a new color that is blended to white with the given ratio
+ // ratio - (0-65535) where 65535 will return the original color and 0 will return white
+ //
+ // NOTE: This is a simple linear blend
+ // ------------------------------------------------------------------------
+ Rgb48Color Brighten(uint16_t ratio) const;
+
+ // ------------------------------------------------------------------------
+ // Darken will adjust the color by the given delta toward black
+ // NOTE: This is a simple linear change
+ // delta - (0-65535) the amount to dim the color
+ // ------------------------------------------------------------------------
+ void Darken(uint16_t delta);
+
+ // ------------------------------------------------------------------------
+ // Lighten will adjust the color by the given delta toward white
+ // NOTE: This is a simple linear change
+ // delta - (0-65535) the amount to lighten the color
+ // ------------------------------------------------------------------------
+ void Lighten(uint16_t delta);
+
+ // ------------------------------------------------------------------------
+ // LinearBlend between two colors by the amount defined by progress variable
+ // left - the color to start the blend at
+ // right - the color to end the blend at
+ // progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
+ // and a value between will blend the color weighted linearly between them
+ // ------------------------------------------------------------------------
+ static Rgb48Color LinearBlend(const Rgb48Color& left, const Rgb48Color& right, float progress);
+
+ // ------------------------------------------------------------------------
+ // BilinearBlend between four colors by the amount defined by 2d variable
+ // c00 - upper left quadrant color
+ // c01 - upper right quadrant color
+ // c10 - lower left quadrant color
+ // c11 - lower right quadrant color
+ // x - unit value (0.0 - 1.0) that defines the blend progress in horizontal space
+ // y - unit value (0.0 - 1.0) that defines the blend progress in vertical space
+ // ------------------------------------------------------------------------
+ static Rgb48Color BilinearBlend(const Rgb48Color& c00,
+ const Rgb48Color& c01,
+ const Rgb48Color& c10,
+ const Rgb48Color& c11,
+ float x,
+ float y);
+
+ uint32_t CalcTotalTenthMilliAmpere(const SettingsObject& settings)
+ {
+ auto total = 0;
+
+ total += R * settings.RedTenthMilliAmpere / Max;
+ total += G * settings.GreenTenthMilliAmpere / Max;
+ total += B * settings.BlueTenthMilliAmpere / Max;
+
+ return total;
+ }
+
+ // ------------------------------------------------------------------------
+ // Red, Green, Blue color members (0-65535) where
+ // (0,0,0) is black and (65535,65535,65535) is white
+ // ------------------------------------------------------------------------
+ uint16_t R;
+ uint16_t G;
+ uint16_t B;
+
+ const static uint16_t Max = 65535;
+
+private:
+ inline static uint16_t _elementDim(uint16_t value, uint16_t ratio)
+ {
+ return (static_cast(value) * (static_cast(ratio) + 1)) >> 8;
+ }
+
+ inline static uint16_t _elementBrighten(uint16_t value, uint16_t ratio)
+ {
+ uint32_t element = ((static_cast(value) + 1) << 8) / (static_cast(ratio) + 1);
+
+ if (element > Max)
+ {
+ element = Max;
+ }
+ else
+ {
+ element -= 1;
+ }
+ return element;
+ }
+};
+
diff --git a/src/internal/RgbColor.cpp b/src/internal/RgbColor.cpp
index 30a7811..c2692ed 100644
--- a/src/internal/RgbColor.cpp
+++ b/src/internal/RgbColor.cpp
@@ -25,27 +25,17 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#include "RgbColor.h"
+#include "Rgb16Color.h"
+#include "Rgb48Color.h"
#include "HslColor.h"
#include "HsbColor.h"
#include "HtmlColor.h"
-static float _CalcColor(float p, float q, float t)
+RgbColor::RgbColor(const Rgb16Color& color)
{
- if (t < 0.0f)
- t += 1.0f;
- if (t > 1.0f)
- t -= 1.0f;
-
- if (t < 1.0f / 6.0f)
- return p + (q - p) * 6.0f * t;
-
- if (t < 0.5f)
- return q;
-
- if (t < 2.0f / 3.0f)
- return p + ((q - p) * (2.0f / 3.0f - t) * 6.0f);
-
- return p;
+ R = color.getR();
+ G = color.getG();
+ B = color.getB();
}
RgbColor::RgbColor(const HtmlColor& color)
@@ -65,27 +55,11 @@ RgbColor::RgbColor(const HslColor& color)
float g;
float b;
- float h = color.H;
- float s = color.S;
- float l = color.L;
+ _HslToRgb(color, &r, &g, &b);
-
- if (color.S == 0.0f || color.L == 0.0f)
- {
- r = g = b = l; // achromatic or black
- }
- else
- {
- float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s);
- float p = 2.0f * l - q;
- r = _CalcColor(p, q, h + 1.0f / 3.0f);
- g = _CalcColor(p, q, h);
- b = _CalcColor(p, q, h - 1.0f / 3.0f);
- }
-
- R = (uint8_t)(r * 255.0f);
- G = (uint8_t)(g * 255.0f);
- B = (uint8_t)(b * 255.0f);
+ R = (uint8_t)(r * Max);
+ G = (uint8_t)(g * Max);
+ B = (uint8_t)(b * Max);
}
RgbColor::RgbColor(const HsbColor& color)
@@ -94,68 +68,11 @@ RgbColor::RgbColor(const HsbColor& color)
float g;
float b;
- float h = color.H;
- float s = color.S;
- float v = color.B;
+ _HsbToRgb(color, &r, &g, &b);
- if (color.S == 0.0f)
- {
- r = g = b = v; // achromatic or black
- }
- else
- {
- if (h < 0.0f)
- {
- h += 1.0f;
- }
- else if (h >= 1.0f)
- {
- h -= 1.0f;
- }
- h *= 6.0f;
- int i = (int)h;
- float f = h - i;
- float q = v * (1.0f - s * f);
- float p = v * (1.0f - s);
- float t = v * (1.0f - s * (1.0f - f));
- switch (i)
- {
- case 0:
- r = v;
- g = t;
- b = p;
- break;
- case 1:
- r = q;
- g = v;
- b = p;
- break;
- case 2:
- r = p;
- g = v;
- b = t;
- break;
- case 3:
- r = p;
- g = q;
- b = v;
- break;
- case 4:
- r = t;
- g = p;
- b = v;
- break;
- default:
- r = v;
- g = p;
- b = q;
- break;
- }
- }
-
- R = (uint8_t)(r * 255.0f);
- G = (uint8_t)(g * 255.0f);
- B = (uint8_t)(b * 255.0f);
+ R = (uint8_t)(r * Max);
+ G = (uint8_t)(g * Max);
+ B = (uint8_t)(b * Max);
}
uint8_t RgbColor::CalculateBrightness() const
@@ -207,31 +124,31 @@ void RgbColor::Darken(uint8_t delta)
void RgbColor::Lighten(uint8_t delta)
{
- if (R < 255 - delta)
+ if (R < Max - delta)
{
R += delta;
}
else
{
- R = 255;
+ R = Max;
}
- if (G < 255 - delta)
+ if (G < Max - delta)
{
G += delta;
}
else
{
- G = 255;
+ G = Max;
}
- if (B < 255 - delta)
+ if (B < Max - delta)
{
B += delta;
}
else
{
- B = 255;
+ B = Max;
}
}
diff --git a/src/internal/RgbColor.h b/src/internal/RgbColor.h
index b50857b..cdbcf22 100644
--- a/src/internal/RgbColor.h
+++ b/src/internal/RgbColor.h
@@ -27,17 +27,15 @@ License along with NeoPixel. If not, see
#include
#include "NeoSettings.h"
+#include "RgbColorBase.h"
-struct HslColor;
-struct HsbColor;
-struct HtmlColor;
// ------------------------------------------------------------------------
// RgbColor represents a color object that is represented by Red, Green, Blue
// component values. It contains helpful color routines to manipulate the
// color.
// ------------------------------------------------------------------------
-struct RgbColor
+struct RgbColor : RgbColorBase
{
typedef NeoRgbCurrentSettings SettingsObject;
@@ -59,6 +57,11 @@ struct RgbColor
{
};
+ // ------------------------------------------------------------------------
+ // Construct a RgbColor using Rgb16Color
+ // ------------------------------------------------------------------------
+ RgbColor(const Rgb16Color& color);
+
// ------------------------------------------------------------------------
// Construct a RgbColor using HtmlColor
// ------------------------------------------------------------------------
@@ -74,6 +77,7 @@ struct RgbColor
// ------------------------------------------------------------------------
RgbColor(const HsbColor& color);
+
// ------------------------------------------------------------------------
// Construct a RgbColor that will have its values set in latter operations
// CAUTION: The R,G,B members are not initialized and may not be consistent
@@ -160,9 +164,9 @@ struct RgbColor
{
auto total = 0;
- total += R * settings.RedTenthMilliAmpere / 255;
- total += G * settings.GreenTenthMilliAmpere / 255;
- total += B * settings.BlueTenthMilliAmpere / 255;
+ total += R * settings.RedTenthMilliAmpere / Max;
+ total += G * settings.GreenTenthMilliAmpere / Max;
+ total += B * settings.BlueTenthMilliAmpere / Max;
return total;
}
@@ -175,6 +179,8 @@ struct RgbColor
uint8_t G;
uint8_t B;
+ const static uint8_t Max = 255;
+
private:
inline static uint8_t _elementDim(uint8_t value, uint8_t ratio)
{
@@ -185,9 +191,9 @@ private:
{
uint16_t element = ((static_cast(value) + 1) << 8) / (static_cast(ratio) + 1);
- if (element > 255)
+ if (element > Max)
{
- element = 255;
+ element = Max;
}
else
{
diff --git a/src/internal/RgbColorBase.cpp b/src/internal/RgbColorBase.cpp
new file mode 100644
index 0000000..ad0eb82
--- /dev/null
+++ b/src/internal/RgbColorBase.cpp
@@ -0,0 +1,134 @@
+/*-------------------------------------------------------------------------
+RgbColorBase provides a RGB color object common support
+
+Written by Michael C. Miller.
+
+I invest time and resources providing this open source code,
+please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
+
+-------------------------------------------------------------------------
+This file is part of the Makuna/NeoPixelBus library.
+
+NeoPixelBus is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation, either version 3 of
+the License, or (at your option) any later version.
+
+NeoPixelBus is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with NeoPixel. If not, see
+.
+-------------------------------------------------------------------------*/
+
+#include "RgbColorBase.h"
+#include "RgbColor.h"
+#include "Rgb48Color.h"
+#include "HslColor.h"
+#include "HsbColor.h"
+#include "HtmlColor.h"
+
+float RgbColorBase::_CalcColor(float p, float q, float t)
+{
+ if (t < 0.0f)
+ t += 1.0f;
+ if (t > 1.0f)
+ t -= 1.0f;
+
+ if (t < 1.0f / 6.0f)
+ return p + (q - p) * 6.0f * t;
+
+ if (t < 0.5f)
+ return q;
+
+ if (t < 2.0f / 3.0f)
+ return p + ((q - p) * (2.0f / 3.0f - t) * 6.0f);
+
+ return p;
+}
+
+void RgbColorBase::_HslToRgb(const HslColor& color, float* r, float* g, float* b)
+{
+ float h = color.H;
+ float s = color.S;
+ float l = color.L;
+
+
+ if (color.S == 0.0f || color.L == 0.0f)
+ {
+ *r = *g = *b = l; // achromatic or black
+ }
+ else
+ {
+ float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s);
+ float p = 2.0f * l - q;
+ *r = _CalcColor(p, q, h + 1.0f / 3.0f);
+ *g = _CalcColor(p, q, h);
+ *b = _CalcColor(p, q, h - 1.0f / 3.0f);
+ }
+}
+
+void RgbColorBase::_HsbToRgb(const HsbColor& color, float* r, float* g, float* b)
+{
+ float h = color.H;
+ float s = color.S;
+ float v = color.B;
+
+ if (color.S == 0.0f)
+ {
+ *r = *g = *b = v; // achromatic or black
+ }
+ else
+ {
+ if (h < 0.0f)
+ {
+ h += 1.0f;
+ }
+ else if (h >= 1.0f)
+ {
+ h -= 1.0f;
+ }
+ h *= 6.0f;
+ int i = (int)h;
+ float f = h - i;
+ float q = v * (1.0f - s * f);
+ float p = v * (1.0f - s);
+ float t = v * (1.0f - s * (1.0f - f));
+ switch (i)
+ {
+ case 0:
+ *r = v;
+ *g = t;
+ *b = p;
+ break;
+ case 1:
+ *r = q;
+ *g = v;
+ *b = p;
+ break;
+ case 2:
+ *r = p;
+ *g = v;
+ *b = t;
+ break;
+ case 3:
+ *r = p;
+ *g = q;
+ *b = v;
+ break;
+ case 4:
+ *r = t;
+ *g = p;
+ *b = v;
+ break;
+ default:
+ *r = v;
+ *g = p;
+ *b = q;
+ break;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/internal/RgbColorBase.h b/src/internal/RgbColorBase.h
new file mode 100644
index 0000000..689fe88
--- /dev/null
+++ b/src/internal/RgbColorBase.h
@@ -0,0 +1,42 @@
+/*-------------------------------------------------------------------------
+RgbColorBase provides a RGB color object common support
+
+Written by Michael C. Miller.
+
+I invest time and resources providing this open source code,
+please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
+
+-------------------------------------------------------------------------
+This file is part of the Makuna/NeoPixelBus library.
+
+NeoPixelBus is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation, either version 3 of
+the License, or (at your option) any later version.
+
+NeoPixelBus is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with NeoPixel. If not, see
+.
+-------------------------------------------------------------------------*/
+#pragma once
+
+struct HslColor;
+struct HsbColor;
+struct HtmlColor;
+struct Rgb16Color;
+
+struct RgbColorBase
+{
+
+protected:
+ static float _CalcColor(float p, float q, float t);
+
+ static void _HslToRgb(const HslColor& color, float* r, float* g, float* b);
+
+ static void _HsbToRgb(const HsbColor& color, float* r, float* g, float* b);
+};
\ No newline at end of file
diff --git a/src/internal/RgbwColor.cpp b/src/internal/RgbwColor.cpp
index cb9681f..d73c7c9 100644
--- a/src/internal/RgbwColor.cpp
+++ b/src/internal/RgbwColor.cpp
@@ -25,6 +25,7 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#include "RgbColor.h"
+#include "Rgb48Color.h"
#include "HslColor.h"
#include "HsbColor.h"
#include "RgbwColor.h"