fix/refactor backlight stuff (#394)

* fix/refactor backlight stuff:
- fix colors dont turn of when backlight 0 and black is set
- add option to use not colored backlight
- fix colored backlight not colored on very low color values
- various code style tunings

* apply needed change to wizard

* backlight disabled on static color and efects

* fix warnings

* try fix udp compiler warnings
This commit is contained in:
redPanther
2017-02-11 22:52:47 +01:00
committed by GitHub
parent 199d266bc0
commit e1165e112f
33 changed files with 364 additions and 240 deletions

View File

@@ -6,25 +6,27 @@ using namespace commandline;
bool ColorOption::validate(Parser & parser, QString & value)
{
// Check if we can create the color by name
_color = QColor(value);
if (_color.isValid()) {
return true;
}
// Check if we can create the color by name
_color = QColor(value);
if (_color.isValid())
{
return true;
}
// check if we can create the color by hex RRGGBB getColors
_color = QColor(QString("#%1").arg(value));
if (_color.isValid()) {
return true;
}
// check if we can create the color by hex RRGGBB getColors
_color = QColor(QString("#%1").arg(value));
if (_color.isValid())
{
return true;
}
if(!parser.isSet(*this)){
// Return true if no value is available
return true;
}
if(!parser.isSet(*this))
{
// Return true if no value is available
return true;
}
QStringList error;
_error = QString("Invalid color. A color is specified by a six lettered RRGGBB hex getColors or one of the following names:\n\t- %1").arg(QColor::colorNames().join("\n\t- "));
_error = QString("Invalid color. A color is specified by a six lettered RRGGBB hex getColors or one of the following names:\n\t- %1").arg(QColor::colorNames().join("\n\t- "));
return false;
return false;
}

View File

@@ -6,32 +6,36 @@ using namespace commandline;
bool ColorsOption::validate(Parser & parser, QString & value)
{
// Clear any old results
_colors.clear();
// Clear any old results
_colors.clear();
// Check if we can create the color by name
QColor color(value);
if (color.isValid()) {
_colors.push_back(color);
return true;
}
// Check if we can create the color by name
QColor color(value);
if (color.isValid())
{
_colors.push_back(color);
return true;
}
// check if we can create the color by hex RRGGBB getColors
QRegularExpression hexRe("^([0-9A-F]{6})+$", QRegularExpression::CaseInsensitiveOption);
QRegularExpressionMatch match = hexRe.match(value);
if(match.hasMatch()) {
Q_FOREACH(const QString m, match.capturedTexts()){
_colors.push_back(QColor(QString("#%1").arg(m)));
}
return true;
}
// check if we can create the color by hex RRGGBB getColors
QRegularExpression hexRe("^([0-9A-F]{6})+$", QRegularExpression::CaseInsensitiveOption);
QRegularExpressionMatch match = hexRe.match(value);
if(match.hasMatch())
{
Q_FOREACH(const QString m, match.capturedTexts())
{
_colors.push_back(QColor(QString("#%1").arg(m)));
}
return true;
}
if(!parser.isSet(*this)){
if(!parser.isSet(*this))
{
// Return true if no value is available
return true;
}
_error = QString("Invalid color. A color is specified by a six lettered RRGGBB hex getColors or one of the following names:\n\t- %1").arg(QColor::colorNames().join("\n\t- "));
_error = QString("Invalid color. A color is specified by a six lettered RRGGBB hex getColors or one of the following names:\n\t- %1").arg(QColor::colorNames().join("\n\t- "));
return false;
return false;
}

View File

@@ -5,16 +5,17 @@ using namespace commandline;
double DoubleOption::getDouble(Parser &parser, bool *ok)
{
_double = value(parser).toDouble(ok);
return _double;
_double = value(parser).toDouble(ok);
return _double;
}
double *DoubleOption::getDoublePtr(Parser &parser, bool *ok)
{
if (parser.isSet(this)) {
getDouble(parser, ok);
return &_double;
} else {
return nullptr;
}
if (parser.isSet(this))
{
getDouble(parser, ok);
return &_double;
}
return nullptr;
}

View File

@@ -4,7 +4,8 @@ using namespace commandline;
bool ImageOption::validate(Parser & parser, QString & value)
{
if(value.size()){
if(value.size())
{
_image = QImage(value);
if (_image.isNull())
@@ -12,7 +13,7 @@ bool ImageOption::validate(Parser & parser, QString & value)
_error = QString("File %1 could not be opened as image").arg(value);
return false;
}
}
}
return true;
return true;
}

View File

@@ -5,16 +5,16 @@ using namespace commandline;
int IntOption::getInt(Parser &parser, bool *ok, int base)
{
_int = value(parser).toInt(ok, base);
return _int;
_int = value(parser).toInt(ok, base);
return _int;
}
int *IntOption::getIntPtr(Parser &parser, bool *ok, int base)
{
if (parser.isSet(this)) {
getInt(parser, ok, base);
return &_int;
} else {
return nullptr;
}
if (parser.isSet(this))
{
getInt(parser, ok, base);
return &_int;
}
return nullptr;
}

View File

@@ -6,26 +6,26 @@ using namespace commandline;
bool Option::validate(Parser & parser, QString &value)
{
/* By default everything is accepted */
return true;
return true;
}
QString Option::value(Parser &parser)
{
return parser.value(*this);
return parser.value(*this);
}
std::string Option::getStdString(Parser &parser)
{
return value(parser).toStdString();
return value(parser).toStdString();
}
std::wstring Option::getStdWString(Parser &parser)
{
return value(parser).toStdWString();
return value(parser).toStdWString();
}
const char* Option::getCString(Parser &parser)
{
return value(parser).toLocal8Bit().constData();
return value(parser).toLocal8Bit().constData();
}

View File

@@ -6,85 +6,88 @@ using namespace commandline;
bool Parser::parse(const QStringList &arguments)
{
if (!_parser.parse(arguments)) {
return false;
}
if (!_parser.parse(arguments))
{
return false;
}
Q_FOREACH(Option * option, _options) {
QString value = this->value(*option);
if (!option->validate(*this, value)) {
const QString error = option->getError();
if (error.size()) {
_errorText = tr("%1 is not a valid option for %2\n%3").arg(value, option->name(), error);
}
else {
_errorText = tr("%1 is not a valid option for %2").arg(value, option->name());
}
return false;
Q_FOREACH(Option * option, _options)
{
QString value = this->value(*option);
if (!option->validate(*this, value)) {
const QString error = option->getError();
if (error.size()) {
_errorText = tr("%1 is not a valid option for %2\n%3").arg(value, option->name(), error);
}
}
return true;
else
{
_errorText = tr("%1 is not a valid option for %2").arg(value, option->name());
}
return false;
}
}
return true;
}
void Parser::process(const QStringList &arguments)
{
_parser.process(arguments);
if (!parse(arguments)) {
_parser.process(arguments);
if (!parse(arguments))
{
fprintf(stdout, "%s", qPrintable(tr("Error: %1").arg(_errorText)));
showHelp(EXIT_FAILURE);
}
showHelp(EXIT_FAILURE);
}
}
void Parser::process(const QCoreApplication &app)
{
Q_UNUSED(app);
process(QCoreApplication::arguments());
Q_UNUSED(app);
process(QCoreApplication::arguments());
}
QString Parser::errorText() const
{
if (_errorText.size()) {
return _errorText;
}
else {
return _parser.errorText();
}
return (_errorText.size()) ? _errorText : _parser.errorText();
}
bool Parser::addOption(Option &option)
{
return addOption(&option);
return addOption(&option);
}
bool Parser::addOption(Option * const option)
{
_options[option->name()] = option;
return _parser.addOption(*option);
_options[option->name()] = option;
return _parser.addOption(*option);
}
QStringList Parser::_getNames(const char shortOption, const QString longOption)
{
QStringList names;
if (shortOption != 0x0) {
if (shortOption != 0x0)
{
names << QString(shortOption);
}
if (longOption.size()) {
if (longOption.size())
{
names << longOption;
}
return names;
}
QString Parser::_getDescription(const QString description, const QString default_)
{
/* Add the translations if available */
QString formattedDescription(tr(qPrintable(description)));
/* Fill in the default if needed */
if (default_.size()) {
if(!formattedDescription.contains("%1")){
if (default_.size())
{
if(!formattedDescription.contains("%1"))
{
formattedDescription += " [default: %1]";
}
formattedDescription = formattedDescription.arg(default_);
}
return formattedDescription;
}

View File

@@ -5,21 +5,22 @@ using namespace commandline;
bool ValidatorOption::validate(Parser & parser, QString & value)
{
if (parser.isSet(*this) || !defaultValues().empty()) {
if (parser.isSet(*this) || !defaultValues().empty())
{
int pos = 0;
validator->fixup(value);
return validator->validate(value, pos) == QValidator::Acceptable;
} else {
return true;
}
return true;
}
const QValidator *ValidatorOption::getValidator() const
{
return validator;
}
void ValidatorOption::setValidator(const QValidator *validator)
{
ValidatorOption::validator = validator;
return validator;
}
void ValidatorOption::setValidator(const QValidator *validator)
{
ValidatorOption::validator = validator;
}

View File

@@ -158,13 +158,14 @@ MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt
RgbTransform* Hyperion::createRgbTransform(const QJsonObject& colorConfig)
{
const double brightnessMin = colorConfig["brightnessMin"].toDouble(0.0);
const double backlightThreshold = colorConfig["backlightThreshold"].toDouble(0.0);
const bool backlightColored = colorConfig["backlightColored"].toBool(false);
const double brightness = colorConfig["brightness"].toDouble(0.5);
const double gammaR = colorConfig["gammaRed"].toDouble(1.0);
const double gammaG = colorConfig["gammaGreen"].toDouble(1.0);
const double gammaB = colorConfig["gammaBlue"].toDouble(1.0);
RgbTransform* transform = new RgbTransform(gammaR, gammaG, gammaB, brightnessMin, brightness);
RgbTransform* transform = new RgbTransform(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, brightness);
return transform;
}
@@ -392,10 +393,10 @@ Hyperion::Hyperion(const QJsonObject &qjsonConfig, const QString configFile)
, _timer()
, _log(CORE_LOGGER)
, _hwLedCount(_ledString.leds().size())
, _sourceAutoSelectEnabled(true)
, _configHash()
, _ledGridSize(getLedLayoutGridSize(qjsonConfig["leds"]))
, _prevCompId(hyperion::COMP_INVALID)
{
registerPriority("Off", PriorityMuxer::LOWEST_PRIORITY);
@@ -718,6 +719,12 @@ void Hyperion::update()
if ( priority < PriorityMuxer::LOWEST_PRIORITY)
{
if (priorityInfo.componentId != _prevCompId)
{
bool backlightEnabled = (priorityInfo.componentId != hyperion::COMP_COLOR && priorityInfo.componentId != hyperion::COMP_EFFECT);
_raw2ledAdjustment->setBacklightEnabled(backlightEnabled);
_prevCompId = priorityInfo.componentId;
}
_raw2ledAdjustment->applyAdjustment(_ledBuffer);
}

View File

@@ -51,11 +51,11 @@ bool MultiColorAdjustment::verifyAdjustments() const
Error(_log, "No adjustment set for %d", iLed);
return false;
}
if (adjustment->_rgbTransform.getBrightness() <= adjustment->_rgbTransform.getBrightnessMin() )
if (adjustment->_rgbTransform.getBrightness() <= adjustment->_rgbTransform.getBacklightThreshold() )
{
adjustment->_rgbTransform.setBrightnessMin(0);
adjustment->_rgbTransform.setBacklightThreshold(0.0);
adjustment->_rgbTransform.setBrightness(0.5);
Warning(_log, "Adjustment for %d has invalid Brightness values, values set to default. (brightnessMin is bigger then brightness)", iLed);
Warning(_log, "Adjustment for %d has invalid Brightness values, values set to default. (setBacklightThreshold is bigger then brightness)", iLed);
}
}
return true;
@@ -81,6 +81,15 @@ ColorAdjustment* MultiColorAdjustment::getAdjustment(const std::string& id)
return nullptr;
}
void MultiColorAdjustment::setBacklightEnabled(bool enable)
{
for (ColorAdjustment* adjustment : _adjustment)
{
adjustment->_rgbTransform.setBackLightEnabled(enable);
}
}
void MultiColorAdjustment::applyAdjustment(std::vector<ColorRgb>& ledColors)
{
const size_t itCnt = std::min(_ledAdjustments.size(), ledColors.size());

View File

@@ -30,6 +30,8 @@ public:
bool verifyAdjustments() const;
void setBacklightEnabled(bool enable);
///
/// Returns the identifier of all the unique ColorAdjustment
///

View File

@@ -271,10 +271,10 @@
"maxItems" : 3,
"propertyOrder" : 10
},
"brightnessMin" :
"backlightThreshold" :
{
"type" : "number",
"title" : "edt_conf_color_brightnessMin_title",
"title" : "edt_conf_color_backlightThreshold_title",
"required" : true,
"minimum" : 0.0,
"maximum": 1.0,
@@ -282,6 +282,14 @@
"step" : 0.05,
"propertyOrder" : 11
},
"backlightColored" :
{
"type" : "boolean",
"title" : "edt_conf_color_backlightColored_title",
"required" : true,
"default" : false,
"propertyOrder" : 12
},
"brightness" :
{
"type" : "number",
@@ -291,7 +299,7 @@
"maximum": 1.0,
"default" : 1.0,
"step" : 0.05,
"propertyOrder" : 12
"propertyOrder" : 13
},
"gammaRed" :
{
@@ -302,7 +310,7 @@
"maximum": 100.0,
"default" : 1.0,
"step" : 0.1,
"propertyOrder" : 13
"propertyOrder" : 14
},
"gammaGreen" :
{
@@ -313,7 +321,7 @@
"maximum": 100.0,
"default" : 1.0,
"step" : 0.1,
"propertyOrder" : 14
"propertyOrder" : 15
},
"gammaBlue" :
{
@@ -324,7 +332,7 @@
"maximum": 100.0,
"default" : 1.0,
"step" : 0.1,
"propertyOrder" : 15
"propertyOrder" : 16
}
},
"additionalProperties" : false

View File

@@ -731,11 +731,12 @@ void JsonClientConnection::handleServerInfoCommand(const QJsonObject&, const QSt
yellowAdjust.append(colorAdjustment->_rgbYellowAdjustment.getAdjustmentB());
adjustment.insert("yellow", yellowAdjust);
adjustment["brightnessMin"] = colorAdjustment->_rgbTransform.getBrightnessMin();
adjustment["backlightThreshold"] = colorAdjustment->_rgbTransform.getBacklightThreshold();
adjustment["backlightColored"] = colorAdjustment->_rgbTransform.getBacklightColored();
adjustment["brightness"] = colorAdjustment->_rgbTransform.getBrightness();
adjustment["gammaRed"] = colorAdjustment->_rgbTransform.getGammaR();
adjustment["gammaRed"] = colorAdjustment->_rgbTransform.getGammaR();
adjustment["gammaGreen"] = colorAdjustment->_rgbTransform.getGammaG();
adjustment["gammaBlue"] = colorAdjustment->_rgbTransform.getGammaB();
adjustment["gammaBlue"] = colorAdjustment->_rgbTransform.getGammaB();
adjustmentArray.append(adjustment);
}
@@ -913,9 +914,13 @@ void JsonClientConnection::handleAdjustmentCommand(const QJsonObject& message, c
colorAdjustment->_rgbTransform.setGamma(colorAdjustment->_rgbTransform.getGammaR(), colorAdjustment->_rgbTransform.getGammaG(), adjustment["gammaBlue"].toDouble());
}
if (adjustment.contains("brightnessMin"))
if (adjustment.contains("backlightThreshold"))
{
colorAdjustment->_rgbTransform.setBrightnessMin(adjustment["brightnessMin"].toDouble());
colorAdjustment->_rgbTransform.setBacklightThreshold(adjustment["backlightThreshold"].toDouble());
}
if (adjustment.contains("backlightColored"))
{
colorAdjustment->_rgbTransform.setBacklightColored(adjustment["backlightColored"].toBool());
}
if (adjustment.contains("brightness"))
{

View File

@@ -351,13 +351,13 @@ private:
// masks for fields in the basic header
static uint8_t const BHB0_OPCODE = 0x0F;
static uint8_t const BHB0_RSV3 = 0x10;
static uint8_t const BHB0_RSV2 = 0x20;
static uint8_t const BHB0_RSV1 = 0x40;
static uint8_t const BHB0_FIN = 0x80;
static uint8_t const BHB0_RSV3 = 0x10;
static uint8_t const BHB0_RSV2 = 0x20;
static uint8_t const BHB0_RSV1 = 0x40;
static uint8_t const BHB0_FIN = 0x80;
static uint8_t const BHB1_PAYLOAD = 0x7F;
static uint8_t const BHB1_MASK = 0x80;
static uint8_t const BHB1_MASK = 0x80;
static uint8_t const payload_size_code_16bit = 0x7E; // 126
static uint8_t const payload_size_code_64bit = 0x7F; // 127

View File

@@ -124,12 +124,16 @@
"minimum" : 0.0,
"maximum" : 100.0
},
"brightnessMin" : {
"backlightThreshold" : {
"type" : "number",
"required" : false,
"minimum" : 0.0,
"maximum" : 1.0
},
"backlightColored" : {
"type" : "boolean",
"required" : false
},
"brightness" : {
"type" : "number",
"required" : false,

View File

@@ -82,17 +82,17 @@ typedef union
} e131_packet_t;
/* defined parameters from http://tsp.esta.org/tsp/documents/docs/BSR_E1-31-20xx_CP-2014-1009r2.pdf */
#define VECTOR_ROOT_E131_DATA 0x00000004
#define VECTOR_ROOT_E131_EXTENDED 0x00000008
#define VECTOR_DMP_SET_PROPERTY 0x02
#define VECTOR_E131_DATA_PACKET 0x00000002
#define VECTOR_E131_EXTENDED_SYNCHRONIZATION 0x00000001
#define VECTOR_E131_EXTENDED_DISCOVERY 0x00000002
#define VECTOR_ROOT_E131_DATA 0x00000004
#define VECTOR_ROOT_E131_EXTENDED 0x00000008
#define VECTOR_DMP_SET_PROPERTY 0x02
#define VECTOR_E131_DATA_PACKET 0x00000002
#define VECTOR_E131_EXTENDED_SYNCHRONIZATION 0x00000001
#define VECTOR_E131_EXTENDED_DISCOVERY 0x00000002
#define VECTOR_UNIVERSE_DISCOVERY_UNIVERSE_LIST 0x00000001
#define E131_E131_UNIVERSE_DISCOVERY_INTERVAL 10 // seconds
#define E131_NETWORK_DATA_LOSS_TIMEOUT 2500 // milli econds
#define E131_DISCOVERY_UNIVERSE 64214
#define DMX_MAX 512 // 512 usable slots
#define E131_E131_UNIVERSE_DISCOVERY_INTERVAL 10 // seconds
#define E131_NETWORK_DATA_LOSS_TIMEOUT 2500 // milli econds
#define E131_DISCOVERY_UNIVERSE 64214
#define DMX_MAX 512 // 512 usable slots
///
/// Implementation of the LedDevice interface for sending led colors via udp/E1.31 packets

View File

@@ -11,7 +11,8 @@ bool LedDeviceUdpH801::init(const QJsonObject &deviceConfig)
/* The H801 port is fixed */
_LatchTime_ns = 10000000;
_port = 30977;
ProviderUdp::init(deviceConfig, "255.255.255.255");
_defaultHost = "255.255.255.255";
ProviderUdp::init(deviceConfig);
_ids.clear();
QJsonArray lArray = deviceConfig["lightIds"].toArray();

View File

@@ -19,6 +19,7 @@ ProviderUdp::ProviderUdp()
: LedDevice()
, _LatchTime_ns(-1)
, _port(1)
, _defaultHost("127.0.0.1")
{
_udpSocket = new QUdpSocket();
}
@@ -28,11 +29,11 @@ ProviderUdp::~ProviderUdp()
_udpSocket->close();
}
bool ProviderUdp::init(const QJsonObject &deviceConfig, std::string defaultHost)
bool ProviderUdp::init(const QJsonObject &deviceConfig)
{
LedDevice::init(deviceConfig);
QString host = deviceConfig["host"].toString(QString::fromStdString(defaultHost));
QString host = deviceConfig["host"].toString(_defaultHost);
if (_address.setAddress(host) )
{

View File

@@ -27,7 +27,7 @@ public:
///
/// @param deviceConfig the json device config
/// @return true if success
bool init(const QJsonObject &deviceConfig, std::string defaultHost="127.0.0.1");
virtual bool init(const QJsonObject &deviceConfig);
///
/// Opens and configures the output device
@@ -55,4 +55,5 @@ protected:
QUdpSocket * _udpSocket;
QHostAddress _address;
quint16 _port;
QString _defaultHost;
};

View File

@@ -11,7 +11,6 @@ static const char * LogLevelStrings[] = { "", "DEBUG", "INFO", "WARNING", "ERR
static const int LogLevelSysLog[] = { LOG_DEBUG, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR };
static unsigned int loggerCount = 0;
static unsigned int loggerId = 0;
static const int loggerMaxMsgBufferSize = 50;
std::map<std::string,Logger*> *Logger::LoggerMap = nullptr;
Logger::LogLevel Logger::GLOBAL_MIN_LOG_LEVEL = Logger::UNSET;

View File

@@ -5,18 +5,20 @@
RgbTransform::RgbTransform()
{
init(1.0, 1.0, 1.0, 0.0, 1.0);
init(1.0, 1.0, 1.0, 0.0, false, 1.0);
}
RgbTransform::RgbTransform(double gammaR, double gammaG, double gammaB, double brightnessLow, double brightnessHigh)
RgbTransform::RgbTransform(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, double brightnessHigh)
{
init(gammaR, gammaG, gammaB, brightnessLow, brightnessHigh);
init(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, brightnessHigh);
}
void RgbTransform::init(double gammaR, double gammaG, double gammaB, double brightnessLow, double brightnessHigh)
void RgbTransform::init(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, double brightnessHigh)
{
_backLightEnabled = true;
setGamma(gammaR,gammaG,gammaB);
setBrightnessMin(brightnessLow);
setBacklightThreshold(backlightThreshold);
setBacklightColored(backlightColored);
setBrightness(brightnessHigh);
initializeMapping();
}
@@ -59,15 +61,35 @@ void RgbTransform::initializeMapping()
}
double RgbTransform::getBrightnessMin() const
double RgbTransform::getBacklightThreshold() const
{
return _brightnessLow;
return _backlightThreshold;
}
void RgbTransform::setBrightnessMin(double brightness)
void RgbTransform::setBacklightThreshold(double backlightThreshold)
{
_brightnessLow = brightness;
_sumBrightnessLow = 765.0 * ((std::pow(2.0,brightness*2)-1) / 3.0);
_backlightThreshold = backlightThreshold;
_sumBrightnessLow = 765.0 * ((std::pow(2.0,backlightThreshold*2)-1) / 3.0);
}
bool RgbTransform::getBacklightColored() const
{
return _backlightColored;
}
void RgbTransform::setBacklightColored(bool backlightColored)
{
_backlightColored = backlightColored;
}
bool RgbTransform::getBackLightEnabled() const
{
return _backLightEnabled;
}
void RgbTransform::setBackLightEnabled(bool enable)
{
_backLightEnabled = enable;
}
double RgbTransform::getBrightness() const
@@ -90,25 +112,38 @@ void RgbTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue)
//std::cout << (int)red << " " << (int)green << " " << (int)blue << " => ";
// apply brightnesss
if (red ==0) red = 1;
if (green==0) green = 1;
if (blue ==0) blue = 1;
int rgbSum = red+green+blue;
if (rgbSum > _sumBrightnessHigh)
if (_sumBrightnessHigh > 0 && rgbSum > _sumBrightnessHigh)
{
double cH = _sumBrightnessHigh / rgbSum;
red *= cH;
green *= cH;
blue *= cH;
}
else if (rgbSum < _sumBrightnessLow)
else if ( _backLightEnabled && _sumBrightnessLow>0 && rgbSum < _sumBrightnessLow)
{
double cL = _sumBrightnessLow / rgbSum;
red *= cL;
green *= cL;
blue *= cL;
if (_backlightColored)
{
if (rgbSum == 0)
{
if (red ==0) red = 1;
if (green==0) green = 1;
if (blue ==0) blue = 1;
rgbSum = red+green+blue;
}
double cL =std::min((int)(_sumBrightnessLow /rgbSum), 255);
red *= cL;
green *= cL;
blue *= cL;
}
else
{
red = std::min((int)(_sumBrightnessLow/3.0), 255);
green = red;
blue = red;
}
}
//std::cout << (int)red << " " << (int)green << " " << (int)blue << std::endl;
//std::cout << _sumBrightnessLow << " " << (int)red << " " << (int)green << " " << (int)blue << std::endl;
}