This commit is contained in:
Michael Miller
2021-10-10 17:45:48 -07:00
committed by GitHub
parent 0913134003
commit 2040a4837d
10 changed files with 737 additions and 53 deletions

View File

@@ -12,6 +12,7 @@ RgbwColor KEYWORD1
RgbColor KEYWORD1
Rgb16Color KEYWORD1
Rgb48Color KEYWORD1
Rgbw64Color KEYWORD1
HslColor KEYWORD1
HsbColor KEYWORD1
HtmlColor KEYWORD1
@@ -25,6 +26,10 @@ NeoRgbwFeature KEYWORD1
NeoRgbFeature KEYWORD1
NeoBrgFeature KEYWORD1
NeoRbgFeature KEYWORD1
NeoRgbw64Feature KEYWORD1
NeoRgb48Feature KEYWORD1
NeoRgbUcs8903Feature KEYWORD1
NeoRgbwUcs8904Feature KEYWORD1
NeoWrgbTm1814Feature KEYWORD1
NeoRgbTm1914Feature KEYWORD1
NeoGrbTm1914Feature KEYWORD1

View File

@@ -59,6 +59,8 @@ License along with NeoPixel. If not, see
#include "internal/HtmlColor.h"
#include "internal/RgbwColor.h"
#include "internal/Rgbw64Color.h"
#include "internal/SegmentDigit.h"
#include "internal/NeoColorFeatures.h"

View File

@@ -26,7 +26,7 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#pragma once
class Neo3Elements
class Neo3ByteElements
{
public:
static const size_t PixelSize = 3;
@@ -64,7 +64,7 @@ public:
static void movePixelsInc_P(uint8_t* pPixelDest, PGM_VOID_P pPixelSrc, uint16_t count)
{
uint8_t* pEnd = pPixelDest + (count * PixelSize);
const uint8_t* pSrc = (const uint8_t*)pPixelSrc;
const uint8_t* pSrc = reinterpret_cast<const uint8_t*>(pPixelSrc);
while (pPixelDest < pEnd)
{
*pPixelDest++ = pgm_read_byte(pSrc++);
@@ -84,7 +84,7 @@ public:
typedef RgbColor ColorObject;
};
class Neo4Elements
class Neo4ByteElements
{
public:
static const size_t PixelSize = 4;
@@ -100,8 +100,8 @@ public:
static void replicatePixel(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint32_t* pDest = (uint32_t*)pPixelDest;
const uint32_t* pSrc = (const uint32_t*)pPixelSrc;
uint32_t* pDest = reinterpret_cast<uint32_t*>(pPixelDest);
const uint32_t* pSrc = reinterpret_cast<const uint32_t*>(pPixelSrc);
uint32_t* pEnd = pDest + count;
while (pDest < pEnd)
@@ -112,8 +112,8 @@ public:
static void movePixelsInc(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint32_t* pDest = (uint32_t*)pPixelDest;
const uint32_t* pSrc = (uint32_t*)pPixelSrc;
uint32_t* pDest = reinterpret_cast<uint32_t*>(pPixelDest);
const uint32_t* pSrc = reinterpret_cast<const uint32_t*>(pPixelSrc);
uint32_t* pEnd = pDest + count;
while (pDest < pEnd)
{
@@ -123,8 +123,8 @@ public:
static void movePixelsInc_P(uint8_t* pPixelDest, PGM_VOID_P pPixelSrc, uint16_t count)
{
uint32_t* pDest = (uint32_t*)pPixelDest;
const uint32_t* pSrc = (const uint32_t*)pPixelSrc;
uint32_t* pDest = reinterpret_cast<uint32_t*>(pPixelDest);
const uint32_t* pSrc = reinterpret_cast<const uint32_t*>(pPixelSrc);
uint32_t* pEnd = pDest + count;
while (pDest < pEnd)
{
@@ -134,8 +134,8 @@ public:
static void movePixelsDec(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint32_t* pDest = (uint32_t*)pPixelDest;
const uint32_t* pSrc = (uint32_t*)pPixelSrc;
uint32_t* pDest = reinterpret_cast<uint32_t*>(pPixelDest);
const uint32_t* pSrc = reinterpret_cast<const uint32_t*>(pPixelSrc);
uint32_t* pDestBack = pDest + count;
const uint32_t* pSrcBack = pSrc + count;
while (pDestBack > pDest)
@@ -147,8 +147,133 @@ public:
typedef RgbwColor ColorObject;
};
class Neo6ByteElements
{
public:
static const size_t PixelSize = 6;
class Neo3ElementsNoSettings : public Neo3Elements
static uint8_t* getPixelAddress(uint8_t* pPixels, uint16_t indexPixel)
{
return pPixels + indexPixel * PixelSize;
}
static const uint8_t* getPixelAddress(const uint8_t* pPixels, uint16_t indexPixel)
{
return pPixels + indexPixel * PixelSize;
}
static void replicatePixel(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint16_t* pDest = reinterpret_cast<uint16_t*>(pPixelDest);
const uint16_t* pSrc = reinterpret_cast<const uint16_t*>(pPixelSrc);
uint16_t* pEnd = pDest + (count * PixelSize / 2);
while (pDest < pEnd)
{
*pDest++ = *pSrc;
}
}
static void movePixelsInc(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint16_t* pDest = reinterpret_cast<uint16_t*>(pPixelDest);
const uint16_t* pSrc = reinterpret_cast<const uint16_t*>(pPixelSrc);
uint16_t* pEnd = pDest + (count * PixelSize / 2);
while (pDest < pEnd)
{
*pDest++ = *pSrc++;
}
}
static void movePixelsInc_P(uint8_t* pPixelDest, PGM_VOID_P pPixelSrc, uint16_t count)
{
uint16_t* pDest = reinterpret_cast<uint16_t*>(pPixelDest);
const uint16_t* pSrc = reinterpret_cast<const uint16_t*>(pPixelSrc);
uint16_t* pEnd = pDest + (count * PixelSize / 2);
while (pDest < pEnd)
{
*pDest++ = pgm_read_word(pSrc++);
}
}
static void movePixelsDec(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint16_t* pDest = reinterpret_cast<uint16_t*>(pPixelDest);
const uint16_t* pSrc = reinterpret_cast<const uint16_t*>(pPixelSrc);
uint16_t* pDestBack = pDest + (count * PixelSize / 2);
const uint16_t* pSrcBack = pSrc + (count * PixelSize / 2);
while (pDestBack > pDest)
{
*--pDestBack = *--pSrcBack;
}
}
typedef Rgb48Color ColorObject;
};
class Neo8ByteElements
{
public:
static const size_t PixelSize = 8;
static uint8_t* getPixelAddress(uint8_t* pPixels, uint16_t indexPixel)
{
return pPixels + indexPixel * PixelSize;
}
static const uint8_t* getPixelAddress(const uint8_t* pPixels, uint16_t indexPixel)
{
return pPixels + indexPixel * PixelSize;
}
static void replicatePixel(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint32_t* pDest = reinterpret_cast<uint32_t*>(pPixelDest);
const uint32_t* pSrc = reinterpret_cast<const uint32_t*>(pPixelSrc);
uint32_t* pEnd = pDest + (count * PixelSize);
while (pDest < pEnd)
{
*pDest++ = *pSrc;
}
}
static void movePixelsInc(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint32_t* pDest = reinterpret_cast<uint32_t*>(pPixelDest);
const uint32_t* pSrc = reinterpret_cast<const uint32_t*>(pPixelSrc);
uint32_t* pEnd = pDest + (count * PixelSize);
while (pDest < pEnd)
{
*pDest++ = *pSrc++;
}
}
static void movePixelsInc_P(uint8_t* pPixelDest, PGM_VOID_P pPixelSrc, uint16_t count)
{
uint32_t* pDest = reinterpret_cast<uint32_t*>(pPixelDest);
const uint32_t* pSrc = reinterpret_cast<const uint32_t*>(pPixelSrc);
uint32_t* pEnd = pDest + (count * PixelSize);
while (pDest < pEnd)
{
*pDest++ = pgm_read_dword(pSrc++);
}
}
static void movePixelsDec(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint32_t* pDest = reinterpret_cast<uint32_t*>(pPixelDest);
const uint32_t* pSrc = reinterpret_cast<const uint32_t*>(pPixelSrc);
uint32_t* pDestBack = pDest + (count * PixelSize);
const uint32_t* pSrcBack = pSrc + (count * PixelSize);
while (pDestBack > pDest)
{
*--pDestBack = *--pSrcBack;
}
}
typedef Rgbw64Color ColorObject;
};
class Neo3ByteElementsNoSettings : public Neo3ByteElements
{
public:
typedef NeoNoSettings SettingsObject;
@@ -169,7 +294,7 @@ public:
}
};
class Neo4ElementsNoSettings : public Neo4Elements
class Neo4ByteElementsNoSettings : public Neo4ByteElements
{
public:
typedef NeoNoSettings SettingsObject;
@@ -190,7 +315,49 @@ public:
}
};
class NeoGrbFeature : public Neo3ElementsNoSettings
class Neo6ByteElementsNoSettings : public Neo6ByteElements
{
public:
typedef NeoNoSettings SettingsObject;
static const size_t SettingsSize = 0;
static void applySettings(uint8_t*, const SettingsObject&)
{
}
static uint8_t* pixels(uint8_t* pData)
{
return pData;
}
static const uint8_t* pixels(const uint8_t* pData)
{
return pData;
}
};
class Neo8ByteElementsNoSettings : public Neo8ByteElements
{
public:
typedef NeoNoSettings SettingsObject;
static const size_t SettingsSize = 0;
static void applySettings(uint8_t*, const SettingsObject&)
{
}
static uint8_t* pixels(uint8_t* pData)
{
return pData;
}
static const uint8_t* pixels(const uint8_t* pData)
{
return pData;
}
};
class NeoGrbFeature : public Neo3ByteElementsNoSettings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
@@ -217,7 +384,7 @@ public:
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
const uint8_t* p = getPixelAddress(reinterpret_cast<const uint8_t*>(pPixels), indexPixel);
color.G = pgm_read_byte(p++);
color.R = pgm_read_byte(p++);
@@ -228,7 +395,7 @@ public:
};
class NeoGrbwFeature : public Neo4ElementsNoSettings
class NeoGrbwFeature : public Neo4ByteElementsNoSettings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
@@ -258,7 +425,7 @@ public:
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
const uint8_t* p = getPixelAddress(reinterpret_cast<const uint8_t*>(pPixels), indexPixel);
color.G = pgm_read_byte(p++);
color.R = pgm_read_byte(p++);
@@ -270,7 +437,7 @@ public:
};
class NeoRgbwFeature : public Neo4ElementsNoSettings
class NeoRgbwFeature : public Neo4ByteElementsNoSettings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
@@ -299,7 +466,7 @@ public:
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
const uint8_t* p = getPixelAddress(reinterpret_cast<const uint8_t*>(pPixels), indexPixel);
color.R = pgm_read_byte(p++);
color.G = pgm_read_byte(p++);
@@ -311,7 +478,7 @@ public:
};
class NeoRgbFeature : public Neo3ElementsNoSettings
class NeoRgbFeature : public Neo3ByteElementsNoSettings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
@@ -338,7 +505,7 @@ public:
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
const uint8_t* p = getPixelAddress(reinterpret_cast<const uint8_t*>(pPixels), indexPixel);
color.R = pgm_read_byte(p++);
color.G = pgm_read_byte(p++);
@@ -349,7 +516,7 @@ public:
};
class NeoBrgFeature : public Neo3ElementsNoSettings
class NeoBrgFeature : public Neo3ByteElementsNoSettings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
@@ -376,7 +543,7 @@ public:
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
const uint8_t* p = getPixelAddress(reinterpret_cast<const uint8_t*>(pPixels), indexPixel);
color.B = pgm_read_byte(p++);
color.R = pgm_read_byte(p++);
@@ -387,7 +554,7 @@ public:
};
class NeoRbgFeature : public Neo3ElementsNoSettings
class NeoRbgFeature : public Neo3ByteElementsNoSettings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
@@ -415,7 +582,7 @@ public:
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
const uint8_t* p = getPixelAddress(reinterpret_cast<const uint8_t*>(pPixels), indexPixel);
color.R = pgm_read_byte(p++);
color.B = pgm_read_byte(p++);
@@ -425,3 +592,83 @@ public:
}
};
class NeoRgbw64Feature : public Neo8ByteElementsNoSettings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
{
uint16_t* p = reinterpret_cast<uint16_t *>(getPixelAddress(pPixels, indexPixel));
*p++ = color.R;
*p++ = color.G;
*p++ = color.B;
*p = color.W;
}
static ColorObject retrievePixelColor(const uint8_t* pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint16_t* p = reinterpret_cast<const uint16_t*>(getPixelAddress(pPixels, indexPixel));
color.R = *p++;
color.G = *p++;
color.B = *p++;
color.W = *p;
return color;
}
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint16_t* p = reinterpret_cast<const uint16_t*>(getPixelAddress(reinterpret_cast<const uint8_t*>(pPixels), indexPixel));
color.R = pgm_read_word(p++);
color.G = pgm_read_word(p++);
color.B = pgm_read_word(p++);
color.W = pgm_read_word(p);
return color;
}
};
class NeoRgb48Feature : public Neo6ByteElementsNoSettings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
{
uint16_t* p = reinterpret_cast<uint16_t*>(getPixelAddress(pPixels, indexPixel));
*p++ = color.R;
*p++ = color.G;
*p = color.B;
}
static ColorObject retrievePixelColor(const uint8_t* pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint16_t* p = reinterpret_cast<const uint16_t*>(getPixelAddress(pPixels, indexPixel));
color.R = *p++;
color.G = *p++;
color.B = *p;
return color;
}
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint16_t* p = reinterpret_cast<const uint16_t*>(getPixelAddress(reinterpret_cast<const uint8_t*>(pPixels), indexPixel));
color.R = pgm_read_word(p++);
color.G = pgm_read_word(p++);
color.B = pgm_read_word(p);
return color;
}
};
typedef NeoRgb48Feature NeoRgbUcs8903Feature;
typedef NeoRgbw64Feature NeoRgbwUcs8904Feature;

View File

@@ -51,7 +51,7 @@ public:
}
};
class Neo4ElementsTm1814Settings : public Neo4Elements
class Neo4ByteElementsTm1814Settings : public Neo4ByteElements
{
public:
typedef NeoTm1814Settings SettingsObject;
@@ -88,7 +88,7 @@ public:
};
class NeoWrgbTm1814Feature : public Neo4ElementsTm1814Settings
class NeoWrgbTm1814Feature : public Neo4ByteElementsTm1814Settings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)

View File

@@ -44,7 +44,7 @@ public:
NeoTm1914_Mode Mode;
};
class Neo3ElementsTm1914Settings : public Neo3Elements
class Neo3ByteElementsTm1914Settings : public Neo3ByteElements
{
public:
typedef NeoTm1914Settings SettingsObject;
@@ -96,7 +96,7 @@ public:
};
class NeoRgbTm1914Feature : public Neo3ElementsTm1914Settings
class NeoRgbTm1914Feature : public Neo3ByteElementsTm1914Settings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
@@ -135,7 +135,7 @@ public:
};
class NeoGrbTm1914Feature : public Neo3ElementsTm1914Settings
class NeoGrbTm1914Feature : public Neo3ByteElementsTm1914Settings
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)

View File

@@ -30,17 +30,6 @@ License along with NeoPixel. If not, see
#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;

View File

@@ -66,12 +66,15 @@ struct Rgb48Color : RgbColorBase
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);
Rgb48Color(const HtmlColor& color)
{
*this = RgbColor(color);
};
// ------------------------------------------------------------------------
// Construct a Rgb48Color using HslColor
@@ -189,12 +192,12 @@ struct Rgb48Color : RgbColorBase
private:
inline static uint16_t _elementDim(uint16_t value, uint16_t ratio)
{
return (static_cast<uint32_t>(value) * (static_cast<uint32_t>(ratio) + 1)) >> 8;
return (static_cast<uint32_t>(value) * (static_cast<uint32_t>(ratio) + 1)) >> 16;
}
inline static uint16_t _elementBrighten(uint16_t value, uint16_t ratio)
{
uint32_t element = ((static_cast<uint32_t>(value) + 1) << 8) / (static_cast<uint32_t>(ratio) + 1);
uint32_t element = ((static_cast<uint32_t>(value) + 1) << 16) / (static_cast<uint32_t>(ratio) + 1);
if (element > Max)
{

View File

@@ -0,0 +1,188 @@
/*-------------------------------------------------------------------------
Rgbw64Color 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
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include "RgbColor.h"
#include "RgbwColor.h"
#include "Rgb48Color.h"
#include "HslColor.h"
#include "HsbColor.h"
#include "Rgbw64Color.h"
#include "HtmlColor.h"
Rgbw64Color::Rgbw64Color(const RgbwColor& 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);
W = (color.W == 0) ? 0 : (color.W << 8 | 0xff);
};
Rgbw64Color::Rgbw64Color(const HslColor& color)
{
Rgb48Color rgbColor(color);
*this = rgbColor;
}
Rgbw64Color::Rgbw64Color(const HsbColor& color)
{
Rgb48Color rgbColor(color);
*this = rgbColor;
}
uint16_t Rgbw64Color::CalculateBrightness() const
{
uint16_t colorB = static_cast<uint16_t>((static_cast<uint32_t>(R) + static_cast<uint32_t>(G) + static_cast<uint32_t>(B)) / 3);
if (W > colorB)
{
return W;
}
else
{
return colorB;
}
}
Rgbw64Color Rgbw64Color::Dim(uint16_t ratio) const
{
// specifically avoids float math
return Rgbw64Color(_elementDim(R, ratio), _elementDim(G, ratio), _elementDim(B, ratio), _elementDim(W, ratio));
}
Rgbw64Color Rgbw64Color::Brighten(uint16_t ratio) const
{
// specifically avoids float math
return Rgbw64Color(_elementBrighten(R, ratio), _elementBrighten(G, ratio), _elementBrighten(B, ratio), _elementBrighten(W, ratio));
}
void Rgbw64Color::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;
}
if (W > delta)
{
W -= delta;
}
else
{
W = 0;
}
}
void Rgbw64Color::Lighten(uint16_t delta)
{
if (IsColorLess())
{
if (W < Max - delta)
{
W += delta;
}
else
{
W = Max;
}
}
else
{
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;
}
}
}
Rgbw64Color Rgbw64Color::LinearBlend(const Rgbw64Color& left, const Rgbw64Color& right, float progress)
{
return Rgbw64Color( left.R + ((right.R - left.R) * progress),
left.G + ((right.G - left.G) * progress),
left.B + ((right.B - left.B) * progress),
left.W + ((right.W - left.W) * progress) );
}
Rgbw64Color Rgbw64Color::BilinearBlend(const Rgbw64Color& c00,
const Rgbw64Color& c01,
const Rgbw64Color& c10,
const Rgbw64Color& 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 Rgbw64Color(
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,
c00.W * v00 + c10.W * v10 + c01.W * v01 + c11.W * v11 );
}

248
src/internal/Rgbw64Color.h Normal file
View File

@@ -0,0 +1,248 @@
/*-------------------------------------------------------------------------
Rgbw64Color 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
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
#include "NeoSettings.h"
struct RgbColor;
struct HslColor;
struct HsbColor;
// ------------------------------------------------------------------------
// Rgbw64Color represents a color object that is represented by Red, Green, Blue
// component values and an extra White component. It contains helpful color
// routines to manipulate the color.
// ------------------------------------------------------------------------
struct Rgbw64Color
{
typedef NeoRgbwCurrentSettings SettingsObject;
// ------------------------------------------------------------------------
// Construct a Rgbw64Color using R, G, B, W values (0-65535)
// ------------------------------------------------------------------------
Rgbw64Color(uint16_t r, uint16_t g, uint16_t b, uint16_t w = 0) :
R(r), G(g), B(b), W(w)
{
};
// ------------------------------------------------------------------------
// Construct a RgbColor using a single brightness value (0-65535)
// This works well for creating gray tone colors
// (0) = black, (65535) = white, (32768) = gray
// ------------------------------------------------------------------------
Rgbw64Color(uint16_t brightness) :
R(0), G(0), B(0), W(brightness)
{
};
// ------------------------------------------------------------------------
// Construct a Rgbw64Color using RgbColor
// ------------------------------------------------------------------------
Rgbw64Color(const RgbColor& color)
{
*this = Rgb48Color(color);
};
// ------------------------------------------------------------------------
// Construct a Rgbw64Color using Rgb48Color
// ------------------------------------------------------------------------
Rgbw64Color(const Rgb48Color& color) :
R(color.R),
G(color.G),
B(color.B),
W(0)
{
};
// ------------------------------------------------------------------------
// Construct a Rgbw64Color using RgbwColor
// ------------------------------------------------------------------------
Rgbw64Color(const RgbwColor& color);
// ------------------------------------------------------------------------
// Construct a Rgbw64Color using HtmlColor
// ------------------------------------------------------------------------
Rgbw64Color(const HtmlColor& color)
{
*this = RgbwColor(color);
}
// ------------------------------------------------------------------------
// Construct a Rgbw64Color using HslColor
// ------------------------------------------------------------------------
Rgbw64Color(const HslColor& color);
// ------------------------------------------------------------------------
// Construct a Rgbw64Color using HsbColor
// ------------------------------------------------------------------------
Rgbw64Color(const HsbColor& color);
// ------------------------------------------------------------------------
// Construct a Rgbw64Color that will have its values set in latter operations
// CAUTION: The R,G,B, W members are not initialized and may not be consistent
// ------------------------------------------------------------------------
Rgbw64Color()
{
};
// ------------------------------------------------------------------------
// Comparison operators
// ------------------------------------------------------------------------
bool operator==(const Rgbw64Color& other) const
{
return (R == other.R && G == other.G && B == other.B && W == other.W);
};
bool operator!=(const Rgbw64Color& other) const
{
return !(*this == other);
};
// ------------------------------------------------------------------------
// Returns if the color is grey, all values are equal other than white
// ------------------------------------------------------------------------
bool IsMonotone() const
{
return (R == B && R == G);
};
// ------------------------------------------------------------------------
// Returns if the color components are all zero, the white component maybe
// anything
// ------------------------------------------------------------------------
bool IsColorLess() const
{
return (R == 0 && B == 0 && G == 0);
};
// ------------------------------------------------------------------------
// 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
// ------------------------------------------------------------------------
Rgbw64Color 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
// ------------------------------------------------------------------------
Rgbw64Color 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 Rgbw64Color LinearBlend(const Rgbw64Color& left, const Rgbw64Color& 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 Rgbw64Color BilinearBlend(const Rgbw64Color& c00,
const Rgbw64Color& c01,
const Rgbw64Color& c10,
const Rgbw64Color& c11,
float x,
float y);
uint16_t CalcTotalTenthMilliAmpere(const SettingsObject& settings)
{
auto total = 0;
total += R * settings.RedTenthMilliAmpere / Max;
total += G * settings.GreenTenthMilliAmpere / Max;
total += B * settings.BlueTenthMilliAmpere / Max;
total += W * settings.WhiteCurrent / Max;
return total;
}
// ------------------------------------------------------------------------
// Red, Green, Blue, White color members (0-65535) where
// (0,0,0,0) is black and (65535,65535,65535, 0) and (0,0,0,65535) is white
// Note (65535,65535,65535,65535) is extreme bright white
// ------------------------------------------------------------------------
uint16_t R;
uint16_t G;
uint16_t B;
uint16_t W;
const static uint16_t Max = 65535;
private:
inline static uint16_t _elementDim(uint16_t value, uint16_t ratio)
{
return (static_cast<uint16_t>(value) * (static_cast<uint16_t>(ratio) + 1)) >> 16;
}
inline static uint16_t _elementBrighten(uint16_t value, uint16_t ratio)
{
uint16_t element = ((static_cast<uint32_t>(value) + 1) << 16) / (static_cast<uint32_t>(ratio) + 1);
if (element > Max)
{
element = Max;
}
else
{
element -= 1;
}
return element;
}
};

View File

@@ -187,10 +187,10 @@ struct RgbwColor
{
auto total = 0;
total += R * settings.RedTenthMilliAmpere / 255;
total += G * settings.GreenTenthMilliAmpere / 255;
total += B * settings.BlueTenthMilliAmpere / 255;
total += W * settings.WhiteCurrent / 255;
total += R * settings.RedTenthMilliAmpere / Max;
total += G * settings.GreenTenthMilliAmpere / Max;
total += B * settings.BlueTenthMilliAmpere / Max;
total += W * settings.WhiteCurrent / Max;
return total;
}
@@ -205,6 +205,8 @@ struct RgbwColor
uint8_t B;
uint8_t W;
const static uint8_t Max = 255;
private:
inline static uint8_t _elementDim(uint8_t value, uint8_t ratio)
{
@@ -215,9 +217,9 @@ private:
{
uint16_t element = ((static_cast<uint16_t>(value) + 1) << 8) / (static_cast<uint16_t>(ratio) + 1);
if (element > 255)
if (element > Max)
{
element = 255;
element = Max;
}
else
{