This commit is contained in:
LordGrey 2024-05-31 17:27:30 +02:00
parent 4e77d4a0d4
commit 1eed23f765
11 changed files with 97 additions and 112 deletions

View File

@ -111,7 +111,7 @@ set(DEFAULT_USE_SYSTEM_QMDNS_LIBS OFF)
set(DEFAULT_TESTS OFF) set(DEFAULT_TESTS OFF)
# Build Hyperion with a reduced set of functionality, overwrites other default values # Build Hyperion with a reduced set of functionality, overwrites other default values
set(DEFAULT_HYPERION_LIGHT ON ) set(DEFAULT_HYPERION_LIGHT OFF)
if(${CMAKE_SYSTEM} MATCHES "Linux") if(${CMAKE_SYSTEM} MATCHES "Linux")
set(DEFAULT_FB ON) set(DEFAULT_FB ON)

View File

@ -48,7 +48,6 @@ class LinearColorSmoothing;
class EffectEngine; class EffectEngine;
#endif #endif
class MultiColorAdjustment; class MultiColorAdjustment;
class MultiColorCorrection;
class ColorAdjustment; class ColorAdjustment;
class SettingsManager; class SettingsManager;
class BGEffectHandler; class BGEffectHandler;
@ -578,9 +577,6 @@ private:
/// The adjustment from raw colors to led colors /// The adjustment from raw colors to led colors
MultiColorAdjustment * _raw2ledAdjustment; MultiColorAdjustment * _raw2ledAdjustment;
/// The temperature from raw colors to led colors
MultiColorCorrection * _raw2ledTemperature;
/// The actual LedDeviceWrapper /// The actual LedDeviceWrapper
LedDeviceWrapper* _ledDeviceWrapper; LedDeviceWrapper* _ledDeviceWrapper;

View File

@ -33,6 +33,10 @@ struct ColorRgb
static const ColorRgb YELLOW; static const ColorRgb YELLOW;
/// 'White' RgbColor (255, 255, 255) /// 'White' RgbColor (255, 255, 255)
static const ColorRgb WHITE; static const ColorRgb WHITE;
/// 'Cyan' RgbColor (0, 255, 255)
static const ColorRgb CYAN;
/// 'Magenta' RgbColor (255, 0,255)
static const ColorRgb MAGENTA;
ColorRgb() = default; ColorRgb() = default;

View File

@ -5,28 +5,31 @@
#include <utils/ColorRgb.h> #include <utils/ColorRgb.h>
// Constants // Constants
namespace { namespace ColorTemperature {
const int TEMPERATURE_MINIMUM = 1000; constexpr int MINIMUM {1000};
const int TEMPERATUR_MAXIMUM = 40000; constexpr int MAXIMUM {40000};
} //End of constants constexpr int DEFAULT {6600};
}
//End of constants
static ColorRgb getRgbFromTemperature(int temperature) static ColorRgb getRgbFromTemperature(int temperature)
{ {
//Temperature input in Kelvin valid in the range 1000 K to 40000 K. White light = 6600K //Temperature input in Kelvin valid in the range 1000 K to 40000 K. White light = 6600K
temperature = qBound(TEMPERATURE_MINIMUM, temperature, TEMPERATUR_MAXIMUM); temperature = qBound(ColorTemperature::MINIMUM, temperature, ColorTemperature::MAXIMUM);
// All calculations require temperature / 100, so only do the conversion once. // All calculations require temperature / 100, so only do the conversion once.
temperature /= 100; temperature /= 100;
// Compute each color in turn. // Compute each color in turn.
int red, green, blue; int red;
int green;
int blue;
// red // red
if (temperature <= 66) if (temperature <= 66)
{ {
red = 255; red = UINT8_MAX;
} }
else else
{ {
@ -50,7 +53,7 @@ static ColorRgb getRgbFromTemperature(int temperature)
// blue // blue
if (temperature >= 66) if (temperature >= 66)
{ {
blue = 255; blue = UINT8_MAX;
} }
else if (temperature <= 19) else if (temperature <= 19)
{ {
@ -63,9 +66,9 @@ static ColorRgb getRgbFromTemperature(int temperature)
} }
return { return {
static_cast<uint8_t>(qBound(0, red, 255)), static_cast<uint8_t>(qBound(0, red, UINT8_MAX)),
static_cast<uint8_t>(qBound(0, green, 255)), static_cast<uint8_t>(qBound(0, green, UINT8_MAX)),
static_cast<uint8_t>(qBound(0, blue, 255)), static_cast<uint8_t>(qBound(0, blue, UINT8_MAX)),
}; };
} }

View File

@ -1,23 +1,27 @@
#pragma once #pragma once
// STL includes
#include <cstdint> #include <cstdint>
#include <QString> #include <QString>
#include <utils/Logger.h> #include <utils/Logger.h>
#include <utils/ColorRgb.h>
/// Correction for a single color byte value /// Correction for a single color byte value
/// All configuration values are unsigned int and assume the color value to be between 0 and 255 /// All configuration values are unsigned int and assume the color value to be between 0 and 255
class RgbChannelAdjustment class RgbChannelAdjustment
{ {
public: public:
/// Default constructor /// Default constructor
RgbChannelAdjustment(QString channelName=""); explicit RgbChannelAdjustment(const QString& channelName="");
explicit RgbChannelAdjustment(const ColorRgb& adjust, const QString& channelName="");
/// Constructor /// Constructor
/// @param adjustR /// @param adjustR
/// @param adjustG /// @param adjustG
/// @param adjustB /// @param adjustB
RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB, QString channelName=""); explicit RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB, const QString& channelName="");
/// ///
/// Transform the given array value /// Transform the given array value
@ -40,6 +44,7 @@ public:
/// @param adjustB /// @param adjustB
/// ///
void setAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB); void setAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB);
void setAdjustment(const ColorRgb& adjust);
/// @return The current adjustR value /// @return The current adjustR value
uint8_t getAdjustmentR() const; uint8_t getAdjustmentR() const;
@ -51,24 +56,28 @@ public:
uint8_t getAdjustmentB() const; uint8_t getAdjustmentB() const;
private: private:
/// color channels
enum ColorChannel { RED=0, GREEN=1, BLUE=2 }; struct ColorMapping {
uint8_t red[256];
uint8_t green[256];
uint8_t blue[256];
};
/// reset init of color mapping /// reset init of color mapping
void resetInitialized(); void resetInitialized();
/// The adjustment of RGB channel
uint8_t _adjust[3];
/// The mapping from input color to output color
uint8_t _mapping[3][256];
/// Name of this channel, usefull for debug messages /// Name of this channel, usefull for debug messages
QString _channelName; QString _channelName;
/// Logger instance /// Logger instance
Logger * _log; Logger * _log;
/// The adjustment of RGB channel
ColorRgb _adjust;
/// The mapping from input color to output color
ColorMapping _mapping;
/// bitfield to determine white value is alreade initialized /// bitfield to determine white value is alreade initialized
bool _initialized[256]; bool _initialized[256];

View File

@ -3,4 +3,6 @@
#define QSTRING_CSTR(str) str.toUtf8().constData() #define QSTRING_CSTR(str) str.toUtf8().constData()
typedef QList< int > QIntList; typedef QList< int > QIntList;
constexpr uint32_t UINT8_MAX_SQUARED = static_cast<uint32_t>(std::numeric_limits<unsigned char>::max()) * static_cast<uint32_t>(std::numeric_limits<unsigned char>::max());

View File

@ -5,6 +5,7 @@
#include <hyperion/ColorAdjustment.h> #include <hyperion/ColorAdjustment.h>
#include <hyperion/MultiColorAdjustment.h> #include <hyperion/MultiColorAdjustment.h>
#include <hyperion/LedString.h> #include <hyperion/LedString.h>
#include <utils/KelvinToRgb.h>
#include <QRegularExpression> #include <QRegularExpression>
// fg effect // fg effect
@ -77,7 +78,7 @@ namespace hyperion {
const double gammaR = colorConfig["gammaRed"].toDouble(1.0); const double gammaR = colorConfig["gammaRed"].toDouble(1.0);
const double gammaG = colorConfig["gammaGreen"].toDouble(1.0); const double gammaG = colorConfig["gammaGreen"].toDouble(1.0);
const double gammaB = colorConfig["gammaBlue"].toDouble(1.0); const double gammaB = colorConfig["gammaBlue"].toDouble(1.0);
const int temperature = colorConfig["temperature"].toInt(6600); const int temperature = colorConfig["temperature"].toInt(ColorTemperature::DEFAULT);
return RgbTransform(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, static_cast<uint8_t>(brightness), static_cast<uint8_t>(brightnessComp), temperature); return RgbTransform(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, static_cast<uint8_t>(brightness), static_cast<uint8_t>(brightnessComp), temperature);
} }
@ -90,13 +91,13 @@ namespace hyperion {
return OkhsvTransform(saturationGain, brightnessGain); return OkhsvTransform(saturationGain, brightnessGain);
} }
static RgbChannelAdjustment createRgbChannelAdjustment(const QJsonObject& colorConfig, const QString& channelName, int defaultR, int defaultG, int defaultB) static RgbChannelAdjustment createRgbChannelAdjustment(const QJsonObject& colorConfig, const QString& channelName, const ColorRgb& color)
{ {
const QJsonArray& channelConfig = colorConfig[channelName].toArray(); const QJsonArray& channelConfig = colorConfig[channelName].toArray();
return RgbChannelAdjustment( return RgbChannelAdjustment(
static_cast<uint8_t>(channelConfig[0].toInt(defaultR)), static_cast<uint8_t>(channelConfig[0].toInt(color.red)),
static_cast<uint8_t>(channelConfig[1].toInt(defaultG)), static_cast<uint8_t>(channelConfig[1].toInt(color.green)),
static_cast<uint8_t>(channelConfig[2].toInt(defaultB)), static_cast<uint8_t>(channelConfig[2].toInt(color.blue)),
channelName channelName
); );
} }
@ -107,14 +108,14 @@ namespace hyperion {
ColorAdjustment * adjustment = new ColorAdjustment(); ColorAdjustment * adjustment = new ColorAdjustment();
adjustment->_id = id; adjustment->_id = id;
adjustment->_rgbBlackAdjustment = createRgbChannelAdjustment(adjustmentConfig, "black" , 0, 0, 0); adjustment->_rgbBlackAdjustment = createRgbChannelAdjustment(adjustmentConfig, "black" , ColorRgb::BLACK);
adjustment->_rgbWhiteAdjustment = createRgbChannelAdjustment(adjustmentConfig, "white" , 255,255,255); adjustment->_rgbWhiteAdjustment = createRgbChannelAdjustment(adjustmentConfig, "white" , ColorRgb::WHITE);
adjustment->_rgbRedAdjustment = createRgbChannelAdjustment(adjustmentConfig, "red" , 255, 0, 0); adjustment->_rgbRedAdjustment = createRgbChannelAdjustment(adjustmentConfig, "red" , ColorRgb::RED);
adjustment->_rgbGreenAdjustment = createRgbChannelAdjustment(adjustmentConfig, "green" , 0,255, 0); adjustment->_rgbGreenAdjustment = createRgbChannelAdjustment(adjustmentConfig, "green" , ColorRgb::GREEN);
adjustment->_rgbBlueAdjustment = createRgbChannelAdjustment(adjustmentConfig, "blue" , 0, 0,255); adjustment->_rgbBlueAdjustment = createRgbChannelAdjustment(adjustmentConfig, "blue" , ColorRgb::BLUE);
adjustment->_rgbCyanAdjustment = createRgbChannelAdjustment(adjustmentConfig, "cyan" , 0,255,255); adjustment->_rgbCyanAdjustment = createRgbChannelAdjustment(adjustmentConfig, "cyan" , ColorRgb::CYAN);
adjustment->_rgbMagentaAdjustment = createRgbChannelAdjustment(adjustmentConfig, "magenta", 255, 0,255); adjustment->_rgbMagentaAdjustment = createRgbChannelAdjustment(adjustmentConfig, "magenta", ColorRgb::MAGENTA);
adjustment->_rgbYellowAdjustment = createRgbChannelAdjustment(adjustmentConfig, "yellow" , 255,255, 0); adjustment->_rgbYellowAdjustment = createRgbChannelAdjustment(adjustmentConfig, "yellow" , ColorRgb::YELLOW);
adjustment->_rgbTransform = createRgbTransform(adjustmentConfig); adjustment->_rgbTransform = createRgbTransform(adjustmentConfig);
adjustment->_okhsvTransform = createOkhsvTransform(adjustmentConfig); adjustment->_okhsvTransform = createOkhsvTransform(adjustmentConfig);
@ -150,27 +151,27 @@ namespace hyperion {
continue; continue;
} }
std::stringstream ss; std::stringstream sStream;
const QStringList ledIndexList = ledIndicesStr.split(","); const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) { for (int j=0; j<ledIndexList.size(); ++i) {
if (i > 0) if (j > 0)
{ {
ss << ", "; sStream << ", ";
} }
if (ledIndexList[i].contains("-")) if (ledIndexList[j].contains("-"))
{ {
QStringList ledIndices = ledIndexList[i].split("-"); QStringList ledIndices = ledIndexList[j].split("-");
int startInd = ledIndices[0].toInt(); int startInd = ledIndices[0].toInt();
int endInd = ledIndices[1].toInt(); int endInd = ledIndices[1].toInt();
adjustment->setAdjustmentForLed(colorAdjustment->_id, startInd, endInd); adjustment->setAdjustmentForLed(colorAdjustment->_id, startInd, endInd);
ss << startInd << "-" << endInd; sStream << startInd << "-" << endInd;
} }
else else
{ {
int index = ledIndexList[i].toInt(); int index = ledIndexList[i].toInt();
adjustment->setAdjustmentForLed(colorAdjustment->_id, index, index); adjustment->setAdjustmentForLed(colorAdjustment->_id, index, index);
ss << index; sStream << index;
} }
} }
} }
@ -178,44 +179,6 @@ namespace hyperion {
return adjustment; return adjustment;
} }
/**
* Construct the 'led-string' with the integration area definition per led and the color
* ordering of the RGB channels
* @param ledsConfig The configuration of the led areas
* @param deviceOrder The default RGB channel ordering
* @return The constructed ledstring
*/
static LedString createLedString(const QJsonArray& ledConfigArray, const ColorOrder deviceOrder)
{
LedString ledString;
const QString deviceOrderStr = colorOrderToString(deviceOrder);
for (signed i = 0; i < ledConfigArray.size(); ++i)
{
const QJsonObject& ledConfig = ledConfigArray[i].toObject();
Led led;
led.minX_frac = qMax(0.0, qMin(1.0, ledConfig["hmin"].toDouble()));
led.maxX_frac = qMax(0.0, qMin(1.0, ledConfig["hmax"].toDouble()));
led.minY_frac = qMax(0.0, qMin(1.0, ledConfig["vmin"].toDouble()));
led.maxY_frac = qMax(0.0, qMin(1.0, ledConfig["vmax"].toDouble()));
// Fix if the user swapped min and max
if (led.minX_frac > led.maxX_frac)
{
std::swap(led.minX_frac, led.maxX_frac);
}
if (led.minY_frac > led.maxY_frac)
{
std::swap(led.minY_frac, led.maxY_frac);
}
// Get the order of the rgb channels for this led (default is device order)
led.colorOrder = stringToColorOrder(ledConfig["colorOrder"].toString(deviceOrderStr));
ledString.leds().push_back(led);
}
return ledString;
}
static QSize getLedLayoutGridSize(const QJsonArray& ledConfigArray) static QSize getLedLayoutGridSize(const QJsonArray& ledConfigArray)
{ {
std::vector<int> midPointsX; std::vector<int> midPointsX;

View File

@ -1,13 +1,10 @@
#include <algorithm> #include <algorithm>
#include <limits>
// Hyperion includes // Hyperion includes
#include <utils/Logger.h> #include <utils/Logger.h>
#include <hyperion/MultiColorAdjustment.h> #include <hyperion/MultiColorAdjustment.h>
constexpr uint32_t UINT8_MAX_SQUARED = static_cast<uint32_t>(std::numeric_limits<unsigned char>::max()) * static_cast<uint32_t>(std::numeric_limits<unsigned char>::max());
MultiColorAdjustment::MultiColorAdjustment(int ledCnt) MultiColorAdjustment::MultiColorAdjustment(int ledCnt)
: _ledAdjustments(static_cast<size_t>(ledCnt), nullptr) : _ledAdjustments(static_cast<size_t>(ledCnt), nullptr)
, _log(Logger::getInstance("ADJUSTMENT")) , _log(Logger::getInstance("ADJUSTMENT"))

View File

@ -7,3 +7,5 @@ const ColorRgb ColorRgb::GREEN = { 0, 255, 0 };
const ColorRgb ColorRgb::BLUE = { 0, 0, 255 }; const ColorRgb ColorRgb::BLUE = { 0, 0, 255 };
const ColorRgb ColorRgb::YELLOW = { 255, 255, 0 }; const ColorRgb ColorRgb::YELLOW = { 255, 255, 0 };
const ColorRgb ColorRgb::WHITE = { 255, 255, 255 }; const ColorRgb ColorRgb::WHITE = { 255, 255, 255 };
const ColorRgb ColorRgb::CYAN = { 0, 255, 255 };
const ColorRgb ColorRgb::MAGENTA= { 255, 0, 255 };

View File

@ -1,44 +1,54 @@
#include <utils/RgbChannelAdjustment.h> #include <utils/RgbChannelAdjustment.h>
RgbChannelAdjustment::RgbChannelAdjustment(QString channelName)
RgbChannelAdjustment::RgbChannelAdjustment(const QString& channelName)
: RgbChannelAdjustment(0, 0, 0, channelName) : RgbChannelAdjustment(0, 0, 0, channelName)
{ {
} }
RgbChannelAdjustment::RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB, QString channelName ) RgbChannelAdjustment::RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB, const QString& channelName )
: RgbChannelAdjustment({adjustR, adjustG, adjustB}, channelName)
{
}
RgbChannelAdjustment::RgbChannelAdjustment(const ColorRgb& adjust, const QString& channelName )
: _channelName(channelName) : _channelName(channelName)
, _log(Logger::getInstance("CHANNEL_" + channelName.toUpper())) , _log(Logger::getInstance("CHANNEL_" + channelName.toUpper()))
, _mapping{ {0}, {0}, {0} }
, _brightness(0) , _brightness(0)
{ {
setAdjustment(adjustR, adjustG, adjustB); setAdjustment(adjust);
} }
void RgbChannelAdjustment::resetInitialized() void RgbChannelAdjustment::resetInitialized()
{ {
memset(_initialized, false, sizeof(_initialized)); memset(_initialized, 0, sizeof(_initialized));
} }
void RgbChannelAdjustment::setAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB) void RgbChannelAdjustment::setAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB)
{ {
_adjust[RED] = adjustR; setAdjustment( {adjustR, adjustG, adjustB} );
_adjust[GREEN] = adjustG; }
_adjust[BLUE] = adjustB;
void RgbChannelAdjustment::setAdjustment(const ColorRgb& adjust)
{
_adjust = adjust;
resetInitialized(); resetInitialized();
} }
uint8_t RgbChannelAdjustment::getAdjustmentR() const uint8_t RgbChannelAdjustment::getAdjustmentR() const
{ {
return _adjust[RED]; return _adjust.red;
} }
uint8_t RgbChannelAdjustment::getAdjustmentG() const uint8_t RgbChannelAdjustment::getAdjustmentG() const
{ {
return _adjust[GREEN]; return _adjust.green;
} }
uint8_t RgbChannelAdjustment::getAdjustmentB() const uint8_t RgbChannelAdjustment::getAdjustmentB() const
{ {
return _adjust[BLUE]; return _adjust.blue;
} }
void RgbChannelAdjustment::apply(uint8_t input, uint8_t brightness, uint8_t & red, uint8_t & green, uint8_t & blue) void RgbChannelAdjustment::apply(uint8_t input, uint8_t brightness, uint8_t & red, uint8_t & green, uint8_t & blue)
@ -51,12 +61,13 @@ void RgbChannelAdjustment::apply(uint8_t input, uint8_t brightness, uint8_t & re
if (!_initialized[input]) if (!_initialized[input])
{ {
_mapping[RED ][input] = qMin( ((_brightness * input * _adjust[RED ]) / 65025), (int)UINT8_MAX); const int adjustedInput = static_cast<int>(_brightness * input / UINT8_MAX_SQUARED);
_mapping[GREEN][input] = qMin( ((_brightness * input * _adjust[GREEN]) / 65025), (int)UINT8_MAX); _mapping.red[input] = static_cast<quint8>(qBound(0, _adjust.red * adjustedInput, UINT8_MAX));
_mapping[BLUE ][input] = qMin( ((_brightness * input * _adjust[BLUE ]) / 65025), (int)UINT8_MAX); _mapping.green[input] = static_cast<quint8>(qBound(0 ,_adjust.green * adjustedInput, UINT8_MAX));
_mapping.blue[input] = static_cast<quint8>(qBound(0, _adjust.blue * adjustedInput, UINT8_MAX));
_initialized[input] = true; _initialized[input] = true;
} }
red = _mapping[RED ][input]; red = _mapping.red[input];
green = _mapping[GREEN][input]; green = _mapping.green[input];
blue = _mapping[BLUE ][input]; blue = _mapping.blue[input];
} }

View File

@ -2,10 +2,8 @@
#include <utils/RgbTransform.h> #include <utils/RgbTransform.h>
#include <utils/KelvinToRgb.h> #include <utils/KelvinToRgb.h>
#include<QDebug>
RgbTransform::RgbTransform() RgbTransform::RgbTransform()
: RgbTransform::RgbTransform(1.0, 1.0, 1.0, 0.0, false, 100, 100, 6600) : RgbTransform::RgbTransform(1.0, 1.0, 1.0, 0.0, false, 100, 100, ColorTemperature::DEFAULT)
{ {
} }
@ -66,9 +64,9 @@ void RgbTransform::initializeMapping()
double gammaCorrectedValueB = qPow(normalizedValueB, _gammaB) * UINT8_MAX; double gammaCorrectedValueB = qPow(normalizedValueB, _gammaB) * UINT8_MAX;
// Clamp values to valid range [0, UINT8_MAX] // Clamp values to valid range [0, UINT8_MAX]
quint8 clampedValueR = static_cast<quint8>(qMin(qMax(gammaCorrectedValueR, 0.0), static_cast<double>(UINT8_MAX))); quint8 clampedValueR = static_cast<quint8>(qBound(0.0, gammaCorrectedValueR, static_cast<double>(UINT8_MAX)));
quint8 clampedValueG = static_cast<quint8>(qMin(qMax(gammaCorrectedValueG, 0.0), static_cast<double>(UINT8_MAX))); quint8 clampedValueG = static_cast<quint8>(qBound(0.0, gammaCorrectedValueG, static_cast<double>(UINT8_MAX)));
quint8 clampedValueB = static_cast<quint8>(qMin(qMax(gammaCorrectedValueB, 0.0), static_cast<double>(UINT8_MAX))); quint8 clampedValueB = static_cast<quint8>(qBound(0.0, gammaCorrectedValueB, static_cast<double>(UINT8_MAX)));
// Assign clamped values to _mapping arrays // Assign clamped values to _mapping arrays
_mappingR[i] = clampedValueR; _mappingR[i] = clampedValueR;