From fc0b7398937edb9389854541facbfbe6074fe954 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Tue, 25 Feb 2020 11:04:34 -0800 Subject: [PATCH] Enhance ColorObject (#340) Enahnce Dim Add Brighten NeoPixelBrightnessBus use enhancement --- src/NeoPixelBrightnessBus.h | 35 +++++++---------------------------- src/internal/RgbColor.cpp | 8 +++++++- src/internal/RgbColor.h | 26 ++++++++++++++++++++++++++ src/internal/RgbwColor.cpp | 8 +++++++- src/internal/RgbwColor.h | 24 ++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 30 deletions(-) diff --git a/src/NeoPixelBrightnessBus.h b/src/NeoPixelBrightnessBus.h index 0ff1d52..c2ec7ce 100644 --- a/src/NeoPixelBrightnessBus.h +++ b/src/NeoPixelBrightnessBus.h @@ -34,32 +34,12 @@ template class NeoPixelBrightnessBu private: void ConvertColor(typename T_COLOR_FEATURE::ColorObject* color) { - if (_brightness) - { - uint8_t* ptr = (uint8_t*) color; - uint8_t* ptrEnd = ptr + T_COLOR_FEATURE::PixelSize; - - while (ptr != ptrEnd) - { - uint16_t value = *ptr; - *ptr++ = (value * _brightness) >> 8; - } - } + *color = color->Dim(_brightness); } void RecoverColor(typename T_COLOR_FEATURE::ColorObject* color) const { - if (_brightness) - { - uint8_t* ptr = (uint8_t*) color; - uint8_t* ptrEnd = ptr + T_COLOR_FEATURE::PixelSize; - - while (ptr != ptrEnd) - { - uint16_t value = *ptr; - *ptr++ = (value << 8) / _brightness; - } - } + *color = color->Brighten(_brightness); } public: @@ -110,14 +90,13 @@ public: // re-scale existing pixels // - uint8_t* ptr = this->Pixels(); - uint8_t* ptrEnd = ptr + this->PixelsSize(); - while (ptr != ptrEnd) + for (uint16_t indexPixel = 0; indexPixel < NeoPixelBus::PixelCount(); indexPixel++) { - uint16_t value = *ptr; - *ptr++ = (value * scale) >> 8; + typename T_COLOR_FEATURE::ColorObject color = NeoPixelBus::GetPixelColor(indexPixel); + color = color.Dim(scale); + NeoPixelBus::SetPixelColor(indexPixel, color); } - + _brightness = newBrightness; this->Dirty(); } diff --git a/src/internal/RgbColor.cpp b/src/internal/RgbColor.cpp index 436dfed..ae0b4e1 100644 --- a/src/internal/RgbColor.cpp +++ b/src/internal/RgbColor.cpp @@ -166,7 +166,13 @@ uint8_t RgbColor::CalculateBrightness() const RgbColor RgbColor::Dim(uint8_t ratio) const { // specifically avoids float math - return RgbColor(R * ratio / 255, G * ratio / 255, B * ratio / 255); + return RgbColor(_elementDim(R, ratio), _elementDim(G, ratio), _elementDim(B, ratio)); +} + +RgbColor RgbColor::Brighten(uint8_t ratio) const +{ + // specifically avoids float math + return RgbColor(_elementBrighten(R, ratio), _elementBrighten(G, ratio), _elementBrighten(B, ratio)); } void RgbColor::Darken(uint8_t delta) diff --git a/src/internal/RgbColor.h b/src/internal/RgbColor.h index 1f05aa4..8ed524f 100644 --- a/src/internal/RgbColor.h +++ b/src/internal/RgbColor.h @@ -109,6 +109,14 @@ struct RgbColor // ------------------------------------------------------------------------ RgbColor Dim(uint8_t ratio) const; + // ------------------------------------------------------------------------ + // 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 + // ------------------------------------------------------------------------ + RgbColor Brighten(uint8_t ratio) const; + // ------------------------------------------------------------------------ // Darken will adjust the color by the given delta toward black // NOTE: This is a simple linear change @@ -166,5 +174,23 @@ struct RgbColor uint8_t R; uint8_t G; uint8_t B; + +private: + inline static uint8_t _elementDim(uint8_t value, uint8_t ratio) + { + return (value * (ratio + 1)) >> 8; + } + + inline static uint8_t _elementBrighten(uint8_t value, uint8_t ratio) + { + uint16_t element = (value << 8) / (ratio + 1); + + if (element > 255) + { + element = 255; + } + + return element; + } }; diff --git a/src/internal/RgbwColor.cpp b/src/internal/RgbwColor.cpp index 6bc56d0..cb9681f 100644 --- a/src/internal/RgbwColor.cpp +++ b/src/internal/RgbwColor.cpp @@ -70,7 +70,13 @@ uint8_t RgbwColor::CalculateBrightness() const RgbwColor RgbwColor::Dim(uint8_t ratio) const { // specifically avoids float math - return RgbwColor(R * ratio / 255, G * ratio / 255, B * ratio / 255, W * ratio / 255); + return RgbwColor(_elementDim(R, ratio), _elementDim(G, ratio), _elementDim(B, ratio), _elementDim(W, ratio)); +} + +RgbwColor RgbwColor::Brighten(uint8_t ratio) const +{ + // specifically avoids float math + return RgbwColor(_elementBrighten(R, ratio), _elementBrighten(G, ratio), _elementBrighten(B, ratio), _elementBrighten(W, ratio)); } void RgbwColor::Darken(uint8_t delta) diff --git a/src/internal/RgbwColor.h b/src/internal/RgbwColor.h index f51fee1..ee08906 100644 --- a/src/internal/RgbwColor.h +++ b/src/internal/RgbwColor.h @@ -136,6 +136,14 @@ struct RgbwColor // ------------------------------------------------------------------------ RgbwColor Dim(uint8_t ratio) const; + // ------------------------------------------------------------------------ + // 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 + // ------------------------------------------------------------------------ + RgbwColor Brighten(uint8_t ratio) const; + // ------------------------------------------------------------------------ // Darken will adjust the color by the given delta toward black // NOTE: This is a simple linear change @@ -197,6 +205,22 @@ struct RgbwColor uint8_t B; uint8_t W; +private: + inline static uint8_t _elementDim(uint8_t value, uint8_t ratio) + { + return (value * (ratio + 1)) >> 8; + } + inline static uint8_t _elementBrighten(uint8_t value, uint8_t ratio) + { + uint16_t element = (value << 8) / (ratio + 1); + + if (element > 255) + { + element = 255; + } + + return element; + } };