Integrate color temperature into RGB transformations

This commit is contained in:
LordGrey
2024-05-30 19:11:51 +02:00
parent 07dfce68f6
commit 5897e24316
17 changed files with 177 additions and 654 deletions

View File

@@ -57,8 +57,6 @@ add_library(hyperion-utils
# Rgb single color adjustment/correction
${CMAKE_SOURCE_DIR}/include/utils/RgbChannelAdjustment.h
${CMAKE_SOURCE_DIR}/libsrc/utils/RgbChannelAdjustment.cpp
${CMAKE_SOURCE_DIR}/include/utils/RgbChannelCorrection.h
${CMAKE_SOURCE_DIR}/libsrc/utils/RgbChannelCorrection.cpp
# Color conversion/transformation
${CMAKE_SOURCE_DIR}/include/utils/RgbToRgbw.h
${CMAKE_SOURCE_DIR}/libsrc/utils/RgbToRgbw.cpp

View File

@@ -1,120 +0,0 @@
// STL includes
#include <cmath>
// Utils includes
#include <utils/RgbChannelCorrection.h>
RgbChannelCorrection::RgbChannelCorrection() :
_correctionR(255),
_correctionG(255),
_correctionB(255)
{
initializeMapping();
}
RgbChannelCorrection::RgbChannelCorrection(int correctionR, int correctionG, int correctionB) :
_correctionR(correctionR),
_correctionG(correctionG),
_correctionB(correctionB)
{
initializeMapping();
}
RgbChannelCorrection::~RgbChannelCorrection()
{
}
uint8_t RgbChannelCorrection::getcorrectionR() const
{
return _correctionR;
}
void RgbChannelCorrection::setcorrectionR(uint8_t correctionR)
{
_correctionR = correctionR;
initializeMapping();
}
uint8_t RgbChannelCorrection::getcorrectionG() const
{
return _correctionG;
}
void RgbChannelCorrection::setcorrectionG(uint8_t correctionG)
{
_correctionG = correctionG;
initializeMapping();
}
uint8_t RgbChannelCorrection::getcorrectionB() const
{
return _correctionB;
}
void RgbChannelCorrection::setcorrectionB(uint8_t correctionB)
{
_correctionB = correctionB;
initializeMapping();
}
uint8_t RgbChannelCorrection::correctionR(uint8_t inputR) const
{
return _mappingR[inputR];
}
uint8_t RgbChannelCorrection::correctionG(uint8_t inputG) const
{
return _mappingG[inputG];
}
uint8_t RgbChannelCorrection::correctionB(uint8_t inputB) const
{
return _mappingB[inputB];
}
void RgbChannelCorrection::initializeMapping()
{
// initialize the mapping
for (int i = 0; i < 256; ++i)
{
int outputR = (i * _correctionR) / 255;
if (outputR < -255)
{
outputR = -255;
}
else if (outputR > 255)
{
outputR = 255;
}
_mappingR[i] = outputR;
}
for (int i = 0; i < 256; ++i)
{
int outputG = (i * _correctionG) / 255;
if (outputG < -255)
{
outputG = -255;
}
else if (outputG > 255)
{
outputG = 255;
}
_mappingG[i] = outputG;
}
for (int i = 0; i < 256; ++i)
{
int outputB = (i * _correctionB) / 255;
if (outputB < -255)
{
outputB = -255;
}
else if (outputB > 255)
{
outputB = 255;
}
_mappingB[i] = outputB;
}
}

View File

@@ -1,19 +1,22 @@
#include <QtCore/qmath.h>
#include <utils/RgbTransform.h>
#include <utils/KelvinToRgb.h>
#include<QDebug>
RgbTransform::RgbTransform()
: RgbTransform::RgbTransform(1.0, 1.0, 1.0, 0.0, false, 100, 100)
: RgbTransform::RgbTransform(1.0, 1.0, 1.0, 0.0, false, 100, 100, 6600)
{
}
RgbTransform::RgbTransform(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, uint8_t brightness, uint8_t brightnessCompensation)
RgbTransform::RgbTransform(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, uint8_t brightness, uint8_t brightnessCompensation, int temperature)
: _brightness(brightness)
, _brightnessCompensation(brightnessCompensation)
{
init(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, _brightness, _brightnessCompensation);
init(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, _brightness, _brightnessCompensation, temperature);
}
void RgbTransform::init(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, uint8_t brightness, uint8_t brightnessCompensation)
void RgbTransform::init(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, uint8_t brightness, uint8_t brightnessCompensation, int temperature)
{
_backLightEnabled = true;
setGamma(gammaR,gammaG,gammaB);
@@ -21,6 +24,7 @@ void RgbTransform::init(double gammaR, double gammaG, double gammaB, double back
setBacklightColored(backlightColored);
setBrightness(brightness);
setBrightnessCompensation(brightnessCompensation);
setTemperature(temperature);
initializeMapping();
}
@@ -49,18 +53,34 @@ void RgbTransform::setGamma(double gammaR, double gammaG, double gammaB)
void RgbTransform::initializeMapping()
{
for (int i = 0; i < 256; ++i)
for (int i = 0; i <= UINT8_MAX; ++i)
{
_mappingR[i] = qMin(qMax((int)(qPow(i / 255.0, _gammaR) * 255), 0), 255);
_mappingG[i] = qMin(qMax((int)(qPow(i / 255.0, _gammaG) * 255), 0), 255);
_mappingB[i] = qMin(qMax((int)(qPow(i / 255.0, _gammaB) * 255), 0), 255);
// Calculate normalized value
double normalizedValueR = static_cast<double>(i) / UINT8_MAX;
double normalizedValueG = static_cast<double>(i) / UINT8_MAX;
double normalizedValueB = static_cast<double>(i) / UINT8_MAX;
// Apply gamma correction
double gammaCorrectedValueR = qPow(normalizedValueR, _gammaR) * UINT8_MAX;
double gammaCorrectedValueG = qPow(normalizedValueG, _gammaG) * UINT8_MAX;
double gammaCorrectedValueB = qPow(normalizedValueB, _gammaB) * 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 clampedValueG = static_cast<quint8>(qMin(qMax(gammaCorrectedValueG, 0.0), static_cast<double>(UINT8_MAX)));
quint8 clampedValueB = static_cast<quint8>(qMin(qMax(gammaCorrectedValueB, 0.0), static_cast<double>(UINT8_MAX)));
// Assign clamped values to _mapping arrays
_mappingR[i] = clampedValueR;
_mappingG[i] = clampedValueG;
_mappingB[i] = clampedValueB;
}
}
int RgbTransform::getBacklightThreshold() const
{
return _backlightThreshold;
return static_cast<int>(_backlightThreshold);
}
void RgbTransform::setBacklightThreshold(double backlightThreshold)
@@ -116,60 +136,81 @@ void RgbTransform::updateBrightnessComponents()
double Fw = _brightnessCompensation*2.0/100.0+1.0;
double Fcmy = _brightnessCompensation/100.0+1.0;
double B_in= 0;
_brightness_rgb = 0;
_brightness_cmy = 0;
_brightness_w = 0;
if (_brightness > 0)
{
B_in = (_brightness<50)? -0.09*_brightness+7.5 : -0.04*_brightness+5.0;
double B_in = (_brightness < 50) ? -0.09 * _brightness + 7.5 : -0.04 * _brightness + 5.0;
_brightness_rgb = std::ceil(qMin(255.0,255.0/B_in));
_brightness_cmy = std::ceil(qMin(255.0,255.0/(B_in*Fcmy)));
_brightness_w = std::ceil(qMin(255.0,255.0/(B_in*Fw)));
// Ensure that the result is converted to an integer before assigning to uint8_t
_brightness_rgb = static_cast<uint8_t>(std::ceil(qMin(static_cast<double>(UINT8_MAX), UINT8_MAX / B_in)));
_brightness_cmy = static_cast<uint8_t>(std::ceil(qMin(static_cast<double>(UINT8_MAX), UINT8_MAX / (B_in * Fcmy))));
_brightness_w = static_cast<uint8_t>(std::ceil(qMin(static_cast<double>(UINT8_MAX), UINT8_MAX / (B_in * Fw))));
}
}
void RgbTransform::getBrightnessComponents(uint8_t & rgb, uint8_t & cmy, uint8_t & w) const
void RgbTransform::getBrightnessComponents(uint8_t & rgb, uint8_t & cmy, uint8_t & white) const
{
rgb = _brightness_rgb;
cmy = _brightness_cmy;
w = _brightness_w;
white = _brightness_w;
}
void RgbTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue)
void RgbTransform::applyGamma(uint8_t & red, uint8_t & green, uint8_t & blue)
{
// apply gamma
red = _mappingR[red];
green = _mappingG[green];
blue = _mappingB[blue];
}
void RgbTransform::applyBacklight(uint8_t & red, uint8_t & green, uint8_t & blue) const
{
// apply brightnesss
int rgbSum = red+green+blue;
if ( _backLightEnabled && _sumBrightnessLow>0 && rgbSum < _sumBrightnessLow)
if ( _backLightEnabled && _sumBrightnessLow > 0 && rgbSum < _sumBrightnessLow)
{
if (_backlightColored)
{
if (rgbSum == 0)
{
if (red ==0) red = 1;
if (green==0) green = 1;
if (blue ==0) blue = 1;
if (red ==0) { red = 1; }
if (green==0) { green = 1; }
if (blue ==0) { blue = 1; }
rgbSum = red+green+blue;
}
double cL =qMin((int)(_sumBrightnessLow /rgbSum), 255);
red *= cL;
green *= cL;
blue *= cL;
uint8_t cLow = static_cast<uint8_t>(qMin(static_cast<int>(_sumBrightnessLow / rgbSum), UINT8_MAX));
red *= cLow;
green *= cLow;
blue *= cLow;
}
else
{
red = qMin((int)(_sumBrightnessLow/3.0), 255);
red = static_cast<uint8_t>(qMin(static_cast<int>(_sumBrightnessLow/3.0), UINT8_MAX));
green = red;
blue = red;
}
}
}
void RgbTransform::setTemperature(int temperature)
{
_temperature = temperature;
_temperatureRGB = getRgbFromTemperature(_temperature);
}
int RgbTransform::getTemperature() const
{
return _temperature;
}
void RgbTransform::applyTemperature(ColorRgb& color) const
{
color.red = color.red * _temperatureRGB.red / UINT8_MAX;
color.green = color.green * _temperatureRGB.green / UINT8_MAX;
color.blue = color.blue * _temperatureRGB.blue / UINT8_MAX;
}