From 5ea3c752b575c11772499860c1ae88cfaeccfe14 Mon Sep 17 00:00:00 2001 From: redPanther Date: Mon, 3 Apr 2017 05:19:05 +0200 Subject: [PATCH] new brightness handling (#430) * clean color adjustment * now a prio duration of "0" means infinity * implement dynamic 'just in time' initialization * implement new brightness handling * cahnge access level * i18n fix * - cleanup brightness stuff - update webserver, now with initial ssl support * - backlightThreshold is now 0-100 instead 0-1 - better performance for brightness - use piecewise linear instead of sqrt --- assets/webconfig/i18n/de.json | 6 +- assets/webconfig/i18n/en.json | 6 +- assets/webconfig/js/content_remote.js | 4 +- assets/webconfig/js/hyperion.js | 2 +- assets/webconfig/js/ui_utils.js | 6 +- config/hyperion.config.json.commented | 14 +-- config/hyperion.config.json.default | 5 +- include/utils/RgbChannelAdjustment.h | 28 ++++-- include/utils/RgbTransform.h | 53 ++++++++--- libsrc/hyperion/Hyperion.cpp | 5 +- libsrc/hyperion/MultiColorAdjustment.cpp | 22 +++-- libsrc/hyperion/PriorityMuxer.cpp | 4 +- .../hyperion/schemas/hyperion.schema-2.json | 38 +++++--- libsrc/jsonserver/JsonClientConnection.cpp | 9 +- .../jsonserver/schema/schema-adjustment.json | 18 ++-- libsrc/utils/RgbChannelAdjustment.cpp | 41 +++++---- libsrc/utils/RgbTransform.cpp | 75 +++++++++++----- libsrc/webconfig/QtHttpServer.cpp | 89 ++++++++++++++++--- libsrc/webconfig/QtHttpServer.h | 51 +++++++++-- src/hyperion-remote/JsonConnection.cpp | 9 +- src/hyperion-remote/JsonConnection.h | 5 +- src/hyperion-remote/hyperion-remote.cpp | 15 ++-- 22 files changed, 366 insertions(+), 139 deletions(-) diff --git a/assets/webconfig/i18n/de.json b/assets/webconfig/i18n/de.json index a87e3c75..52b8dc6b 100644 --- a/assets/webconfig/i18n/de.json +++ b/assets/webconfig/i18n/de.json @@ -439,8 +439,10 @@ "edt_conf_color_backlightThreshold_expl" : "Eine Beleuchtung die dauerhaft aktiv ist. (Automatisch deaktiviert bei Effekten, Farben oder im Zustand \"Aus\")", "edt_conf_color_backlightColored_title" : "Farbige Hintergrund - beleuchtung", "edt_conf_color_backlightColored_expl" : "Die Hintergrundbeleuchtung kann mit oder ohne Farbanteile genutzt werden.", - "edt_conf_color_brightness_title" : "Maximale Helligkeit", - "edt_conf_color_brightness_expl" : "Zwischen 0.0 und 0.5 ist die Helligkeit linearisiert. Von 0.5 bis 1.0 wird cyan, magenta und gelb bis zu 2x heller und weiß bis zu 3x.", + "edt_conf_color_brightness_title" : "Helligkeit", + "edt_conf_color_brightness_expl" : "die desamt Helligkeit", + "edt_conf_color_brightnessComp_title" : "Helligkeits Kompensation", + "edt_conf_color_brightnessComp_expl" : "Kompensiert unterschiede in der Helligkeit zwischen RGB, CMY und weiß. 100 ist volle Kompensation, 0 keine Kompensation", "edt_conf_smooth_heading_title" : "Glättung", "edt_conf_smooth_type_title" : "Art", "edt_conf_smooth_type_expl" : "Algorithmus der Glättung.", diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json index 7bbf0173..2f54c44b 100644 --- a/assets/webconfig/i18n/en.json +++ b/assets/webconfig/i18n/en.json @@ -440,8 +440,10 @@ "edt_conf_color_backlightThreshold_expl" : "The minimum amount of brightness (backlight). Disabled during effects, colors and in status \"Off\"", "edt_conf_color_backlightColored_title" : "Colored backlight", "edt_conf_color_backlightColored_expl" : "Add some color to your backlight.", - "edt_conf_color_brightness_title" : "maximal brightness", - "edt_conf_color_brightness_expl" : "From 0.0 to 0.5 the brightness is linearised, from 0.5 to 1.0 cyan, magenta, yellow is up to 2x brighter and white 3x.", + "edt_conf_color_brightness_title" : "brightness", + "edt_conf_color_brightness_expl" : "set overall brightness of leds", + "edt_conf_color_brightnessComp_title" : "Brightness Compensation", + "edt_conf_color_brightnessComp_expl" : "compensates bightness differences between RGB, CMY and white. 100 means full compensation, 0 no compensation", "edt_conf_smooth_heading_title" : "Smoothing", "edt_conf_smooth_type_title" : "Type", "edt_conf_smooth_type_expl" : "Type of smoothing.", diff --git a/assets/webconfig/js/content_remote.js b/assets/webconfig/js/content_remote.js index 25806868..aa2bb378 100644 --- a/assets/webconfig/js/content_remote.js +++ b/assets/webconfig/js/content_remote.js @@ -53,8 +53,8 @@ $(document).ready(function() { } else { - if(sColor[key].key == "brightness" || sColor[key].key == "backlightThreshold") - property = ''; + if(sColor[key].key == "backlightThreshold" || sColor[key].key == "brightness" || sColor[key].key == "brightnessCompensation") + property = ''; else property = ''; diff --git a/assets/webconfig/js/hyperion.js b/assets/webconfig/js/hyperion.js index ca5be504..1b31f175 100644 --- a/assets/webconfig/js/hyperion.js +++ b/assets/webconfig/js/hyperion.js @@ -41,7 +41,7 @@ function cron() function connectionLostDetection(type) { - if ( watchdog > 1 ) + if ( watchdog > 2 ) { var interval_id = window.setInterval("", 9999); // Get a reference to the last for (var i = 1; i < interval_id; i++) diff --git a/assets/webconfig/js/ui_utils.js b/assets/webconfig/js/ui_utils.js index 9893e391..9ca37938 100644 --- a/assets/webconfig/js/ui_utils.js +++ b/assets/webconfig/js/ui_utils.js @@ -235,14 +235,14 @@ function valValue(id,value,min,max) { if(typeof max === 'undefined' || max == "") max = 999999; - - if(value > max) + + if(Number(value) > Number(max)) { $('#'+id).val(max); showInfoDialog("warning","",$.i18n('edt_msg_error_maximum_incl',max)); return max; } - else if(value < min) + else if(Number(value) < Number(min)) { $('#'+id).val(min); showInfoDialog("warning","",$.i18n('edt_msg_error_minimum_incl',min)); diff --git a/config/hyperion.config.json.commented b/config/hyperion.config.json.commented index 0902c5d2..69f3a712 100644 --- a/config/hyperion.config.json.commented +++ b/config/hyperion.config.json.commented @@ -49,10 +49,11 @@ /// * 'gammaRed'/'gammaGreen'/'gammaBlue' : Gamma value for each channel /// * 'id' : The unique identifier of the channel adjustments (eg 'device_1') /// * 'id' : The unique identifier of the channel adjustments (eg 'device_1') - /// * 'backlightThreshold' : Minimum brightness (backlight) - /// * 'backlightColored' : backlight with color, instead of white - /// * 'brightness' : Between 0.0-0.5 the brightness is linearized (white is as bright as red, is as bright as yellow). - /// Between 0.5-1.0 the linearization reduces slowly until it's gone with 1.0 (white is 3x brighter than red, yellow is 2x brighter than red) + /// * 'backlightThreshold' : Minimum brightness (backlight) + /// * 'backlightColored' : backlight with color, instead of white + /// * 'brightness' : overall brightness + /// * 'brightnessCompensation' : 100 means brightness differences are compensated (white is as bright as red, is as bright as yellow. + /// 0 means white is 3x brighter than red, yellow is 2x brighter than red "color" : { "imageToLedMappingType" : "multicolor_mean", @@ -72,9 +73,10 @@ "gammaRed" : 1.5, "gammaGreen" : 1.5, "gammaBlue" : 1.5, - "backlightThreshold" : 0.0, + "backlightThreshold" : 0, "backlightColored" : false, - "brightness" : 0.5 + "brightness" : 100, + "brightnessCompensation" : 80 } ] }, diff --git a/config/hyperion.config.json.default b/config/hyperion.config.json.default index 0533f799..18f08b1b 100644 --- a/config/hyperion.config.json.default +++ b/config/hyperion.config.json.default @@ -38,9 +38,10 @@ "gammaRed" : 1.5, "gammaGreen" : 1.5, "gammaBlue" : 1.5, - "backlightThreshold" : 0.0, + "backlightThreshold" : 0, "backlightColored" : false, - "brightness" : 0.75 + "brightness" : 100, + "brightnessCompensation" : 100 } ] }, diff --git a/include/utils/RgbChannelAdjustment.h b/include/utils/RgbChannelAdjustment.h index 88bb9aea..9d53b290 100644 --- a/include/utils/RgbChannelAdjustment.h +++ b/include/utils/RgbChannelAdjustment.h @@ -22,14 +22,26 @@ public: /// Destructor ~RgbChannelAdjustment(); + /// /// Transform the given array value + /// /// @param input The input color bytes - void apply(uint8_t input, uint8_t & red, uint8_t & green, uint8_t & blue); + /// @param brightness The current brightness value + /// @param red The red color component + /// @param green The green color component + /// @param blue The blue color component + /// + /// @note The values are updated in place. + /// + void apply(uint8_t input, uint8_t brightness, uint8_t & red, uint8_t & green, uint8_t & blue); + /// /// setAdjustment RGB + /// /// @param adjustR /// @param adjustG /// @param adjustB + /// void setAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB); /// @return The current adjustR value @@ -43,11 +55,11 @@ public: private: /// color channels - enum ColorChannel { RED=0,GREEN=1, BLUE=2 }; + enum ColorChannel { RED=0, GREEN=1, BLUE=2 }; + + /// reset init of color mapping + void resetInitialized(); - /// (re)-initilize the color mapping - void initializeMapping(); - /// The adjustment of RGB channel uint8_t _adjust[3]; @@ -59,4 +71,10 @@ private: /// Logger instance Logger * _log; + + /// bitfield to determine white value is alreade initialized + bool _initialized[256]; + + /// current brightness value + uint8_t _brightness; }; diff --git a/include/utils/RgbTransform.h b/include/utils/RgbTransform.h index 32523362..0cb45b8e 100644 --- a/include/utils/RgbTransform.h +++ b/include/utils/RgbTransform.h @@ -24,7 +24,7 @@ public: /// @param backlightColored use color in backlight /// @param brightnessHigh The used higher brightness /// - RgbTransform(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, double brightnessHigh); + RgbTransform(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, uint8_t brightness, uint8_t brightnessCompensation); /// /// Destructor @@ -46,10 +46,10 @@ public: void setGamma(double gammaR,double gammaG=-1, double gammaB=-1); /// @return The current lower brightness - double getBacklightThreshold() const; + int getBacklightThreshold() const; /// @param backlightThreshold New lower brightness - void setBacklightThreshold(double backlightThreshold); + void setBacklightThreshold(int backlightThreshold); /// @return The current state bool getBacklightColored() const; @@ -63,12 +63,28 @@ public: /// @param enable en/disable backlight void setBackLightEnabled(bool enable); - /// @return The current brightness - double getBrightness() const; + uint8_t getBrightness() const; /// @param brightness New brightness - void setBrightness(double brightness); + void setBrightness(uint8_t brightness); + + /// @return The current brightnessCompensation value + uint8_t getBrightnessCompensation() const; + + /// @param brightnessCompensation new brightnessCompensation + void setBrightnessCompensation(uint8_t brightnessCompensation); + + /// + /// get component values of brightness for compensated brightness + /// + /// @param rgb the rgb component + /// @param cmy the cyan magenta yellow component + /// @param w the white component + /// + /// @note The values are updated in place. + /// + void getBrightnessComponents(uint8_t & rgb, uint8_t & cmy, uint8_t & w ); /// /// Apply the transform the the given RGB values. @@ -90,19 +106,23 @@ private: /// @param gammab The used blue gamma /// @param backlightThreshold The used lower brightness /// @param backlightColored en/disable color in backlight - /// @param brightnessHigh The used higher brightness + /// @param brightness The used brightness + /// @param brightnessCompensation The used brightness compensation /// - void init(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, double brightnessHigh); + void init(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, uint8_t brightness, uint8_t brightnessCompensation); /// (re)-initilize the color mapping void initializeMapping(); /// The saturation gain - double _backlightThreshold; - bool _backlightColored; - double _brightnessHigh; - double _sumBrightnessLow; - double _sumBrightnessHigh; + void updateBrightnessComponents(); + /// backlight variables + bool _backLightEnabled; + bool _backlightColored; + double _backlightThreshold; + double _sumBrightnessLow; + + /// gamma variables double _gammaR; double _gammaG; double _gammaB; @@ -112,5 +132,10 @@ private: uint8_t _mappingG[256]; uint8_t _mappingB[256]; - bool _backLightEnabled; + /// brightness variables + uint8_t _brightness; + uint8_t _brightnessCompensation; + uint8_t _brightness_rgb; + uint8_t _brightness_cmy; + uint8_t _brightness_w; }; diff --git a/libsrc/hyperion/Hyperion.cpp b/libsrc/hyperion/Hyperion.cpp index fc9c2f6e..000ae736 100644 --- a/libsrc/hyperion/Hyperion.cpp +++ b/libsrc/hyperion/Hyperion.cpp @@ -162,12 +162,13 @@ RgbTransform* Hyperion::createRgbTransform(const QJsonObject& colorConfig) { 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 brightness = colorConfig["brightness"].toInt(100); + const double brightnessComp= colorConfig["brightnessCompensation"].toInt(100); 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, backlightThreshold, backlightColored, brightness); + RgbTransform* transform = new RgbTransform(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, brightness, brightnessComp); return transform; } diff --git a/libsrc/hyperion/MultiColorAdjustment.cpp b/libsrc/hyperion/MultiColorAdjustment.cpp index 6bab6382..302fb52b 100644 --- a/libsrc/hyperion/MultiColorAdjustment.cpp +++ b/libsrc/hyperion/MultiColorAdjustment.cpp @@ -106,8 +106,10 @@ void MultiColorAdjustment::applyAdjustment(std::vector& ledColors) uint8_t ored = color.red; uint8_t ogreen = color.green; uint8_t oblue = color.blue; + uint8_t B_RGB, B_CMY, B_W; adjustment->_rgbTransform.transform(ored,ogreen,oblue); + adjustment->_rgbTransform.getBrightnessComponents(B_RGB, B_CMY, B_W); uint32_t nrng = (uint32_t) (255-ored)*(255-ogreen); uint32_t rng = (uint32_t) (ored) *(255-ogreen); @@ -123,15 +125,17 @@ void MultiColorAdjustment::applyAdjustment(std::vector& ledColors) uint8_t yellow = rg *(255-oblue)/65025; uint8_t white = rg *(oblue) /65025; - uint8_t OR, OG, OB, RR, RG, RB, GR, GG, GB, BR, BG, BB, CR, CG, CB, MR, MG, MB, YR, YG, YB, WR, WG, WB; - adjustment->_rgbBlackAdjustment.apply(black, OR, OG, OB); - adjustment->_rgbRedAdjustment.apply(red, RR, RG, RB); - adjustment->_rgbGreenAdjustment.apply(green, GR, GG, GB); - adjustment->_rgbBlueAdjustment.apply(blue, BR, BG, BB); - adjustment->_rgbCyanAdjustment.apply(cyan, CR, CG, CB); - adjustment->_rgbMagentaAdjustment.apply(magenta, MR, MG, MB); - adjustment->_rgbYellowAdjustment.apply(yellow, YR, YG, YB); - adjustment->_rgbWhiteAdjustment.apply(white, WR, WG, WB); + uint8_t OR, OG, OB, RR, RG, RB, GR, GG, GB, BR, BG, BB; + uint8_t CR, CG, CB, MR, MG, MB, YR, YG, YB, WR, WG, WB; + + adjustment->_rgbBlackAdjustment.apply (black , 255 , OR, OG, OB); + adjustment->_rgbRedAdjustment.apply (red , B_RGB, RR, RG, RB); + adjustment->_rgbGreenAdjustment.apply (green , B_RGB, GR, GG, GB); + adjustment->_rgbBlueAdjustment.apply (blue , B_RGB, BR, BG, BB); + adjustment->_rgbCyanAdjustment.apply (cyan , B_CMY, CR, CG, CB); + adjustment->_rgbMagentaAdjustment.apply(magenta, B_CMY, MR, MG, MB); + adjustment->_rgbYellowAdjustment.apply (yellow , B_CMY, YR, YG, YB); + adjustment->_rgbWhiteAdjustment.apply (white , B_W , WR, WG, WB); color.red = OR + RR + GR + BR + CR + MR + YR + WR; color.green = OG + RG + GG + BG + CG + MG + YG + WG; diff --git a/libsrc/hyperion/PriorityMuxer.cpp b/libsrc/hyperion/PriorityMuxer.cpp index 611d0650..a71df018 100644 --- a/libsrc/hyperion/PriorityMuxer.cpp +++ b/libsrc/hyperion/PriorityMuxer.cpp @@ -12,7 +12,7 @@ PriorityMuxer::PriorityMuxer(int ledCount) , _lowestPriorityInfo() { _lowestPriorityInfo.priority = LOWEST_PRIORITY; - _lowestPriorityInfo.timeoutTime_ms = -1; + _lowestPriorityInfo.timeoutTime_ms = 0; _lowestPriorityInfo.ledColors = std::vector(ledCount, {0, 0, 0}); _lowestPriorityInfo.componentId = hyperion::COMP_COLOR; _lowestPriorityInfo.origin = "System"; @@ -91,7 +91,7 @@ void PriorityMuxer::setCurrentTime(const int64_t& now) for (auto infoIt = _activeInputs.begin(); infoIt != _activeInputs.end();) { - if (infoIt->timeoutTime_ms != -1 && infoIt->timeoutTime_ms <= now) + if (infoIt->timeoutTime_ms > 0 && infoIt->timeoutTime_ms <= now) { infoIt = _activeInputs.erase(infoIt); } diff --git a/libsrc/hyperion/schemas/hyperion.schema-2.json b/libsrc/hyperion/schemas/hyperion.schema-2.json index 3224c205..ba9f4ead 100644 --- a/libsrc/hyperion/schemas/hyperion.schema-2.json +++ b/libsrc/hyperion/schemas/hyperion.schema-2.json @@ -275,13 +275,13 @@ }, "backlightThreshold" : { - "type" : "number", + "type" : "integer", "title" : "edt_conf_color_backlightThreshold_title", "required" : true, - "minimum" : 0.0, - "maximum": 1.0, - "default" : 0.0, - "step" : 0.05, + "minimum" : 0, + "maximum": 100, + "default" : 0, + "append" : "edt_append_percent", "propertyOrder" : 11 }, "backlightColored" : @@ -294,15 +294,27 @@ }, "brightness" : { - "type" : "number", + "type" : "integer", "title" : "edt_conf_color_brightness_title", "required" : true, - "minimum" : 0.0, - "maximum": 1.0, - "default" : 1.0, - "step" : 0.05, + "minimum" : 0, + "maximum": 100, + "default" : 100, + "append" : "edt_append_percent", "propertyOrder" : 13 }, + "brightnessCompensation" : + { + "type" : "integer", + "title" : "edt_conf_color_brightnessComp_title", + "required" : true, + "minimum" : 0, + "maximum": 100, + "default" : 90, + "append" : "edt_append_percent", + "access" : "advanced", + "propertyOrder" : 14 + }, "gammaRed" : { "type" : "number", @@ -312,7 +324,7 @@ "maximum": 100.0, "default" : 1.5, "step" : 0.1, - "propertyOrder" : 14 + "propertyOrder" : 15 }, "gammaGreen" : { @@ -323,7 +335,7 @@ "maximum": 100.0, "default" : 1.5, "step" : 0.1, - "propertyOrder" : 15 + "propertyOrder" : 16 }, "gammaBlue" : { @@ -334,7 +346,7 @@ "maximum": 100.0, "default" : 1.5, "step" : 0.1, - "propertyOrder" : 16 + "propertyOrder" : 17 } }, "additionalProperties" : false diff --git a/libsrc/jsonserver/JsonClientConnection.cpp b/libsrc/jsonserver/JsonClientConnection.cpp index ba246547..8c60c0fb 100644 --- a/libsrc/jsonserver/JsonClientConnection.cpp +++ b/libsrc/jsonserver/JsonClientConnection.cpp @@ -757,10 +757,11 @@ void JsonClientConnection::handleServerInfoCommand(const QJsonObject&, const QSt yellowAdjust.append(colorAdjustment->_rgbYellowAdjustment.getAdjustmentG()); yellowAdjust.append(colorAdjustment->_rgbYellowAdjustment.getAdjustmentB()); adjustment.insert("yellow", yellowAdjust); - + adjustment["backlightThreshold"] = colorAdjustment->_rgbTransform.getBacklightThreshold(); adjustment["backlightColored"] = colorAdjustment->_rgbTransform.getBacklightColored(); adjustment["brightness"] = colorAdjustment->_rgbTransform.getBrightness(); + adjustment["brightnessCompensation"] = colorAdjustment->_rgbTransform.getBrightnessCompensation(); adjustment["gammaRed"] = colorAdjustment->_rgbTransform.getGammaR(); adjustment["gammaGreen"] = colorAdjustment->_rgbTransform.getGammaG(); adjustment["gammaBlue"] = colorAdjustment->_rgbTransform.getGammaB(); @@ -956,7 +957,11 @@ void JsonClientConnection::handleAdjustmentCommand(const QJsonObject& message, c } if (adjustment.contains("brightness")) { - colorAdjustment->_rgbTransform.setBrightness(adjustment["brightness"].toDouble()); + colorAdjustment->_rgbTransform.setBrightness(adjustment["brightness"].toInt()); + } + if (adjustment.contains("brightnessCompensation")) + { + colorAdjustment->_rgbTransform.setBrightnessCompensation(adjustment["brightnessCompensation"].toInt()); } // commit the changes diff --git a/libsrc/jsonserver/schema/schema-adjustment.json b/libsrc/jsonserver/schema/schema-adjustment.json index fd7fc163..a16796b1 100644 --- a/libsrc/jsonserver/schema/schema-adjustment.json +++ b/libsrc/jsonserver/schema/schema-adjustment.json @@ -125,20 +125,26 @@ "maximum" : 5.0 }, "backlightThreshold" : { - "type" : "number", + "type" : "integer", "required" : false, - "minimum" : 0.0, - "maximum" : 1.0 + "minimum" : 0, + "maximum" : 100 }, "backlightColored" : { "type" : "boolean", "required" : false }, "brightness" : { - "type" : "number", + "type" : "integer", "required" : false, - "minimum" : 0.0, - "maximum" : 1.0 + "minimum" : 0, + "maximum" : 100 + }, + "brightnessCompensation" : { + "type" : "integer", + "required" : false, + "minimum" : 0, + "maximum" : 100 } }, "additionalProperties": false diff --git a/libsrc/utils/RgbChannelAdjustment.cpp b/libsrc/utils/RgbChannelAdjustment.cpp index f5c76c2d..2a317a8b 100644 --- a/libsrc/utils/RgbChannelAdjustment.cpp +++ b/libsrc/utils/RgbChannelAdjustment.cpp @@ -9,8 +9,9 @@ RgbChannelAdjustment::RgbChannelAdjustment(QString channelName) : _channelName(channelName) , _log(Logger::getInstance(channelName)) + , _brightness(0) { - //setAdjustment(UINT8_MAX, UINT8_MAX, UINT8_MAX); + resetInitialized(); } RgbChannelAdjustment::RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB, QString channelName) @@ -24,12 +25,18 @@ RgbChannelAdjustment::~RgbChannelAdjustment() { } +void RgbChannelAdjustment::resetInitialized() +{ + Debug(_log, "initialize mapping with %d,%d,%d", _adjust[RED], _adjust[GREEN], _adjust[BLUE]); + memset(_initialized, false, sizeof(_initialized)); +} + void RgbChannelAdjustment::setAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB) { _adjust[RED] = adjustR; _adjust[GREEN] = adjustG; _adjust[BLUE] = adjustB; - initializeMapping(); + resetInitialized(); } uint8_t RgbChannelAdjustment::getAdjustmentR() const @@ -47,20 +54,22 @@ uint8_t RgbChannelAdjustment::getAdjustmentB() const return _adjust[BLUE]; } -void RgbChannelAdjustment::apply(uint8_t input, 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) { - red = _mapping[RED][input]; - green = _mapping[GREEN][input]; - blue = _mapping[BLUE][input]; -} + if (_brightness != brightness) + { + _brightness = brightness; + resetInitialized(); + } -void RgbChannelAdjustment::initializeMapping() -{ - Debug(_log, "initialize mapping with %d,%d,%d", _adjust[RED], _adjust[GREEN], _adjust[BLUE]); - // initialize linear mapping - for (unsigned channel=0; channel<3; channel++) - for (unsigned idx=0; idx<=UINT8_MAX; idx++) - { - _mapping[channel][idx] = std::min( ((idx * _adjust[channel]) / UINT8_MAX), (unsigned)UINT8_MAX); - } + if (!_initialized[input]) + { + _mapping[RED ][input] = std::min( ((_brightness * input * _adjust[RED ]) / 65025), UINT8_MAX); + _mapping[GREEN][input] = std::min( ((_brightness * input * _adjust[GREEN]) / 65025), UINT8_MAX); + _mapping[BLUE ][input] = std::min( ((_brightness * input * _adjust[BLUE ]) / 65025), UINT8_MAX); + _initialized[input] = true; + } + red = _mapping[RED ][input]; + green = _mapping[GREEN][input]; + blue = _mapping[BLUE ][input]; } diff --git a/libsrc/utils/RgbTransform.cpp b/libsrc/utils/RgbTransform.cpp index 256cabb5..d99cc687 100644 --- a/libsrc/utils/RgbTransform.cpp +++ b/libsrc/utils/RgbTransform.cpp @@ -5,21 +5,22 @@ RgbTransform::RgbTransform() { - init(1.0, 1.0, 1.0, 0.0, false, 1.0); + init(1.0, 1.0, 1.0, 0.0, false, 100, 100); } -RgbTransform::RgbTransform(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, double brightnessHigh) +RgbTransform::RgbTransform(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, uint8_t brightness, uint8_t brightnessCompensation) { - init(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, brightnessHigh); + init(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, brightness, brightnessCompensation); } -void RgbTransform::init(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, double brightnessHigh) +void RgbTransform::init(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, uint8_t brightness, uint8_t brightnessCompensation) { _backLightEnabled = true; setGamma(gammaR,gammaG,gammaB); setBacklightThreshold(backlightThreshold); setBacklightColored(backlightColored); - setBrightness(brightnessHigh); + setBrightness(brightness); + setBrightnessCompensation(brightnessCompensation); initializeMapping(); } @@ -61,15 +62,15 @@ void RgbTransform::initializeMapping() } -double RgbTransform::getBacklightThreshold() const +int RgbTransform::getBacklightThreshold() const { return _backlightThreshold; } -void RgbTransform::setBacklightThreshold(double backlightThreshold) +void RgbTransform::setBacklightThreshold(int backlightThreshold) { _backlightThreshold = backlightThreshold; - _sumBrightnessLow = 765.0 * ((std::pow(2.0,backlightThreshold*2)-1) / 3.0); + _sumBrightnessLow = 765.0 * ((std::pow(2.0,(_backlightThreshold/100)*2)-1) / 3.0); } bool RgbTransform::getBacklightColored() const @@ -92,15 +93,53 @@ void RgbTransform::setBackLightEnabled(bool enable) _backLightEnabled = enable; } -double RgbTransform::getBrightness() const +uint8_t RgbTransform::getBrightness() const { - return _brightnessHigh; + return _brightness; } -void RgbTransform::setBrightness(double brightness) +void RgbTransform::setBrightness(uint8_t brightness) { - _brightnessHigh = brightness; - _sumBrightnessHigh = 765.0 * ((std::pow(2.0,brightness*2)-1) / 3.0); + _brightness = brightness; + updateBrightnessComponents(); +} + +void RgbTransform::setBrightnessCompensation(uint8_t brightnessCompensation) +{ + _brightnessCompensation = brightnessCompensation; + updateBrightnessComponents(); +} + +uint8_t RgbTransform::getBrightnessCompensation() const +{ + return _brightnessCompensation; +} + +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; + + _brightness_rgb = std::ceil(std::min(255.0,255.0/B_in)); + _brightness_cmy = std::ceil(std::min(255.0,255.0/(B_in*Fcmy))); + _brightness_w = std::ceil(std::min(255.0,255.0/(B_in*Fw))); + } +} + +void RgbTransform::getBrightnessComponents(uint8_t & rgb, uint8_t & cmy, uint8_t & w ) +{ + rgb = _brightness_rgb; + cmy = _brightness_cmy; + w = _brightness_w; } void RgbTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue) @@ -114,14 +153,7 @@ void RgbTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue) // apply brightnesss int rgbSum = red+green+blue; - if (_sumBrightnessHigh > 0 && rgbSum > _sumBrightnessHigh) - { - double cH = _sumBrightnessHigh / rgbSum; - red *= cH; - green *= cH; - blue *= cH; - } - else if ( _backLightEnabled && _sumBrightnessLow>0 && rgbSum < _sumBrightnessLow) + if ( _backLightEnabled && _sumBrightnessLow>0 && rgbSum < _sumBrightnessLow) { if (_backlightColored) { @@ -147,3 +179,4 @@ void RgbTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue) } //std::cout << _sumBrightnessLow << " " << (int)red << " " << (int)green << " " << (int)blue << std::endl; } + diff --git a/libsrc/webconfig/QtHttpServer.cpp b/libsrc/webconfig/QtHttpServer.cpp index 8053f0e2..2830b8f7 100644 --- a/libsrc/webconfig/QtHttpServer.cpp +++ b/libsrc/webconfig/QtHttpServer.cpp @@ -4,18 +4,41 @@ #include "QtHttpReply.h" #include "QtHttpClientWrapper.h" -#include -#include -#include +#include +#include const QString & QtHttpServer::HTTP_VERSION = QStringLiteral ("HTTP/1.1"); +QtHttpServerWrapper::QtHttpServerWrapper (QObject * parent) + : QTcpServer (parent) + , m_useSsl (false) +{ } + +QtHttpServerWrapper::~QtHttpServerWrapper (void) { } + +void QtHttpServerWrapper::setUseSecure (const bool ssl) { + m_useSsl = ssl; +} + +void QtHttpServerWrapper::incomingConnection (qintptr handle) { + QTcpSocket * sock = (m_useSsl + ? new QSslSocket (this) + : new QTcpSocket (this)); + if (sock->setSocketDescriptor (handle)) { + addPendingConnection (sock); + } + else { + delete sock; + } +} + QtHttpServer::QtHttpServer (QObject * parent) : QObject (parent) + , m_useSsl (false) , m_serverName (QStringLiteral ("The Qt5 HTTP Server")) { - m_sockServer = new QTcpServer (this); - connect (m_sockServer, &QTcpServer::newConnection, this, &QtHttpServer::onClientConnected); + m_sockServer = new QtHttpServerWrapper (this); + connect (m_sockServer, &QtHttpServerWrapper::newConnection, this, &QtHttpServer::onClientConnected); } const QString & QtHttpServer::getServerName (void) const { @@ -50,21 +73,59 @@ void QtHttpServer::setServerName (const QString & serverName) { m_serverName = serverName; } +void QtHttpServer::setUseSecure (const bool ssl) { + m_useSsl = ssl; + m_sockServer->setUseSecure (m_useSsl); +} + +void QtHttpServer::setPrivateKey (const QSslKey & key) { + m_sslKey = key; +} + +void QtHttpServer::setCertificates (const QList & certs) { + m_sslCerts = certs; +} + void QtHttpServer::onClientConnected (void) { while (m_sockServer->hasPendingConnections ()) { - QTcpSocket * sockClient = m_sockServer->nextPendingConnection (); - QtHttpClientWrapper * wrapper = new QtHttpClientWrapper (sockClient, this); - connect (sockClient, &QTcpSocket::disconnected, this, &QtHttpServer::onClientDisconnected); - m_socksClientsHash.insert (sockClient, wrapper); - emit clientConnected (wrapper->getGuid ()); + if (QTcpSocket * sock = m_sockServer->nextPendingConnection ()) { + connect (sock, &QTcpSocket::disconnected, this, &QtHttpServer::onClientDisconnected); + if (m_useSsl) { + if (QSslSocket * ssl = qobject_cast (sock)) { + connect (ssl, SslErrorSignal (&QSslSocket::sslErrors), this, &QtHttpServer::onClientSslErrors); + connect (ssl, &QSslSocket::encrypted, this, &QtHttpServer::onClientSslEncrypted); + connect (ssl, &QSslSocket::peerVerifyError, this, &QtHttpServer::onClientSslPeerVerifyError); + connect (ssl, &QSslSocket::modeChanged, this, &QtHttpServer::onClientSslModeChanged); + ssl->setLocalCertificateChain (m_sslCerts); + ssl->setPrivateKey (m_sslKey); + ssl->setPeerVerifyMode (QSslSocket::AutoVerifyPeer); + ssl->startServerEncryption (); + } + } + QtHttpClientWrapper * wrapper = new QtHttpClientWrapper (sock, this); + m_socksClientsHash.insert (sock, wrapper); + emit clientConnected (wrapper->getGuid ()); + } } } +void QtHttpServer::onClientSslEncrypted (void) { } + +void QtHttpServer::onClientSslPeerVerifyError (const QSslError & err) { + Q_UNUSED (err) +} + +void QtHttpServer::onClientSslErrors (const QList & errors) { + Q_UNUSED (errors) +} + +void QtHttpServer::onClientSslModeChanged (QSslSocket::SslMode mode) { + Q_UNUSED (mode) +} + void QtHttpServer::onClientDisconnected (void) { - QTcpSocket * sockClient = qobject_cast (sender ()); - if (sockClient) { - QtHttpClientWrapper * wrapper = m_socksClientsHash.value (sockClient, Q_NULLPTR); - if (wrapper) { + if (QTcpSocket * sockClient = qobject_cast (sender ())) { + if (QtHttpClientWrapper * wrapper = m_socksClientsHash.value (sockClient, Q_NULLPTR)) { emit clientDisconnected (wrapper->getGuid ()); wrapper->deleteLater (); m_socksClientsHash.remove (sockClient); diff --git a/libsrc/webconfig/QtHttpServer.h b/libsrc/webconfig/QtHttpServer.h index 6ddf4b82..a14b191e 100644 --- a/libsrc/webconfig/QtHttpServer.h +++ b/libsrc/webconfig/QtHttpServer.h @@ -4,6 +4,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include class QTcpSocket; class QTcpServer; @@ -12,6 +18,22 @@ class QtHttpRequest; class QtHttpReply; class QtHttpClientWrapper; +class QtHttpServerWrapper : public QTcpServer { + Q_OBJECT + +public: + explicit QtHttpServerWrapper (QObject * parent = Q_NULLPTR); + virtual ~QtHttpServerWrapper (void); + + void setUseSecure (const bool ssl = true); + +protected: + void incomingConnection (qintptr handle) Q_DECL_OVERRIDE; + +private: + bool m_useSsl; +}; + class QtHttpServer : public QObject { Q_OBJECT @@ -19,14 +41,21 @@ public: explicit QtHttpServer (QObject * parent = Q_NULLPTR); static const QString & HTTP_VERSION; + + typedef void (QSslSocket::* SslErrorSignal) (const QList &); + const QString & getServerName (void) const; - quint16 getServerPort (void) const; + + quint16 getServerPort (void) const; QString getErrorString (void) const; public slots: - void start (quint16 port = 0); - void stop (void); - void setServerName (const QString & serverName); + void start (quint16 port = 0); + void stop (void); + void setServerName (const QString & serverName); + void setUseSecure (const bool ssl = true); + void setPrivateKey (const QSslKey & key); + void setCertificates (const QList & certs); signals: void started (quint16 port); @@ -37,13 +66,21 @@ signals: void requestNeedsReply (QtHttpRequest * request, QtHttpReply * reply); private slots: - void onClientConnected (void); - void onClientDisconnected (void); + void onClientConnected (void); + void onClientDisconnected (void); + void onClientSslEncrypted (void); + void onClientSslPeerVerifyError (const QSslError & err); + void onClientSslErrors (const QList & errors); + void onClientSslModeChanged (QSslSocket::SslMode mode); private: + bool m_useSsl; + QSslKey m_sslKey; + QList m_sslCerts; QString m_serverName; - QTcpServer * m_sockServer; + QtHttpServerWrapper * m_sockServer; QHash m_socksClientsHash; }; #endif // QTHTTPSERVER_H + diff --git a/src/hyperion-remote/JsonConnection.cpp b/src/hyperion-remote/JsonConnection.cpp index bfb42f7b..25d7ffcf 100644 --- a/src/hyperion-remote/JsonConnection.cpp +++ b/src/hyperion-remote/JsonConnection.cpp @@ -445,9 +445,10 @@ void JsonConnection::setAdjustment( double *gammaR, double *gammaG, double *gammaB, - double *backlightThreshold, + int *backlightThreshold, int *backlightColored, - double *brightness) + int *brightness, + int *brightnessC) { qDebug() << "Set color adjustments"; @@ -538,6 +539,10 @@ void JsonConnection::setAdjustment( { adjust["brightness"] = *brightness; } + if (brightnessC != nullptr) + { + adjust["brightnessCompensation"] = *brightnessC; + } if (gammaR != nullptr) { adjust["gammaRed"] = *gammaR; diff --git a/src/hyperion-remote/JsonConnection.h b/src/hyperion-remote/JsonConnection.h index 5e1df5b6..4a3d9f6a 100644 --- a/src/hyperion-remote/JsonConnection.h +++ b/src/hyperion-remote/JsonConnection.h @@ -154,9 +154,10 @@ public: double *gammaR, double *gammaG, double *gammaB, - double *backlightThreshold, + int *backlightThreshold, int *backlightColored, - double *brightness); + int *brightness, + int *brightnessC); /// /// sets the image to leds mapping type diff --git a/src/hyperion-remote/hyperion-remote.cpp b/src/hyperion-remote/hyperion-remote.cpp index 470d108a..aa6e1f92 100644 --- a/src/hyperion-remote/hyperion-remote.cpp +++ b/src/hyperion-remote/hyperion-remote.cpp @@ -75,9 +75,10 @@ int main(int argc, char * argv[]) BooleanOption & argClearAll = parser.add(0x0, "clearall" , "Clear data for all active priority channels"); Option & argEnableComponent = parser.add