mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Merge branch 'master' into add_effect_engine
Conflicts: include/hyperion/Hyperion.h libsrc/hyperion/Hyperion.cpp libsrc/jsonserver/JsonClientConnection.cpp Former-commit-id: 53467c63b97c7dc370f04357588f7cf1ad0e3ada
This commit is contained in:
@@ -30,6 +30,8 @@ SET(Hyperion_HEADERS
|
||||
${CURRENT_HEADER_DIR}/BlackBorderDetector.h
|
||||
${CURRENT_HEADER_DIR}/BlackBorderProcessor.h
|
||||
|
||||
${CURRENT_SOURCE_DIR}/MultiColorTransform.h
|
||||
|
||||
${CURRENT_SOURCE_DIR}/device/LedSpiDevice.h
|
||||
${CURRENT_SOURCE_DIR}/device/LedRs232Device.h
|
||||
${CURRENT_SOURCE_DIR}/device/LedDeviceTest.h
|
||||
@@ -51,6 +53,7 @@ SET(Hyperion_SOURCES
|
||||
${CURRENT_SOURCE_DIR}/BlackBorderDetector.cpp
|
||||
${CURRENT_SOURCE_DIR}/BlackBorderProcessor.cpp
|
||||
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
|
||||
${CURRENT_SOURCE_DIR}/MultiColorTransform.cpp
|
||||
${CURRENT_SOURCE_DIR}/LinearColorSmoothing.cpp
|
||||
|
||||
${CURRENT_SOURCE_DIR}/device/LedSpiDevice.cpp
|
||||
|
@@ -5,6 +5,9 @@
|
||||
// QT includes
|
||||
#include <QDateTime>
|
||||
#include <QThread>
|
||||
#include <QRegExp>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
// JsonSchema include
|
||||
#include <utils/jsonschema/JsonFactory.h>
|
||||
@@ -23,11 +26,9 @@
|
||||
#include "device/LedDeviceLightpack.h"
|
||||
#include "device/LedDeviceMultiLightpack.h"
|
||||
|
||||
#include "MultiColorTransform.h"
|
||||
#include "LinearColorSmoothing.h"
|
||||
|
||||
#include <utils/ColorTransform.h>
|
||||
#include <utils/HsvTransform.h>
|
||||
|
||||
// effect engine includes
|
||||
#include <effectengine/EffectEngine.h>
|
||||
|
||||
@@ -159,6 +160,98 @@ Hyperion::ColorOrder Hyperion::createColorOrder(const Json::Value &deviceConfig)
|
||||
return ORDER_RGB;
|
||||
}
|
||||
|
||||
ColorTransform * Hyperion::createColorTransform(const Json::Value & transformConfig)
|
||||
{
|
||||
const std::string id = transformConfig.get("id", "default").asString();
|
||||
|
||||
RgbChannelTransform * redTransform = createRgbChannelTransform(transformConfig["red"]);
|
||||
RgbChannelTransform * greenTransform = createRgbChannelTransform(transformConfig["green"]);
|
||||
RgbChannelTransform * blueTransform = createRgbChannelTransform(transformConfig["blue"]);
|
||||
|
||||
HsvTransform * hsvTransform = createHsvTransform(transformConfig["hsv"]);
|
||||
|
||||
ColorTransform * transform = new ColorTransform();
|
||||
transform->_id = id;
|
||||
transform->_rgbRedTransform = *redTransform;
|
||||
transform->_rgbGreenTransform = *greenTransform;
|
||||
transform->_rgbBlueTransform = *blueTransform;
|
||||
transform->_hsvTransform = *hsvTransform;
|
||||
|
||||
// Cleanup the allocated individual transforms
|
||||
delete redTransform;
|
||||
delete greenTransform;
|
||||
delete blueTransform;
|
||||
delete hsvTransform;
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorConfig)
|
||||
{
|
||||
// Create the result, the transforms are added to this
|
||||
MultiColorTransform * transform = new MultiColorTransform(ledCnt);
|
||||
|
||||
const Json::Value transformConfig = colorConfig.get("transform", Json::nullValue);
|
||||
if (transformConfig.isNull())
|
||||
{
|
||||
// Old style color transformation config (just one for all leds)
|
||||
ColorTransform * colorTransform = createColorTransform(colorConfig);
|
||||
transform->addTransform(colorTransform);
|
||||
transform->setTransformForLed(colorTransform->_id, 0, ledCnt-1);
|
||||
}
|
||||
else if (!transformConfig.isArray())
|
||||
{
|
||||
ColorTransform * colorTransform = createColorTransform(transformConfig);
|
||||
transform->addTransform(colorTransform);
|
||||
transform->setTransformForLed(colorTransform->_id, 0, ledCnt-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
|
||||
|
||||
for (Json::UInt i = 0; i < transformConfig.size(); ++i)
|
||||
{
|
||||
const Json::Value & config = transformConfig[i];
|
||||
ColorTransform * colorTransform = createColorTransform(config);
|
||||
transform->addTransform(colorTransform);
|
||||
|
||||
const QString ledIndicesStr = config.get("leds", "").asCString();
|
||||
if (!overallExp.exactMatch(ledIndicesStr))
|
||||
{
|
||||
std::cerr << "Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "ColorTransform '" << colorTransform->_id << "' => [";
|
||||
|
||||
const QStringList ledIndexList = ledIndicesStr.split(",");
|
||||
for (int i=0; i<ledIndexList.size(); ++i) {
|
||||
if (i > 0)
|
||||
{
|
||||
std::cout << ", ";
|
||||
}
|
||||
if (ledIndexList[i].contains("-"))
|
||||
{
|
||||
QStringList ledIndices = ledIndexList[i].split("-");
|
||||
int startInd = ledIndices[0].toInt();
|
||||
int endInd = ledIndices[1].toInt();
|
||||
|
||||
transform->setTransformForLed(colorTransform->_id, startInd, endInd);
|
||||
std::cout << startInd << "-" << endInd;
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = ledIndexList[i].toInt();
|
||||
transform->setTransformForLed(colorTransform->_id, index, index);
|
||||
std::cout << index;
|
||||
}
|
||||
}
|
||||
std::cout << "]" << std::endl;
|
||||
}
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
||||
HsvTransform * Hyperion::createHsvTransform(const Json::Value & hsvConfig)
|
||||
{
|
||||
const double saturationGain = hsvConfig.get("saturationGain", 1.0).asDouble();
|
||||
@@ -167,14 +260,14 @@ HsvTransform * Hyperion::createHsvTransform(const Json::Value & hsvConfig)
|
||||
return new HsvTransform(saturationGain, valueGain);
|
||||
}
|
||||
|
||||
ColorTransform* Hyperion::createColorTransform(const Json::Value& colorConfig)
|
||||
RgbChannelTransform* Hyperion::createRgbChannelTransform(const Json::Value& colorConfig)
|
||||
{
|
||||
const double threshold = colorConfig.get("threshold", 0.0).asDouble();
|
||||
const double gamma = colorConfig.get("gamma", 1.0).asDouble();
|
||||
const double blacklevel = colorConfig.get("blacklevel", 0.0).asDouble();
|
||||
const double whitelevel = colorConfig.get("whitelevel", 1.0).asDouble();
|
||||
|
||||
ColorTransform* transform = new ColorTransform(threshold, gamma, blacklevel, whitelevel);
|
||||
RgbChannelTransform* transform = new RgbChannelTransform(threshold, gamma, blacklevel, whitelevel);
|
||||
return transform;
|
||||
}
|
||||
|
||||
@@ -250,15 +343,16 @@ LedDevice * Hyperion::createColorSmoothing(const Json::Value & smoothingConfig,
|
||||
Hyperion::Hyperion(const Json::Value &jsonConfig) :
|
||||
_ledString(createLedString(jsonConfig["leds"])),
|
||||
_muxer(_ledString.leds().size()),
|
||||
_hsvTransform(createHsvTransform(jsonConfig["color"]["hsv"])),
|
||||
_redTransform(createColorTransform(jsonConfig["color"]["red"])),
|
||||
_greenTransform(createColorTransform(jsonConfig["color"]["green"])),
|
||||
_blueTransform(createColorTransform(jsonConfig["color"]["blue"])),
|
||||
_raw2ledTransform(createLedColorsTransform(_ledString.leds().size(), jsonConfig["color"])),
|
||||
_colorOrder(createColorOrder(jsonConfig["device"])),
|
||||
_device(createDevice(jsonConfig["device"])),
|
||||
_effectEngine(nullptr),
|
||||
_timer()
|
||||
{
|
||||
if (!_raw2ledTransform->verifyTransforms())
|
||||
{
|
||||
throw std::runtime_error("Color transformation incorrectly set");
|
||||
}
|
||||
// initialize the image processor factory
|
||||
ImageProcessorFactory::getInstance().init(_ledString, jsonConfig["blackborderdetector"].get("enable", true).asBool());
|
||||
|
||||
@@ -289,13 +383,8 @@ Hyperion::~Hyperion()
|
||||
// Delete the Led-String
|
||||
delete _device;
|
||||
|
||||
// delete he hsv transform
|
||||
delete _hsvTransform;
|
||||
|
||||
// Delete the color-transform
|
||||
delete _blueTransform;
|
||||
delete _greenTransform;
|
||||
delete _redTransform;
|
||||
// delete the color transform
|
||||
delete _raw2ledTransform;
|
||||
}
|
||||
|
||||
unsigned Hyperion::getLedCount() const
|
||||
@@ -330,55 +419,18 @@ void Hyperion::setColors(int priority, const std::vector<ColorRgb>& ledColors, c
|
||||
}
|
||||
}
|
||||
|
||||
void Hyperion::setTransform(Hyperion::Transform transform, Hyperion::Color color, double value)
|
||||
const std::vector<std::string> & Hyperion::getTransformIds() const
|
||||
{
|
||||
// select the transform of the requested color
|
||||
ColorTransform * t = nullptr;
|
||||
switch (color)
|
||||
{
|
||||
case RED:
|
||||
t = _redTransform;
|
||||
break;
|
||||
case GREEN:
|
||||
t = _greenTransform;
|
||||
break;
|
||||
case BLUE:
|
||||
t = _blueTransform;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return _raw2ledTransform->getTransformIds();
|
||||
}
|
||||
|
||||
// set transform value
|
||||
switch (transform)
|
||||
{
|
||||
case SATURATION_GAIN:
|
||||
_hsvTransform->setSaturationGain(value);
|
||||
break;
|
||||
case VALUE_GAIN:
|
||||
_hsvTransform->setValueGain(value);
|
||||
break;
|
||||
case THRESHOLD:
|
||||
assert (t != nullptr);
|
||||
t->setThreshold(value);
|
||||
break;
|
||||
case GAMMA:
|
||||
assert (t != nullptr);
|
||||
t->setGamma(value);
|
||||
break;
|
||||
case BLACKLEVEL:
|
||||
assert (t != nullptr);
|
||||
t->setBlacklevel(value);
|
||||
break;
|
||||
case WHITELEVEL:
|
||||
assert (t != nullptr);
|
||||
t->setWhitelevel(value);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
ColorTransform * Hyperion::getTransform(const std::string& id)
|
||||
{
|
||||
return _raw2ledTransform->getTransform(id);
|
||||
}
|
||||
|
||||
// update the led output
|
||||
void Hyperion::transformsUpdated()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -411,51 +463,6 @@ void Hyperion::clearall()
|
||||
_effectEngine->allChannelsCleared();
|
||||
}
|
||||
|
||||
double Hyperion::getTransform(Hyperion::Transform transform, Hyperion::Color color) const
|
||||
{
|
||||
// select the transform of the requested color
|
||||
ColorTransform * t = nullptr;
|
||||
switch (color)
|
||||
{
|
||||
case RED:
|
||||
t = _redTransform;
|
||||
break;
|
||||
case GREEN:
|
||||
t = _greenTransform;
|
||||
break;
|
||||
case BLUE:
|
||||
t = _blueTransform;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// set transform value
|
||||
switch (transform)
|
||||
{
|
||||
case SATURATION_GAIN:
|
||||
return _hsvTransform->getSaturationGain();
|
||||
case VALUE_GAIN:
|
||||
return _hsvTransform->getValueGain();
|
||||
case THRESHOLD:
|
||||
assert (t != nullptr);
|
||||
return t->getThreshold();
|
||||
case GAMMA:
|
||||
assert (t != nullptr);
|
||||
return t->getGamma();
|
||||
case BLACKLEVEL:
|
||||
assert (t != nullptr);
|
||||
return t->getBlacklevel();
|
||||
case WHITELEVEL:
|
||||
assert (t != nullptr);
|
||||
return t->getWhitelevel();
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return 999.0;
|
||||
}
|
||||
|
||||
QList<int> Hyperion::getActivePriorities() const
|
||||
{
|
||||
return _muxer.getPriorities();
|
||||
@@ -496,14 +503,9 @@ void Hyperion::update()
|
||||
const PriorityMuxer::InputInfo & priorityInfo = _muxer.getInputInfo(priority);
|
||||
|
||||
// Apply the transform to each led and color-channel
|
||||
std::vector<ColorRgb> ledColors(priorityInfo.ledColors);
|
||||
std::vector<ColorRgb> ledColors = _raw2ledTransform->applyTransform(priorityInfo.ledColors);
|
||||
for (ColorRgb& color : ledColors)
|
||||
{
|
||||
_hsvTransform->transform(color.red, color.green, color.blue);
|
||||
color.red = _redTransform->transform(color.red);
|
||||
color.green = _greenTransform->transform(color.green);
|
||||
color.blue = _blueTransform->transform(color.blue);
|
||||
|
||||
// correct the color byte order
|
||||
switch (_colorOrder)
|
||||
{
|
||||
|
@@ -4,8 +4,6 @@
|
||||
#include <hyperion/ImageToLedsMap.h>
|
||||
#include <hyperion/BlackBorderProcessor.h>
|
||||
|
||||
#include <utils/ColorTransform.h>
|
||||
|
||||
using namespace hyperion;
|
||||
|
||||
ImageProcessor::ImageProcessor(const LedString& ledString, bool enableBlackBorderDetector) :
|
||||
|
97
libsrc/hyperion/MultiColorTransform.cpp
Normal file
97
libsrc/hyperion/MultiColorTransform.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
// STL includes
|
||||
#include <cassert>
|
||||
|
||||
// Hyperion includes
|
||||
#include "MultiColorTransform.h"
|
||||
|
||||
MultiColorTransform::MultiColorTransform(const unsigned ledCnt) :
|
||||
_ledTransforms(ledCnt, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
MultiColorTransform::~MultiColorTransform()
|
||||
{
|
||||
// Clean up all the transforms
|
||||
for (ColorTransform * transform : _transform)
|
||||
{
|
||||
delete transform;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiColorTransform::addTransform(ColorTransform * transform)
|
||||
{
|
||||
_transformIds.push_back(transform->_id);
|
||||
_transform.push_back(transform);
|
||||
}
|
||||
|
||||
void MultiColorTransform::setTransformForLed(const std::string& id, const unsigned startLed, const unsigned endLed)
|
||||
{
|
||||
assert(startLed <= endLed);
|
||||
assert(endLed < _ledTransforms.size());
|
||||
|
||||
// Get the identified transform (don't care if is nullptr)
|
||||
ColorTransform * transform = getTransform(id);
|
||||
for (unsigned iLed=startLed; iLed<=endLed; ++iLed)
|
||||
{
|
||||
_ledTransforms[iLed] = transform;
|
||||
}
|
||||
}
|
||||
|
||||
bool MultiColorTransform::verifyTransforms() const
|
||||
{
|
||||
bool allLedsSet = true;
|
||||
for (unsigned iLed=0; iLed<_ledTransforms.size(); ++iLed)
|
||||
{
|
||||
if (_ledTransforms[iLed] == nullptr)
|
||||
{
|
||||
std::cerr << "No transform set for " << iLed << std::endl;
|
||||
allLedsSet = false;
|
||||
}
|
||||
}
|
||||
return allLedsSet;
|
||||
}
|
||||
|
||||
const std::vector<std::string> & MultiColorTransform::getTransformIds()
|
||||
{
|
||||
return _transformIds;
|
||||
}
|
||||
|
||||
ColorTransform* MultiColorTransform::getTransform(const std::string& id)
|
||||
{
|
||||
// Iterate through the unique transforms until we find the one with the given id
|
||||
for (ColorTransform* transform : _transform)
|
||||
{
|
||||
if (transform->_id == id)
|
||||
{
|
||||
return transform;
|
||||
}
|
||||
}
|
||||
|
||||
// The ColorTransform was not found
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<ColorRgb> MultiColorTransform::applyTransform(const std::vector<ColorRgb>& rawColors)
|
||||
{
|
||||
// Create a copy, as we will do the rest of the transformation in place
|
||||
std::vector<ColorRgb> ledColors(rawColors);
|
||||
|
||||
const size_t itCnt = std::min(_ledTransforms.size(), rawColors.size());
|
||||
for (size_t i=0; i<itCnt; ++i)
|
||||
{
|
||||
ColorTransform* transform = _ledTransforms[i];
|
||||
if (transform == nullptr)
|
||||
{
|
||||
// No transform set for this led (do nothing)
|
||||
continue;
|
||||
}
|
||||
ColorRgb& color = ledColors[i];
|
||||
|
||||
transform->_hsvTransform.transform(color.red, color.green, color.blue);
|
||||
color.red = transform->_rgbRedTransform.transform(color.red);
|
||||
color.green = transform->_rgbGreenTransform.transform(color.green);
|
||||
color.blue = transform->_rgbBlueTransform.transform(color.blue);
|
||||
}
|
||||
return ledColors;
|
||||
}
|
66
libsrc/hyperion/MultiColorTransform.h
Normal file
66
libsrc/hyperion/MultiColorTransform.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
// STL includes
|
||||
#include <vector>
|
||||
|
||||
// Utils includes
|
||||
#include <utils/ColorRgb.h>
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/ColorTransform.h>
|
||||
|
||||
///
|
||||
/// The LedColorTransform is responsible for performing color transformation from 'raw' colors
|
||||
/// received as input to colors mapped to match the color-properties of the leds.
|
||||
///
|
||||
class MultiColorTransform
|
||||
{
|
||||
public:
|
||||
MultiColorTransform(const unsigned ledCnt);
|
||||
~MultiColorTransform();
|
||||
|
||||
/**
|
||||
* Adds a new ColorTransform to this MultiColorTransform
|
||||
*
|
||||
* @param transform The new ColorTransform (ownership is transfered)
|
||||
*/
|
||||
void addTransform(ColorTransform * transform);
|
||||
|
||||
void setTransformForLed(const std::string& id, const unsigned startLed, const unsigned endLed);
|
||||
|
||||
bool verifyTransforms() const;
|
||||
|
||||
///
|
||||
/// Returns the identifier of all the unique ColorTransform
|
||||
///
|
||||
/// @return The list with unique id's of the ColorTransforms
|
||||
const std::vector<std::string> & getTransformIds();
|
||||
|
||||
///
|
||||
/// Returns the pointer to the ColorTransform with the given id
|
||||
///
|
||||
/// @param id The identifier of the ColorTransform
|
||||
///
|
||||
/// @return The ColorTransform with the given id (or nullptr if it does not exist)
|
||||
///
|
||||
ColorTransform* getTransform(const std::string& id);
|
||||
|
||||
///
|
||||
/// Performs the color transoformation from raw-color to led-color
|
||||
///
|
||||
/// @param rawColors The list with raw colors
|
||||
///
|
||||
/// @return The list with led-colors
|
||||
///
|
||||
std::vector<ColorRgb> applyTransform(const std::vector<ColorRgb>& rawColors);
|
||||
|
||||
private:
|
||||
/// List with transform ids
|
||||
std::vector<std::string> _transformIds;
|
||||
|
||||
/// List with unique ColorTransforms
|
||||
std::vector<ColorTransform*> _transform;
|
||||
|
||||
/// List with a pointer to the ColorTransform for each individual led
|
||||
std::vector<ColorTransform*> _ledTransforms;
|
||||
};
|
@@ -12,9 +12,10 @@
|
||||
#include <QDateTime>
|
||||
|
||||
// hyperion util includes
|
||||
#include "hyperion/ImageProcessorFactory.h"
|
||||
#include "hyperion/ImageProcessor.h"
|
||||
#include "utils/ColorRgb.h"
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
#include <hyperion/ColorTransform.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
|
||||
// project includes
|
||||
#include "JsonClientConnection.h"
|
||||
@@ -197,25 +198,39 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &)
|
||||
}
|
||||
|
||||
// collect transform information
|
||||
Json::Value & transform = info["transform"] = Json::Value(Json::objectValue);
|
||||
transform["saturationGain"] = _hyperion->getTransform(Hyperion::SATURATION_GAIN, Hyperion::INVALID);
|
||||
transform["valueGain"] = _hyperion->getTransform(Hyperion::VALUE_GAIN, Hyperion::INVALID);
|
||||
Json::Value & threshold = transform["threshold"];
|
||||
threshold.append(_hyperion->getTransform(Hyperion::THRESHOLD, Hyperion::RED));
|
||||
threshold.append(_hyperion->getTransform(Hyperion::THRESHOLD, Hyperion::GREEN));
|
||||
threshold.append(_hyperion->getTransform(Hyperion::THRESHOLD, Hyperion::BLUE));
|
||||
Json::Value & gamma = transform["gamma"];
|
||||
gamma.append(_hyperion->getTransform(Hyperion::GAMMA, Hyperion::RED));
|
||||
gamma.append(_hyperion->getTransform(Hyperion::GAMMA, Hyperion::GREEN));
|
||||
gamma.append(_hyperion->getTransform(Hyperion::GAMMA, Hyperion::BLUE));
|
||||
Json::Value & blacklevel = transform["blacklevel"];
|
||||
blacklevel.append(_hyperion->getTransform(Hyperion::BLACKLEVEL, Hyperion::RED));
|
||||
blacklevel.append(_hyperion->getTransform(Hyperion::BLACKLEVEL, Hyperion::GREEN));
|
||||
blacklevel.append(_hyperion->getTransform(Hyperion::BLACKLEVEL, Hyperion::BLUE));
|
||||
Json::Value & whitelevel = transform["whitelevel"];
|
||||
whitelevel.append(_hyperion->getTransform(Hyperion::WHITELEVEL, Hyperion::RED));
|
||||
whitelevel.append(_hyperion->getTransform(Hyperion::WHITELEVEL, Hyperion::GREEN));
|
||||
whitelevel.append(_hyperion->getTransform(Hyperion::WHITELEVEL, Hyperion::BLUE));
|
||||
Json::Value & transformArray = info["transform"];
|
||||
for (const std::string& transformId : _hyperion->getTransformIds())
|
||||
{
|
||||
const ColorTransform * colorTransform = _hyperion->getTransform(transformId);
|
||||
if (colorTransform == nullptr)
|
||||
{
|
||||
std::cerr << "Incorrect color transform id: " << transformId << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
Json::Value & transform = transformArray.append(Json::Value());
|
||||
transform["id"] = transformId;
|
||||
|
||||
transform["saturationGain"] = colorTransform->_hsvTransform.getSaturationGain();
|
||||
transform["valueGain"] = colorTransform->_hsvTransform.getValueGain();
|
||||
|
||||
Json::Value & threshold = transform["threshold"];
|
||||
threshold.append(colorTransform->_rgbRedTransform.getThreshold());
|
||||
threshold.append(colorTransform->_rgbGreenTransform.getThreshold());
|
||||
threshold.append(colorTransform->_rgbBlueTransform.getThreshold());
|
||||
Json::Value & gamma = transform["gamma"];
|
||||
gamma.append(colorTransform->_rgbRedTransform.getGamma());
|
||||
gamma.append(colorTransform->_rgbGreenTransform.getGamma());
|
||||
gamma.append(colorTransform->_rgbBlueTransform.getGamma());
|
||||
Json::Value & blacklevel = transform["blacklevel"];
|
||||
blacklevel.append(colorTransform->_rgbRedTransform.getBlacklevel());
|
||||
blacklevel.append(colorTransform->_rgbGreenTransform.getBlacklevel());
|
||||
blacklevel.append(colorTransform->_rgbBlueTransform.getBlacklevel());
|
||||
Json::Value & whitelevel = transform["whitelevel"];
|
||||
whitelevel.append(colorTransform->_rgbRedTransform.getWhitelevel());
|
||||
whitelevel.append(colorTransform->_rgbGreenTransform.getWhitelevel());
|
||||
whitelevel.append(colorTransform->_rgbBlueTransform.getWhitelevel());
|
||||
}
|
||||
|
||||
// collect effect info
|
||||
Json::Value & effects = info["effects"] = Json::Value(Json::arrayValue);
|
||||
@@ -259,48 +274,59 @@ void JsonClientConnection::handleTransformCommand(const Json::Value &message)
|
||||
{
|
||||
const Json::Value & transform = message["transform"];
|
||||
|
||||
const std::string transformId = transform.get("id", _hyperion->getTransformIds().front()).asString();
|
||||
ColorTransform * colorTransform = _hyperion->getTransform(transformId);
|
||||
if (colorTransform == nullptr)
|
||||
{
|
||||
//sendErrorReply(std::string("Incorrect transform identifier: ") + transformId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (transform.isMember("saturationGain"))
|
||||
{
|
||||
_hyperion->setTransform(Hyperion::SATURATION_GAIN, Hyperion::INVALID, transform["saturationGain"].asDouble());
|
||||
colorTransform->_hsvTransform.setSaturationGain(transform["saturationGain"].asDouble());
|
||||
}
|
||||
|
||||
if (transform.isMember("valueGain"))
|
||||
{
|
||||
_hyperion->setTransform(Hyperion::VALUE_GAIN, Hyperion::INVALID, transform["valueGain"].asDouble());
|
||||
colorTransform->_hsvTransform.setValueGain(transform["valueGain"].asDouble());
|
||||
}
|
||||
|
||||
if (transform.isMember("threshold"))
|
||||
{
|
||||
const Json::Value & threshold = transform["threshold"];
|
||||
_hyperion->setTransform(Hyperion::THRESHOLD, Hyperion::RED, threshold[0u].asDouble());
|
||||
_hyperion->setTransform(Hyperion::THRESHOLD, Hyperion::GREEN, threshold[1u].asDouble());
|
||||
_hyperion->setTransform(Hyperion::THRESHOLD, Hyperion::BLUE, threshold[2u].asDouble());
|
||||
const Json::Value & values = transform["threshold"];
|
||||
colorTransform->_rgbRedTransform .setThreshold(values[0u].asDouble());
|
||||
colorTransform->_rgbGreenTransform.setThreshold(values[1u].asDouble());
|
||||
colorTransform->_rgbBlueTransform .setThreshold(values[2u].asDouble());
|
||||
}
|
||||
|
||||
if (transform.isMember("gamma"))
|
||||
{
|
||||
const Json::Value & threshold = transform["gamma"];
|
||||
_hyperion->setTransform(Hyperion::GAMMA, Hyperion::RED, threshold[0u].asDouble());
|
||||
_hyperion->setTransform(Hyperion::GAMMA, Hyperion::GREEN, threshold[1u].asDouble());
|
||||
_hyperion->setTransform(Hyperion::GAMMA, Hyperion::BLUE, threshold[2u].asDouble());
|
||||
const Json::Value & values = transform["gamma"];
|
||||
colorTransform->_rgbRedTransform .setGamma(values[0u].asDouble());
|
||||
colorTransform->_rgbGreenTransform.setGamma(values[1u].asDouble());
|
||||
colorTransform->_rgbBlueTransform .setGamma(values[2u].asDouble());
|
||||
}
|
||||
|
||||
if (transform.isMember("blacklevel"))
|
||||
{
|
||||
const Json::Value & threshold = transform["blacklevel"];
|
||||
_hyperion->setTransform(Hyperion::BLACKLEVEL, Hyperion::RED, threshold[0u].asDouble());
|
||||
_hyperion->setTransform(Hyperion::BLACKLEVEL, Hyperion::GREEN, threshold[1u].asDouble());
|
||||
_hyperion->setTransform(Hyperion::BLACKLEVEL, Hyperion::BLUE, threshold[2u].asDouble());
|
||||
const Json::Value & values = transform["blacklevel"];
|
||||
colorTransform->_rgbRedTransform .setBlacklevel(values[0u].asDouble());
|
||||
colorTransform->_rgbGreenTransform.setBlacklevel(values[1u].asDouble());
|
||||
colorTransform->_rgbBlueTransform .setBlacklevel(values[2u].asDouble());
|
||||
}
|
||||
|
||||
if (transform.isMember("whitelevel"))
|
||||
{
|
||||
const Json::Value & threshold = transform["whitelevel"];
|
||||
_hyperion->setTransform(Hyperion::WHITELEVEL, Hyperion::RED, threshold[0u].asDouble());
|
||||
_hyperion->setTransform(Hyperion::WHITELEVEL, Hyperion::GREEN, threshold[1u].asDouble());
|
||||
_hyperion->setTransform(Hyperion::WHITELEVEL, Hyperion::BLUE, threshold[2u].asDouble());
|
||||
const Json::Value & values = transform["whitelevel"];
|
||||
colorTransform->_rgbRedTransform .setWhitelevel(values[0u].asDouble());
|
||||
colorTransform->_rgbGreenTransform.setWhitelevel(values[1u].asDouble());
|
||||
colorTransform->_rgbBlueTransform .setWhitelevel(values[2u].asDouble());
|
||||
}
|
||||
|
||||
// commit the changes
|
||||
_hyperion->transformsUpdated();
|
||||
|
||||
sendSuccessReply();
|
||||
}
|
||||
|
||||
|
@@ -1,68 +1,72 @@
|
||||
{
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["transform"]
|
||||
},
|
||||
"transform": {
|
||||
"type": "object",
|
||||
"required": true,
|
||||
"properties": {
|
||||
"saturationGain" : {
|
||||
"type" : "double",
|
||||
"required" : false,
|
||||
"minimum" : 0.0
|
||||
},
|
||||
"valueGain" : {
|
||||
"type" : "double",
|
||||
"required" : false,
|
||||
"minimum" : 0.0
|
||||
},
|
||||
"threshold": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "double",
|
||||
"minimum": 0.0,
|
||||
"maximum": 1.0
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
"gamma": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "double",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
"blacklevel": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "double"
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
"whitelevel": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "double"
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["transform"]
|
||||
},
|
||||
"transform": {
|
||||
"type": "object",
|
||||
"required": true,
|
||||
"properties": {
|
||||
"id" : {
|
||||
"type" : "string",
|
||||
"required" : false
|
||||
},
|
||||
"saturationGain" : {
|
||||
"type" : "double",
|
||||
"required" : false,
|
||||
"minimum" : 0.0
|
||||
},
|
||||
"valueGain" : {
|
||||
"type" : "double",
|
||||
"required" : false,
|
||||
"minimum" : 0.0
|
||||
},
|
||||
"threshold": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "double",
|
||||
"minimum": 0.0,
|
||||
"maximum": 1.0
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
"gamma": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "double",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
"blacklevel": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "double"
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
"whitelevel": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "double"
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
@@ -11,11 +11,11 @@ add_library(hyperion-utils
|
||||
${CURRENT_HEADER_DIR}/ColorRgba.h
|
||||
${CURRENT_SOURCE_DIR}/ColorRgba.cpp
|
||||
${CURRENT_HEADER_DIR}/Image.h
|
||||
${CURRENT_HEADER_DIR}/ColorTransform.h
|
||||
${CURRENT_HEADER_DIR}/HsvTransform.h
|
||||
|
||||
${CURRENT_SOURCE_DIR}/ColorTransform.cpp
|
||||
${CURRENT_HEADER_DIR}/HsvTransform.h
|
||||
${CURRENT_SOURCE_DIR}/HsvTransform.cpp
|
||||
${CURRENT_HEADER_DIR}/RgbChannelTransform.h
|
||||
${CURRENT_SOURCE_DIR}/RgbChannelTransform.cpp
|
||||
|
||||
${CURRENT_HEADER_DIR}/jsonschema/JsonFactory.h
|
||||
${CURRENT_HEADER_DIR}/jsonschema/JsonSchemaChecker.h
|
||||
|
@@ -1,9 +1,10 @@
|
||||
// STL includes
|
||||
#include <cmath>
|
||||
|
||||
#include <utils/ColorTransform.h>
|
||||
// Utils includes
|
||||
#include <utils/RgbChannelTransform.h>
|
||||
|
||||
ColorTransform::ColorTransform() :
|
||||
RgbChannelTransform::RgbChannelTransform() :
|
||||
_threshold(0),
|
||||
_gamma(1.0),
|
||||
_blacklevel(0.0),
|
||||
@@ -12,7 +13,7 @@ ColorTransform::ColorTransform() :
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
ColorTransform::ColorTransform(double threshold, double gamma, double blacklevel, double whitelevel) :
|
||||
RgbChannelTransform::RgbChannelTransform(double threshold, double gamma, double blacklevel, double whitelevel) :
|
||||
_threshold(threshold),
|
||||
_gamma(gamma),
|
||||
_blacklevel(blacklevel),
|
||||
@@ -21,55 +22,55 @@ ColorTransform::ColorTransform(double threshold, double gamma, double blacklevel
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
ColorTransform::~ColorTransform()
|
||||
RgbChannelTransform::~RgbChannelTransform()
|
||||
{
|
||||
}
|
||||
|
||||
double ColorTransform::getThreshold() const
|
||||
double RgbChannelTransform::getThreshold() const
|
||||
{
|
||||
return _threshold;
|
||||
}
|
||||
|
||||
void ColorTransform::setThreshold(double threshold)
|
||||
void RgbChannelTransform::setThreshold(double threshold)
|
||||
{
|
||||
_threshold = threshold;
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
double ColorTransform::getGamma() const
|
||||
double RgbChannelTransform::getGamma() const
|
||||
{
|
||||
return _gamma;
|
||||
}
|
||||
|
||||
void ColorTransform::setGamma(double gamma)
|
||||
void RgbChannelTransform::setGamma(double gamma)
|
||||
{
|
||||
_gamma = gamma;
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
double ColorTransform::getBlacklevel() const
|
||||
double RgbChannelTransform::getBlacklevel() const
|
||||
{
|
||||
return _blacklevel;
|
||||
}
|
||||
|
||||
void ColorTransform::setBlacklevel(double blacklevel)
|
||||
void RgbChannelTransform::setBlacklevel(double blacklevel)
|
||||
{
|
||||
_blacklevel = blacklevel;
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
double ColorTransform::getWhitelevel() const
|
||||
double RgbChannelTransform::getWhitelevel() const
|
||||
{
|
||||
return _whitelevel;
|
||||
}
|
||||
|
||||
void ColorTransform::setWhitelevel(double whitelevel)
|
||||
void RgbChannelTransform::setWhitelevel(double whitelevel)
|
||||
{
|
||||
_whitelevel = whitelevel;
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
void ColorTransform::initializeMapping()
|
||||
void RgbChannelTransform::initializeMapping()
|
||||
{
|
||||
// initialize the mapping as a linear array
|
||||
for (int i = 0; i < 256; ++i)
|
@@ -154,6 +154,8 @@ void JsonSchemaChecker::checkType(const Json::Value & value, const Json::Value &
|
||||
wrongType = !value.isNumeric();
|
||||
else if (type == "integer")
|
||||
wrongType = !value.isIntegral();
|
||||
else if (type == "double")
|
||||
wrongType = !value.isDouble();
|
||||
else if (type == "boolean")
|
||||
wrongType = !value.isBool();
|
||||
else if (type == "object")
|
||||
@@ -162,6 +164,8 @@ void JsonSchemaChecker::checkType(const Json::Value & value, const Json::Value &
|
||||
wrongType = !value.isArray();
|
||||
else if (type == "null")
|
||||
wrongType = !value.isNull();
|
||||
else if (type == "enum")
|
||||
wrongType = !value.isString();
|
||||
else if (type == "any")
|
||||
wrongType = false;
|
||||
// else
|
||||
|
Reference in New Issue
Block a user