diff --git a/Software/grab/GrabberBase.cpp b/Software/grab/GrabberBase.cpp index 56a0b5712..a559bf816 100644 --- a/Software/grab/GrabberBase.cpp +++ b/Software/grab/GrabberBase.cpp @@ -69,6 +69,11 @@ void GrabberBase::setGrabInterval(int msec) m_timer->setInterval(msec); } +void GrabberBase::setGammaDecodeValue(double value) +{ + for (int i = 0; i < 256; i++) gammaDecodeArray[i] = 65535 * pow((double)i / 255.0, value); +} + void GrabberBase::startGrabbing() { DEBUG_LOW_LEVEL << Q_FUNC_INFO << this->metaObject()->className(); @@ -142,7 +147,7 @@ void GrabberBase::grab() for (int i = 0; i < _context->grabWidgets->size(); ++i) { if (!_context->grabWidgets->at(i)->isAreaEnabled()) { - _context->grabResult->append(qRgb(0,0,0)); + _context->grabResult->append(qRgba64(0)); continue; } QRect widgetRect = _context->grabWidgets->at(i)->frameGeometry(); @@ -151,7 +156,7 @@ void GrabberBase::grab() const GrabbedScreen *grabbedScreen = screenOfRect(widgetRect); if (grabbedScreen == NULL) { DEBUG_HIGH_LEVEL << Q_FUNC_INFO << " widget is out of screen " << Debug::toString(widgetRect); - _context->grabResult->append(0); + _context->grabResult->append(qRgba64(0)); continue; } DEBUG_HIGH_LEVEL << Q_FUNC_INFO << Debug::toString(widgetRect); @@ -164,7 +169,7 @@ void GrabberBase::grab() DEBUG_HIGH_LEVEL << "Widget 'grabme' is out of screen:" << Debug::toString(clippedRect); - _context->grabResult->append(qRgb(0,0,0)); + _context->grabResult->append(qRgba64(0)); continue; } @@ -210,16 +215,16 @@ void GrabberBase::grab() qWarning() << Q_FUNC_INFO << " preparedRect is not valid:" << Debug::toString(preparedRect); // width and height can't be negative - _context->grabResult->append(qRgb(0,0,0)); + _context->grabResult->append(qRgba64(0)); continue; } const int bytesPerPixel = 4; Q_ASSERT(grabbedScreen->imgData); - QRgb avgColor = Grab::Calculations::calculateAvgColor( + QRgba64 avgColor = Grab::Calculations::calculateAvgColor( grabbedScreen->imgData, grabbedScreen->imgFormat, grabbedScreen->bytesPerRow > 0 ? grabbedScreen->bytesPerRow : grabbedScreen->screenInfo.rect.width() * bytesPerPixel, - preparedRect); + preparedRect, gammaDecodeArray); _context->grabResult->append(avgColor); } diff --git a/Software/grab/WinUtils.cpp b/Software/grab/WinUtils.cpp index abdf21ed9..c52f3d8b8 100644 --- a/Software/grab/WinUtils.cpp +++ b/Software/grab/WinUtils.cpp @@ -393,6 +393,12 @@ VOID FreeRestrictedSD(PVOID ptr) { { PrismatikMath::applyColorTemperature(colors, _client->getSmoothenedColorTemperature(), gamma); } + + + void NightLight::apply(QList& colors, const double gamma) + { + PrismatikMath::applyColorTemperature(colors, _client->getSmoothenedColorTemperature(), gamma); + } #endif // NIGHTLIGHT_SUPPORT bool GammaRamp::isSupported() @@ -425,6 +431,22 @@ VOID FreeRestrictedSD(PVOID ptr) { return true; } + void GammaRamp::interpolateGamma() + { + // interpolate 8 bit input to 16 bit input + for (int channel = 0; channel < 3; channel++) { + int pos = 0; + for (int value = 0; value < 255; value++) { + int delta = _gammaArray[channel][value + 1] - _gammaArray[channel][value]; + for (int i = 0; i < 257; i++) { + _gammaArray16[channel][pos] = _gammaArray[channel][value] + (delta * i) / 257; + pos++; + } + } + _gammaArray16[channel][pos] = _gammaArray[channel][255]; + } + } + void GammaRamp::apply(QList& colors, const double/*gamma*/) { HDC dc = NULL; @@ -453,4 +475,33 @@ VOID FreeRestrictedSD(PVOID ptr) { DeleteObject(dc); } + void GammaRamp::apply(QList& colors, const double/*gamma*/) + { + HDC dc = NULL; + + // Reload the gamma ramp every 15 seconds only. + // There seems to be a memory leak somewhere in the API and we don't + // expect the ramp to change every frame. + if (time(nullptr) - _gammaAge > 15) { + if (!loadGamma(&_gammaArray, &dc)) + return; + _gammaAge = time(nullptr); + interpolateGamma(); + } + + for (QRgba64& color : colors) { + int red = color.red(); + int green = color.green(); + int blue = color.blue(); + + red = _gammaArray16[0][red]; + green = _gammaArray16[1][green]; + blue = _gammaArray16[2][blue]; + + color = qRgba64(red, green, blue, 0); + } + + DeleteObject(dc); + } + } // namespace WinUtils diff --git a/Software/grab/calculations.cpp b/Software/grab/calculations.cpp index f4df9e061..9d89fa7f9 100644 --- a/Software/grab/calculations.cpp +++ b/Software/grab/calculations.cpp @@ -234,6 +234,44 @@ namespace { return color; }; + template + static ColorValue accumulateBufferGamma( + const int* const buff, + const size_t pitch, + const QRect& rect, + const quint16* gamma) { + const unsigned char* const buffer = (const unsigned char* const)buff; + + int r = 0; + int g = 0; + int b = 0; + + const int delta = rect.width() % pixelsPerStep; + if (rect.width() >= pixelsPerStep) + for (int currentY = 0; currentY < rect.height(); currentY++) { + for (int currentX = 0; currentX < rect.width() - delta; currentX += pixelsPerStep) { + const size_t index = pitch * bytesPerPixel * (rect.y() + currentY) + (rect.x() + currentX) * bytesPerPixel; + r += gamma[PIXEL_R(0)] + gamma[PIXEL_R(1)] + gamma[PIXEL_R(2)] + gamma[PIXEL_R(3)]; + g += gamma[PIXEL_G(0)] + gamma[PIXEL_G(1)] + gamma[PIXEL_G(2)] + gamma[PIXEL_G(3)]; + b += gamma[PIXEL_B(0)] + gamma[PIXEL_B(1)] + gamma[PIXEL_B(2)] + gamma[PIXEL_B(3)]; + } + } + for (int currentX = rect.width() - delta; currentX < rect.width(); ++currentX) { + for (int currentY = 0; currentY < rect.height(); ++currentY) { + const size_t index = pitch * bytesPerPixel * (rect.y() + currentY) + (rect.x() + currentX) * bytesPerPixel; + r += gamma[PIXEL_R(0)]; + g += gamma[PIXEL_G(0)]; + b += gamma[PIXEL_B(0)]; + } + } + + const size_t count = rect.height() * rect.width(); + ColorValue color; + color.r = (r / count) & 0xffff; + color.g = (g / count) & 0xffff; + color.b = (b / count) & 0xffff; + return color; + }; enum SIMDLevel { None = 0, @@ -372,5 +410,33 @@ namespace Grab { return qRgb(color.r, color.g, color.b); } + + QRgba64 calculateAvgColor(const unsigned char* const buffer, BufferFormat bufferFormat, const size_t pitch, const QRect& rect, const quint16* gamma) { + + ColorValue color; + switch (bufferFormat) { + case BufferFormatArgb: + color = accumulateBufferGamma((int*)buffer, pitch / bytesPerPixel, rect, gamma); + break; + + case BufferFormatAbgr: + color = accumulateBufferGamma((int*)buffer, pitch / bytesPerPixel, rect, gamma); + break; + + case BufferFormatRgba: + color = accumulateBufferGamma((int*)buffer, pitch / bytesPerPixel, rect, gamma); + break; + + case BufferFormatBgra: + color = accumulateBufferGamma((int*)buffer, pitch / bytesPerPixel, rect, gamma); + break; + + default: + return qRgba64(0); + break; + } + + return qRgba64(color.r, color.g, color.b, 0); + } } } diff --git a/Software/grab/include/BlueLightReduction.hpp b/Software/grab/include/BlueLightReduction.hpp index 2628686f1..e53b9e1d4 100644 --- a/Software/grab/include/BlueLightReduction.hpp +++ b/Software/grab/include/BlueLightReduction.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include namespace BlueLightReduction @@ -10,6 +11,7 @@ namespace BlueLightReduction public: static bool isSupported() { assert(("BlueLightReduction::isSupported() is not implemented", false)); return false; } virtual void apply(QList& colors, const double gamma = 1.2) = 0; + virtual void apply(QList& colors, const double gamma = 1.2) = 0; virtual ~Client() = default; }; diff --git a/Software/grab/include/GrabberBase.hpp b/Software/grab/include/GrabberBase.hpp index dca98366a..416a4ceff 100644 --- a/Software/grab/include/GrabberBase.hpp +++ b/Software/grab/include/GrabberBase.hpp @@ -27,6 +27,7 @@ #include #include +#include #include #include "src/GrabWidget.hpp" #include "calculations.hpp" @@ -90,6 +91,7 @@ class GrabberBase : public QObject virtual ~GrabberBase() {} virtual const char * name() const = 0; + virtual void setGammaDecodeValue(double value); public slots: virtual void startGrabbing(); @@ -124,6 +126,7 @@ protected slots: virtual bool isReallocationNeeded(const QList< ScreenInfo > &grabScreens) const; + protected: const GrabbedScreen * screenOfRect(const QRect &rect) const; @@ -141,4 +144,5 @@ protected slots: int grabScreensCount; QList _screensWithWidgets; QScopedPointer m_timer; + quint16 gammaDecodeArray[256]; }; diff --git a/Software/grab/include/GrabberContext.hpp b/Software/grab/include/GrabberContext.hpp index fcf2a5b44..07c30e3b3 100644 --- a/Software/grab/include/GrabberContext.hpp +++ b/Software/grab/include/GrabberContext.hpp @@ -29,6 +29,7 @@ #include #include +#include class GrabWidget; @@ -96,7 +97,7 @@ class GrabberContext { } public: QList *grabWidgets; - QList *grabResult; + QList *grabResult; private: diff --git a/Software/grab/include/WinUtils.hpp b/Software/grab/include/WinUtils.hpp index 5e1a900a9..d875d22bd 100644 --- a/Software/grab/include/WinUtils.hpp +++ b/Software/grab/include/WinUtils.hpp @@ -38,6 +38,7 @@ #include #include #include +#include #include "BlueLightReduction.hpp" #if defined(NIGHTLIGHT_SUPPORT) @@ -76,6 +77,7 @@ VOID FreeRestrictedSD(PVOID ptr); NightLight(); ~NightLight(); void apply(QList& colors, const double gamma); + void apply(QList& colors, const double gamma); static bool isSupported(); private: NightLightLibrary::NightLightWrapper* _client; @@ -87,11 +89,14 @@ VOID FreeRestrictedSD(PVOID ptr); GammaRamp() = default; ~GammaRamp() = default; void apply(QList& colors, const double/*gamma*/); + void apply(QList& colors, const double/*gamma*/); static bool isSupported(); private: time_t _gammaAge = 0; WORD _gammaArray[3][256]; + WORD _gammaArray16[3][65536]; static bool loadGamma(LPVOID gamma, HDC* dc); + void interpolateGamma(); }; } diff --git a/Software/grab/include/calculations.hpp b/Software/grab/include/calculations.hpp index e76eadb39..058642cc3 100644 --- a/Software/grab/include/calculations.hpp +++ b/Software/grab/include/calculations.hpp @@ -27,11 +27,13 @@ #include #include +#include #include #include "common/BufferFormat.h" namespace Grab { namespace Calculations { QRgb calculateAvgColor(const unsigned char * const buffer, BufferFormat bufferFormat, const size_t pitch, const QRect &rect); + QRgba64 calculateAvgColor(const unsigned char* const buffer, BufferFormat bufferFormat, const size_t pitch, const QRect& rect, const quint16* gamma); } } diff --git a/Software/math/PrismatikMath.cpp b/Software/math/PrismatikMath.cpp index 4d13836c1..8e349460f 100644 --- a/Software/math/PrismatikMath.cpp +++ b/Software/math/PrismatikMath.cpp @@ -50,9 +50,9 @@ namespace PrismatikMath void gammaCorrection(double gamma, StructRgb & eRgb) { - eRgb.r = 4095 * pow(eRgb.r / 4095.0, gamma); - eRgb.g = 4095 * pow(eRgb.g / 4095.0, gamma); - eRgb.b = 4095 * pow(eRgb.b / 4095.0, gamma); + eRgb.r = 65535 * pow(eRgb.r / 65535.0, gamma); + eRgb.g = 65535 * pow(eRgb.g / 65535.0, gamma); + eRgb.b = 65535 * pow(eRgb.b / 65535.0, gamma); } void brightnessCorrection(unsigned int brightness, StructRgb & eRgb) { @@ -74,13 +74,24 @@ namespace PrismatikMath gamma = 1.0 / gamma; // encoding for (QRgb& color : colors) { - quint8 r = ::pow((qRed(color) * wp.r) / (double)USHRT_MAX, gamma) * UCHAR_MAX; - quint8 g = ::pow((qGreen(color) * wp.g) / (double)USHRT_MAX, gamma) * UCHAR_MAX; - quint8 b = ::pow((qBlue(color) * wp.b) / (double)USHRT_MAX, gamma) * UCHAR_MAX; + quint8 r = ::pow(((double)qRed(color) * wp.r) / (double)USHRT_MAX, gamma) * UCHAR_MAX; + quint8 g = ::pow(((double)qGreen(color) * wp.g) / (double)USHRT_MAX, gamma) * UCHAR_MAX; + quint8 b = ::pow(((double)qBlue(color) * wp.b) / (double)USHRT_MAX, gamma) * UCHAR_MAX; color = qRgb(r, g, b); } } + void applyColorTemperature(QList& colors, const quint16 colorTemperature, double gamma) { + StructRgb wp = whitePoint(colorTemperature); + gamma = 1.0 / gamma; // encoding + for (QRgba64& color : colors) + { + quint16 r = ::pow(((double)color.red() * wp.r) / (double)(65535 * 255), gamma) * 65535; + quint16 g = ::pow(((double)color.green() * wp.g) / (double)(65535 * 255), gamma) * 65535; + quint16 b = ::pow(((double)color.blue() * wp.b) / (double)(65535 * 255), gamma) * 65535; + color = qRgba64(r, g, b, 0); + } + } int getValueHSV(const QRgb rgb) { return max(rgb); @@ -194,10 +205,10 @@ namespace PrismatikMath } StructXyz toXyz(const StructRgb & rgb) { - //12bit RGB from 0 to 4095 - double r = ( rgb.r / 4095.0 ); - double g = ( rgb.g / 4095.0 ); - double b = ( rgb.b / 4095.0 ); + //16bit RGB from 0 to 65535 + double r = ( rgb.r / 65535.0 ); + double g = ( rgb.g / 65535.0); + double b = ( rgb.b / 65535.0); if ( r > 0.04045 ) r = pow( (r + 0.055)/1.055, 2.4); @@ -319,9 +330,9 @@ namespace PrismatikMath StructRgb eRgb; - eRgb.r = round(r*4095); - eRgb.g = round(g*4095); - eRgb.b = round(b*4095); + eRgb.r = round(r * 65535); + eRgb.g = round(g * 65535); + eRgb.b = round(b * 65535); return eRgb; } diff --git a/Software/math/include/PrismatikMath.hpp b/Software/math/include/PrismatikMath.hpp index fd000713c..785969d48 100644 --- a/Software/math/include/PrismatikMath.hpp +++ b/Software/math/include/PrismatikMath.hpp @@ -27,6 +27,7 @@ #include #include +#include #include #include "colorspace_types.h" #include "../../common/defs.h" @@ -43,6 +44,7 @@ namespace PrismatikMath QRgb withValueHSV(const QRgb, int); QRgb withChromaHSV(const QRgb, int); void applyColorTemperature(QList&, const quint16, double gamma); + void applyColorTemperature(QList&, const quint16, double gamma); StructRgb whitePoint(const quint16 colorTemperature); StructRgb avgColor(const QList &); StructXyz toXyz(const StructRgb &); diff --git a/Software/math/include/colorspace_types.h b/Software/math/include/colorspace_types.h index 36fa2ee8f..c3d5c43a1 100644 --- a/Software/math/include/colorspace_types.h +++ b/Software/math/include/colorspace_types.h @@ -28,10 +28,10 @@ #define COLORSPACE_TYPES_H /*! - 36bit RGB, 12 bit per channel! + 48bit RGB, 16 bit per channel! */ struct StructRgb { - unsigned r, g, b; + unsigned int r, g, b; StructRgb() { r = g = b = 0;} }; diff --git a/Software/src/AbstractLedDevice.cpp b/Software/src/AbstractLedDevice.cpp index 70e5d17bf..b9742d7ea 100644 --- a/Software/src/AbstractLedDevice.cpp +++ b/Software/src/AbstractLedDevice.cpp @@ -100,24 +100,22 @@ void AbstractLedDevice::updateDeviceSettings() All modifications are made over extended 12bit RGB, so \code outColors \endcode will contain 12bit RGB instead of 8bit. */ -void AbstractLedDevice::applyColorModifications(const QList &inColors, QList &outColors) { +void AbstractLedDevice::applyColorModifications(const QList &inColors, QList &outColors) { const bool isApplyWBAdjustments = m_wbAdjustments.count() == inColors.count(); for(int i = 0; i < inColors.count(); i++) { - //renormalize to 12bit - const constexpr double k = 4095/255.0; - outColors[i].r = qRed(inColors[i]) * k; - outColors[i].g = qGreen(inColors[i]) * k; - outColors[i].b = qBlue(inColors[i]) * k; + outColors[i].r = inColors[i].red(); + outColors[i].g = inColors[i].green(); + outColors[i].b = inColors[i].blue(); PrismatikMath::gammaCorrection(m_gamma, outColors[i]); } const StructLab avgColor = PrismatikMath::toLab(PrismatikMath::avgColor(outColors)); - const double ampCoef = m_ledMilliAmps / (4095.0 * 3.0) / 1000.0; + const double ampCoef = m_ledMilliAmps / (65535.0 * 3.0) / 1000.0; double estimatedTotalAmps = 0.0; for (int i = 0; i < outColors.count(); ++i) { @@ -150,7 +148,7 @@ void AbstractLedDevice::applyColorModifications(const QList &inColors, QLi outColors[i].b *= m_wbAdjustments[i].blue; } if (m_brightnessCap < SettingsScope::Profile::Device::BrightnessCapMax) { - const double bcapFactor = (m_brightnessCap / 100.0 * 4095 * 3) / (outColors[i].r + outColors[i].g + outColors[i].b); + const double bcapFactor = (m_brightnessCap / 100.0 * 65535 * 3) / (outColors[i].r + outColors[i].g + outColors[i].b); if (bcapFactor < 1.0) { outColors[i].r *= bcapFactor; outColors[i].g *= bcapFactor; @@ -169,4 +167,33 @@ void AbstractLedDevice::applyColorModifications(const QList &inColors, QLi color.b *= powerRatio; } } + + double carryR = 0; + double carryG = 0; + double carryB = 0; + + for (int i = 0; i < outColors.count(); ++i) { + double tempR = outColors[i].r + carryR; + double tempG = outColors[i].g + carryG; + double tempB = outColors[i].b + carryB; + + const constexpr double k = 65535 / 255.0; + const constexpr double kinv = 255.0 / 65535; + + if ((tempR * kinv) > 255) outColors[i].r = 255 << 8; + else if (tempR < 0) outColors[i].r = 0; + else outColors[i].r = (int)(tempR * kinv + 0.5) << 8; + + if ((tempG * kinv) > 255) outColors[i].g = 255 << 8; + else if (tempG < 0) outColors[i].g = 0; + else outColors[i].g = (int)(tempG * kinv + 0.5) << 8; + + if ((tempB * kinv) > 255) outColors[i].b = 255 << 8; + else if (tempB < 0) outColors[i].b = 0; + else outColors[i].b = (int)(tempB * kinv + 0.5) << 8; + + carryR = tempR - ((double)(outColors[i].r >> 8) * k); + carryG = tempG - ((double)(outColors[i].g >> 8) * k); + carryB = tempB - ((double)(outColors[i].b >> 8) * k); + } } diff --git a/Software/src/AbstractLedDevice.hpp b/Software/src/AbstractLedDevice.hpp index 075b6d220..8e2a2333e 100644 --- a/Software/src/AbstractLedDevice.hpp +++ b/Software/src/AbstractLedDevice.hpp @@ -53,13 +53,13 @@ class AbstractLedDevice : public QObject \param ok is command completed successfully */ void commandCompleted(bool ok); - void colorsUpdated(QList colors); + void colorsUpdated(QList colors); public slots: virtual const QString name() const = 0; virtual void open() = 0; virtual void close() = 0; - virtual void setColors(const QList & colors) = 0; + virtual void setColors(const QList & colors) = 0; virtual void switchOffLeds() = 0; /*! @@ -95,7 +95,7 @@ public slots: virtual void setUsbPowerLedDisabled(bool isDisabled) { Q_UNUSED(isDisabled) emit commandCompleted(true); }; protected: - virtual void applyColorModifications(const QList & inColors, QList & outColors); + virtual void applyColorModifications(const QList & inColors, QList & outColors); protected: QString m_colorSequence; @@ -109,6 +109,6 @@ public slots: QList m_wbAdjustments; - QList m_colorsSaved; + QList m_colorsSaved; QList m_colorsBuffer; }; diff --git a/Software/src/ApiServer.cpp b/Software/src/ApiServer.cpp index 73306c4b1..bfadbb9bb 100644 --- a/Software/src/ApiServer.cpp +++ b/Software/src/ApiServer.cpp @@ -496,7 +496,7 @@ void ApiServer::clientProcessCommands() API_DEBUG_OUT << CmdGetColors; result = ApiServer::CmdResultGetColors; - QList curentColors = lightpack->GetColors(); + QList curentColors = lightpack->GetColors(); for (int i = 0; i < curentColors.count(); i++) { diff --git a/Software/src/GrabManager.cpp b/Software/src/GrabManager.cpp index c2786898d..bff5a0d73 100644 --- a/Software/src/GrabManager.cpp +++ b/Software/src/GrabManager.cpp @@ -244,6 +244,15 @@ void GrabManager::onGrabberStateChangeRequested(bool isStartRequested) { #endif } +void GrabManager::onDeviceGammaChanged(double value) +{ + DEBUG_LOW_LEVEL << Q_FUNC_INFO << value; + if (m_grabber) { + m_grabber->setGammaDecodeValue(value); + calcGammaEncodeArray(value); + } +} + void GrabManager::onGrabSlowdownChanged(int ms) { DEBUG_LOW_LEVEL << Q_FUNC_INFO << ms; @@ -421,22 +430,15 @@ void GrabManager::handleGrabbedColors() int avgR = 0, avgG = 0, avgB = 0; int countGrabEnabled = 0; - if (m_isApplyColorTemperature) - { - PrismatikMath::applyColorTemperature(m_colorsProcessing, m_colorTemperature, m_gamma); - } - else if (m_isApplyBlueLightReduction && m_blueLightClient) - m_blueLightClient->apply(m_colorsProcessing, SettingsScope::Profile::Grab::GammaDefault); - if (m_avgColorsOnAllLeds) { for (int i = 0; i < m_ledWidgets.size(); i++) { if (m_ledWidgets[i]->isAreaEnabled()) { - avgR += qRed(m_colorsProcessing[i]); - avgG += qGreen(m_colorsProcessing[i]); - avgB += qBlue(m_colorsProcessing[i]); + avgR += m_colorsProcessing[i].red(); + avgG += m_colorsProcessing[i].green(); + avgB += m_colorsProcessing[i].blue(); countGrabEnabled++; } } @@ -451,21 +453,38 @@ void GrabManager::handleGrabbedColors() { if (m_ledWidgets[ledIndex]->isAreaEnabled()) { - m_colorsProcessing[ledIndex] = qRgb(avgR, avgG, avgB); + m_colorsProcessing[ledIndex] = qRgba64(avgR, avgG, avgB, 0); } } } + // encode color values with gamma + for (int ledIndex = 0; ledIndex < m_ledWidgets.size(); ledIndex++) + { + if (m_ledWidgets[ledIndex]->isAreaEnabled()) + { + quint16 r = m_gammaEncodeArray[m_colorsProcessing[ledIndex].red()]; + quint16 g = m_gammaEncodeArray[m_colorsProcessing[ledIndex].green()]; + quint16 b = m_gammaEncodeArray[m_colorsProcessing[ledIndex].blue()]; + m_colorsProcessing[ledIndex] = qRgba64(r, g, b, 0); + } + } + + if (m_isApplyColorTemperature) + PrismatikMath::applyColorTemperature(m_colorsProcessing, m_colorTemperature, m_gamma); + else if (m_isApplyBlueLightReduction && m_blueLightClient) + m_blueLightClient->apply(m_colorsProcessing, SettingsScope::Profile::Grab::GammaDefault); + for (int i = 0; i < m_ledWidgets.size(); i++) { - QRgb newColor = m_colorsProcessing[i]; + QRgba64 newColor = m_colorsProcessing[i]; if (m_overBrighten) { - int dRed = qRed(newColor); - int dGreen = qGreen(newColor); - int dBlue = qBlue(newColor); + int dRed = newColor.red(); + int dGreen = newColor.green(); + int dBlue = newColor.blue(); int highest = qMax(dRed, qMax(dGreen, dBlue)); - double scaleFactor = qMin((100 + 5 * m_overBrighten) / 100.0, 255.0 / highest); - newColor = qRgb(dRed * scaleFactor, dGreen * scaleFactor, dBlue * scaleFactor); + double scaleFactor = qMin((100 + 5 * m_overBrighten) / 100.0, 65535.0 / highest); + newColor = qRgba64(dRed * scaleFactor, dGreen * scaleFactor, dBlue * scaleFactor, 0); } if (m_colorsCurrent[i] != newColor) @@ -658,6 +677,13 @@ GrabberBase *GrabManager::initGrabber(GrabberBase * grabber) { return grabber; } +void GrabManager::calcGammaEncodeArray(double gamma) +{ + double gammaInv = 1 / gamma; + for (int i = 0; i < 65536; i++) + m_gammaEncodeArray[i] = 65535 * pow((double)i / 65535.0, gammaInv); +} + #ifdef D3D10_GRAB_SUPPORT void GrabManager::reinitDx1011Grabber() { QApplication::setOverrideCursor(Qt::WaitCursor); @@ -709,8 +735,8 @@ void GrabManager::initColorLists(int numberOfLeds) for (int i = 0; i < numberOfLeds; i++) { - m_colorsCurrent << 0; - m_colorsNew << 0; + m_colorsCurrent << qRgba64(0); + m_colorsNew << qRgba64(0); } } diff --git a/Software/src/GrabManager.hpp b/Software/src/GrabManager.hpp index 783710df0..060257b73 100644 --- a/Software/src/GrabManager.hpp +++ b/Software/src/GrabManager.hpp @@ -45,7 +45,7 @@ class GrabManager : public QObject virtual ~GrabManager(); signals: - void updateLedsColors(const QList & colors); + void updateLedsColors(const QList & colors); void ambilightTimeOfUpdatingColors(double ms); void changeScreen(); void onSessionChange(int change); @@ -80,6 +80,7 @@ public slots: void setColoredLedWidgets(bool state); void setWhiteLedWidgets(bool state); void onGrabberStateChangeRequested(bool isStartRequested); + void onDeviceGammaChanged(double value); private slots: void handleGrabbedColors(); @@ -96,6 +97,7 @@ private slots: GrabberBase *queryGrabber(Grab::GrabberType grabber); void initGrabbers(); GrabberBase *initGrabber(GrabberBase *grabber); + void calcGammaEncodeArray(double gamma); #ifdef D3D10_GRAB_SUPPORT void reinitDx1011Grabber(); #endif @@ -119,12 +121,12 @@ private slots: QTimer *m_timerFakeGrab; QWidget *m_parentWidget; QList m_ledWidgets; - QList m_grabResult; + QList m_grabResult; const static QColor m_backgroundAndTextColors[10][2]; - QList m_colorsCurrent; - QList m_colorsNew; - QList m_colorsProcessing; + QList m_colorsCurrent; + QList m_colorsNew; + QList m_colorsProcessing; QRect m_screenSavedRect; int m_screenSavedIndex; @@ -145,4 +147,6 @@ private slots: bool m_isGrabWidgetsVisible; GrabberContext * m_grabberContext; + + quint16 m_gammaEncodeArray[65536]; }; \ No newline at end of file diff --git a/Software/src/LedDeviceAdalight.cpp b/Software/src/LedDeviceAdalight.cpp index 3a96b69bf..ed9a28e8d 100644 --- a/Software/src/LedDeviceAdalight.cpp +++ b/Software/src/LedDeviceAdalight.cpp @@ -73,7 +73,7 @@ void LedDeviceAdalight::close() m_AdalightDevice = NULL; } -void LedDeviceAdalight::setColors(const QList & colors) +void LedDeviceAdalight::setColors(const QList & colors) { // Save colors for showing changes of the brightness m_colorsSaved = colors; @@ -90,9 +90,9 @@ void LedDeviceAdalight::setColors(const QList & colors) { StructRgb color = m_colorsBuffer[i]; - color.r = color.r >> 4; - color.g = color.g >> 4; - color.b = color.b >> 4; + color.r = color.r >> 8; + color.g = color.g >> 8; + color.b = color.b >> 8; if (m_colorSequence == "RBG") { @@ -143,7 +143,7 @@ void LedDeviceAdalight::switchOffLeds() m_colorsSaved.clear(); for (int i = 0; i < count; i++) - m_colorsSaved << 0; + m_colorsSaved << qRgba64(0); m_writeBuffer.clear(); m_writeBuffer.append(m_writeBufferHeader); diff --git a/Software/src/LedDeviceAdalight.hpp b/Software/src/LedDeviceAdalight.hpp index c2d9f6920..f0b65eb88 100644 --- a/Software/src/LedDeviceAdalight.hpp +++ b/Software/src/LedDeviceAdalight.hpp @@ -41,7 +41,7 @@ public slots: const QString name() const { return "adalight"; } void open(); void close(); - void setColors(const QList & /*colors*/); + void setColors(const QList & /*colors*/); void switchOffLeds(); void setRefreshDelay(int /*value*/); void setColorDepth(int /*value*/); diff --git a/Software/src/LedDeviceAlienFx.cpp b/Software/src/LedDeviceAlienFx.cpp index 41911e49d..ce5647f20 100644 --- a/Software/src/LedDeviceAlienFx.cpp +++ b/Software/src/LedDeviceAlienFx.cpp @@ -105,7 +105,7 @@ LedDeviceAlienFx::~LedDeviceAlienFx() DEBUG_LOW_LEVEL << Q_FUNC_INFO << "destroy LedDeviceAlienFx : ILedDevice complete"; } -void LedDeviceAlienFx::setColors(const QList & colors) +void LedDeviceAlienFx::setColors(const QList & colors) { DEBUG_MID_LEVEL << Q_FUNC_INFO; if (m_isInitialized) @@ -141,8 +141,8 @@ void LedDeviceAlienFx::setColors(const QList & colors) void LedDeviceAlienFx::switchOffLeds() { // TODO: fill it with current leds count - QList blackColor; - blackColor << 0; + QList blackColor; + blackColor << qRgba64(0); setColors(blackColor); } diff --git a/Software/src/LedDeviceAlienFx.hpp b/Software/src/LedDeviceAlienFx.hpp index d7614f421..98bac3ff2 100644 --- a/Software/src/LedDeviceAlienFx.hpp +++ b/Software/src/LedDeviceAlienFx.hpp @@ -43,7 +43,7 @@ public slots: const QString name() const { return "lightfx"; } void open(); void close(){}; - void setColors(const QList & colors); + void setColors(const QList & colors); void switchOffLeds(); void setRefreshDelay(int /*value*/); void setColorDepth(int /*value*/); diff --git a/Software/src/LedDeviceArdulight.cpp b/Software/src/LedDeviceArdulight.cpp index 36a108378..78387d4ec 100644 --- a/Software/src/LedDeviceArdulight.cpp +++ b/Software/src/LedDeviceArdulight.cpp @@ -76,10 +76,8 @@ void LedDeviceArdulight::close() m_ArdulightDevice = NULL; } -void LedDeviceArdulight::setColors(const QList & colors) +void LedDeviceArdulight::setColors(const QList & colors) { - DEBUG_MID_LEVEL << Q_FUNC_INFO << colors; - // Save colors for showing changes of the brightness m_colorsSaved = colors; @@ -88,9 +86,9 @@ void LedDeviceArdulight::setColors(const QList & colors) applyColorModifications(colors, m_colorsBuffer); for(int i=0; i < m_colorsBuffer.count(); i++) { - m_colorsBuffer[i].r = m_colorsBuffer[i].r >> 4; - m_colorsBuffer[i].g = m_colorsBuffer[i].g >> 4; - m_colorsBuffer[i].b = m_colorsBuffer[i].b >> 4; + m_colorsBuffer[i].r = m_colorsBuffer[i].r >> 8; + m_colorsBuffer[i].g = m_colorsBuffer[i].g >> 8; + m_colorsBuffer[i].b = m_colorsBuffer[i].b >> 8; PrismatikMath::maxCorrection(254, m_colorsBuffer[i]); } @@ -150,7 +148,7 @@ void LedDeviceArdulight::switchOffLeds() m_colorsSaved.clear(); for (int i = 0; i < count; i++) - m_colorsSaved << 0; + m_colorsSaved << qRgba64(0); m_writeBuffer.clear(); m_writeBuffer.append(m_writeBufferHeader); diff --git a/Software/src/LedDeviceArdulight.hpp b/Software/src/LedDeviceArdulight.hpp index 60216521b..0936bc0ec 100644 --- a/Software/src/LedDeviceArdulight.hpp +++ b/Software/src/LedDeviceArdulight.hpp @@ -41,7 +41,7 @@ public slots: const QString name() const { return "ardulight"; } void open(); void close(); - void setColors(const QList & /*colors*/); + void setColors(const QList & /*colors*/); void switchOffLeds(); void setRefreshDelay(int /*value*/); void setColorDepth(int /*value*/); diff --git a/Software/src/LedDeviceDnrgb.cpp b/Software/src/LedDeviceDnrgb.cpp index 96b480f45..23a67c195 100644 --- a/Software/src/LedDeviceDnrgb.cpp +++ b/Software/src/LedDeviceDnrgb.cpp @@ -41,7 +41,7 @@ int LedDeviceDnrgb::maxLedsCount() return MaximumNumberOfLeds::Dnrgb; } -void LedDeviceDnrgb::setColors(const QList & colors) +void LedDeviceDnrgb::setColors(const QList & colors) { bool ok = true; @@ -76,10 +76,10 @@ void LedDeviceDnrgb::setColors(const QList & colors) { StructRgb color = m_colorsBuffer[i]; - // Reduce 12-bit colour information - color.r = color.r >> 4; - color.g = color.g >> 4; - color.b = color.b >> 4; + // Reduce 16-bit colour information + color.r = color.r >> 8; + color.g = color.g >> 8; + color.b = color.b >> 8; m_writeBuffer.append(color.r); m_writeBuffer.append(color.g); @@ -100,7 +100,7 @@ void LedDeviceDnrgb::switchOffLeds() m_colorsSaved.clear(); for (int i = 0; i < count; i++) { - m_colorsSaved << 0; + m_colorsSaved << qRgba64(0); } // Send multiple buffers diff --git a/Software/src/LedDeviceDnrgb.hpp b/Software/src/LedDeviceDnrgb.hpp index 081d98022..161beddfd 100644 --- a/Software/src/LedDeviceDnrgb.hpp +++ b/Software/src/LedDeviceDnrgb.hpp @@ -36,7 +36,7 @@ class LedDeviceDnrgb : public AbstractLedDeviceUdp public slots: const QString name() const; - void setColors(const QList & colors); + void setColors(const QList & colors); void switchOffLeds(); void requestFirmwareVersion(); int maxLedsCount(); diff --git a/Software/src/LedDeviceDrgb.cpp b/Software/src/LedDeviceDrgb.cpp index 5cc11f711..028dbb0ea 100644 --- a/Software/src/LedDeviceDrgb.cpp +++ b/Software/src/LedDeviceDrgb.cpp @@ -41,7 +41,7 @@ int LedDeviceDrgb::maxLedsCount() return MaximumNumberOfLeds::Drgb; } -void LedDeviceDrgb::setColors(const QList & colors) +void LedDeviceDrgb::setColors(const QList & colors) { m_colorsSaved = colors; @@ -56,10 +56,10 @@ void LedDeviceDrgb::setColors(const QList & colors) { StructRgb color = m_colorsBuffer[i]; - // Reduce 12-bit colour information - color.r = color.r >> 4; - color.g = color.g >> 4; - color.b = color.b >> 4; + // Reduce 16-bit colour information + color.r = color.r >> 8; + color.g = color.g >> 8; + color.b = color.b >> 8; m_writeBuffer.append(color.r); m_writeBuffer.append(color.g); @@ -76,7 +76,7 @@ void LedDeviceDrgb::switchOffLeds() m_colorsSaved.clear(); for (int i = 0; i < count; i++) { - m_colorsSaved << 0; + m_colorsSaved << qRgba64(0); } m_writeBuffer.clear(); diff --git a/Software/src/LedDeviceDrgb.hpp b/Software/src/LedDeviceDrgb.hpp index a1bf6eea2..77fb60ab5 100644 --- a/Software/src/LedDeviceDrgb.hpp +++ b/Software/src/LedDeviceDrgb.hpp @@ -36,7 +36,7 @@ class LedDeviceDrgb : public AbstractLedDeviceUdp public slots: const QString name() const; - void setColors(const QList & colors); + void setColors(const QList & colors); void switchOffLeds(); void requestFirmwareVersion(); int maxLedsCount(); diff --git a/Software/src/LedDeviceLightpack.cpp b/Software/src/LedDeviceLightpack.cpp index 44d8669fa..e5494cdb3 100644 --- a/Software/src/LedDeviceLightpack.cpp +++ b/Software/src/LedDeviceLightpack.cpp @@ -63,7 +63,7 @@ LedDeviceLightpack::~LedDeviceLightpack() closeDevices(); } -void LedDeviceLightpack::setColors(const QList & colors) +void LedDeviceLightpack::setColors(const QList & colors) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) DEBUG_MID_LEVEL << Q_FUNC_INFO << Qt::hex << (colors.isEmpty() ? -1 : colors.first()); @@ -109,15 +109,15 @@ void LedDeviceLightpack::setColors(const QList & colors) buffIndex = WRITE_BUFFER_INDEX_DATA_START + kLedRemap[i % 10] * kSizeOfLedColor; // Send main 8 bits for compability with existing devices - m_writeBuffer[buffIndex++] = (color.r & 0x0FF0) >> 4; - m_writeBuffer[buffIndex++] = (color.g & 0x0FF0) >> 4; - m_writeBuffer[buffIndex++] = (color.b & 0x0FF0) >> 4; + m_writeBuffer[buffIndex++] = (color.r & 0xFF00) >> 8; + m_writeBuffer[buffIndex++] = (color.g & 0xFF00) >> 8; + m_writeBuffer[buffIndex++] = (color.b & 0xFF00) >> 8; // Send over 4 bits for devices revision >= 6 // All existing devices ignore it - m_writeBuffer[buffIndex++] = (color.r & 0x000F); - m_writeBuffer[buffIndex++] = (color.g & 0x000F); - m_writeBuffer[buffIndex++] = (color.b & 0x000F); + m_writeBuffer[buffIndex++] = (color.r & 0x00F0) >> 4; + m_writeBuffer[buffIndex++] = (color.g & 0x00F0) >> 4; + m_writeBuffer[buffIndex++] = (color.b & 0x00F0) >> 4; if ((i+1) % kLedsPerDevice == 0 || i == m_colorsBuffer.size() - 1) { if (m_devices.empty() || !writeBufferToDeviceWithCheck(CMD_UPDATE_LEDS, m_devices[(i+kLedsPerDevice)/kLedsPerDevice - 1])) { @@ -149,7 +149,7 @@ void LedDeviceLightpack::switchOffLeds() if (m_colorsSaved.empty()) { for (size_t i = 0; i < maxLedsCount(); ++i) - m_colorsSaved << 0; + m_colorsSaved << qRgba64(0); } else { for (int i = 0; i < m_colorsSaved.count(); i++) m_colorsSaved[i] = 0; diff --git a/Software/src/LedDeviceLightpack.hpp b/Software/src/LedDeviceLightpack.hpp index b476fe4da..eee01bf36 100644 --- a/Software/src/LedDeviceLightpack.hpp +++ b/Software/src/LedDeviceLightpack.hpp @@ -53,7 +53,7 @@ public slots: virtual const QString name() const { return "lightpack"; } virtual void open(); virtual void close(); - virtual void setColors(const QList & colors); + virtual void setColors(const QList & colors); virtual void switchOffLeds(); virtual void setUsbPowerLedDisabled(bool isDisabled); virtual void setRefreshDelay(int value); diff --git a/Software/src/LedDeviceManager.cpp b/Software/src/LedDeviceManager.cpp index 25d7a0431..709f081d2 100644 --- a/Software/src/LedDeviceManager.cpp +++ b/Software/src/LedDeviceManager.cpp @@ -118,7 +118,7 @@ void LedDeviceManager::switchOnLeds() emit ledDeviceSetColors(m_savedColors); } -void LedDeviceManager::setColors(const QList & colors) +void LedDeviceManager::setColors(const QList & colors) { DEBUG_HIGH_LEVEL << Q_FUNC_INFO << "Is last command completed:" << m_isLastCommandCompleted << " m_backlightStatus = " << m_backlightStatus; @@ -528,10 +528,10 @@ void LedDeviceManager::connectSignalSlotsLedDevice() connect(m_ledDevice, SIGNAL(firmwareVersion(QString)), this, SIGNAL(firmwareVersion(QString)), Qt::QueuedConnection); connect(m_ledDevice, SIGNAL(firmwareVersionUnofficial(int)), this, SIGNAL(firmwareVersionUnofficial(int)), Qt::QueuedConnection); - connect(m_ledDevice, SIGNAL(colorsUpdated(QList)), this, SIGNAL(setColors_VirtualDeviceCallback(QList)), Qt::QueuedConnection); + connect(m_ledDevice, SIGNAL(colorsUpdated(QList)), this, SIGNAL(setColors_VirtualDeviceCallback(QList)), Qt::QueuedConnection); connect(this, SIGNAL(ledDeviceOpen()), m_ledDevice, SLOT(open()), Qt::QueuedConnection); - connect(this, SIGNAL(ledDeviceSetColors(QList)), m_ledDevice, SLOT(setColors(QList)), Qt::QueuedConnection); + connect(this, SIGNAL(ledDeviceSetColors(QList)), m_ledDevice, SLOT(setColors(QList)), Qt::QueuedConnection); connect(this, SIGNAL(ledDeviceOffLeds()), m_ledDevice, SLOT(switchOffLeds()), Qt::QueuedConnection); connect(this, SIGNAL(ledDeviceSetUsbPowerLedDisabled(bool)), m_ledDevice, SLOT(setUsbPowerLedDisabled(bool)), Qt::QueuedConnection); connect(this, SIGNAL(ledDeviceSetRefreshDelay(int)), m_ledDevice, SLOT(setRefreshDelay(int)), Qt::QueuedConnection); @@ -562,10 +562,10 @@ void LedDeviceManager::disconnectSignalSlotsLedDevice() disconnect(m_ledDevice, SIGNAL(firmwareVersion(QString)), this, SIGNAL(firmwareVersion(QString))); disconnect(m_ledDevice, SIGNAL(firmwareVersionUnofficial(int)), this, SIGNAL(firmwareVersionUnofficial(int))); - disconnect(m_ledDevice, SIGNAL(colorsUpdated(QList)), this, SIGNAL(setColors_VirtualDeviceCallback(QList))); + disconnect(m_ledDevice, SIGNAL(colorsUpdated(QList)), this, SIGNAL(setColors_VirtualDeviceCallback(QList))); disconnect(this, SIGNAL(ledDeviceOpen()), m_ledDevice, SLOT(open())); - disconnect(this, SIGNAL(ledDeviceSetColors(QList)), m_ledDevice, SLOT(setColors(QList))); + disconnect(this, SIGNAL(ledDeviceSetColors(QList)), m_ledDevice, SLOT(setColors(QList))); disconnect(this, SIGNAL(ledDeviceOffLeds()), m_ledDevice, SLOT(switchOffLeds())); disconnect(this, SIGNAL(ledDeviceSetUsbPowerLedDisabled(bool)), m_ledDevice, SLOT(setUsbPowerLedDisabled(bool))); disconnect(this, SIGNAL(ledDeviceSetRefreshDelay(int)), m_ledDevice, SLOT(setRefreshDelay(int))); diff --git a/Software/src/LedDeviceManager.hpp b/Software/src/LedDeviceManager.hpp index 63db83685..65dd5779a 100644 --- a/Software/src/LedDeviceManager.hpp +++ b/Software/src/LedDeviceManager.hpp @@ -48,11 +48,11 @@ class LedDeviceManager : public QObject void ioDeviceSuccess(bool isSuccess); void firmwareVersion(const QString & fwVersion); void firmwareVersionUnofficial(const int version); - void setColors_VirtualDeviceCallback(const QList & colors); + void setColors_VirtualDeviceCallback(const QList & colors); // This signals are directly connected to ILedDevice. Don't use outside. void ledDeviceOpen(); - void ledDeviceSetColors(const QList & colors); + void ledDeviceSetColors(const QList & colors); void ledDeviceOffLeds(); void ledDeviceSetUsbPowerLedDisabled(bool isDisabled); void ledDeviceSetRefreshDelay(int value); @@ -74,7 +74,7 @@ public slots: void recreateLedDevice(); // This slots are protected from the overflow of queries - void setColors(const QList & colors); + void setColors(const QList & colors); void switchOffLeds(); void switchOnLeds(); void setUsbPowerLedDisabled(bool isDisabled); @@ -114,7 +114,7 @@ private slots: QList m_cmdQueue; - QList m_savedColors; + QList m_savedColors; bool m_savedUsbPowerLedDisabled; int m_savedRefreshDelay; int m_savedColorDepth; diff --git a/Software/src/LedDeviceVirtual.cpp b/Software/src/LedDeviceVirtual.cpp index 5ead3268f..bb4187d8f 100644 --- a/Software/src/LedDeviceVirtual.cpp +++ b/Software/src/LedDeviceVirtual.cpp @@ -40,13 +40,13 @@ LedDeviceVirtual::LedDeviceVirtual(QObject * parent) : AbstractLedDevice(parent) m_brightness = Settings::getDeviceBrightness(); } -void LedDeviceVirtual::setColors(const QList & colors) +void LedDeviceVirtual::setColors(const QList & colors) { if(colors.size()> 0) { m_colorsSaved = colors; - QList callbackColors; + QList callbackColors; resizeColorsBuffer(colors.count()); @@ -54,7 +54,7 @@ void LedDeviceVirtual::setColors(const QList & colors) for (int i = 0; i < m_colorsBuffer.count(); i++) { - callbackColors.append(qRgb(m_colorsBuffer[i].r>>4, m_colorsBuffer[i].g>>4, m_colorsBuffer[i].b>>4)); + callbackColors.append(qRgba64(m_colorsBuffer[i].r<<4, m_colorsBuffer[i].g<<4, m_colorsBuffer[i].b<<4, 0)); } emit colorsUpdated(callbackColors); @@ -68,7 +68,7 @@ void LedDeviceVirtual::switchOffLeds() m_colorsSaved.clear(); for (int i = 0; i < count; i++) { - m_colorsSaved << 0; + m_colorsSaved << qRgba64(0); } emit colorsUpdated(m_colorsSaved); emit commandCompleted(true); diff --git a/Software/src/LedDeviceVirtual.hpp b/Software/src/LedDeviceVirtual.hpp index 1833ea239..ab114f659 100644 --- a/Software/src/LedDeviceVirtual.hpp +++ b/Software/src/LedDeviceVirtual.hpp @@ -40,7 +40,7 @@ public slots: const QString name() const { return "virtual"; } void open(); void close(){} - void setColors(const QList & colors); + void setColors(const QList & colors); void switchOffLeds(); void setRefreshDelay(int /*value*/); void setColorDepth(int /*value*/); diff --git a/Software/src/LedDeviceWarls.cpp b/Software/src/LedDeviceWarls.cpp index ab18fb4bc..83498479c 100644 --- a/Software/src/LedDeviceWarls.cpp +++ b/Software/src/LedDeviceWarls.cpp @@ -41,7 +41,7 @@ int LedDeviceWarls::maxLedsCount() return MaximumNumberOfLeds::Warls; } -void LedDeviceWarls::setColors(const QList & colors) +void LedDeviceWarls::setColors(const QList & colors) { resizeColorsBuffer(colors.count()); @@ -56,10 +56,10 @@ void LedDeviceWarls::setColors(const QList & colors) { StructRgb color = m_colorsBuffer[i]; - // Reduce 12-bit colour information - color.r = color.r >> 4; - color.g = color.g >> 4; - color.b = color.b >> 4; + // Reduce 16-bit colour information + color.r = color.r >> 8; + color.g = color.g >> 8; + color.b = color.b >> 8; m_writeBuffer.append(i); m_writeBuffer.append(color.r); @@ -81,7 +81,7 @@ void LedDeviceWarls::switchOffLeds() m_colorsSaved.clear(); for (int i = 0; i < count; i++) { - m_colorsSaved << 0; + m_colorsSaved << qRgba64(0); } m_writeBuffer.clear(); @@ -122,7 +122,7 @@ void LedDeviceWarls::resizeColorsBuffer(int buffSize) for (int i = 0; i < buffSize; i++) { m_colorsBuffer << StructRgb(); - m_colorsSaved << 0; + m_colorsSaved << qRgba64(0); } reinitBufferHeader(); diff --git a/Software/src/LedDeviceWarls.hpp b/Software/src/LedDeviceWarls.hpp index de86dadf1..221b646c7 100644 --- a/Software/src/LedDeviceWarls.hpp +++ b/Software/src/LedDeviceWarls.hpp @@ -36,7 +36,7 @@ class LedDeviceWarls : public AbstractLedDeviceUdp public slots: const QString name() const; - void setColors(const QList & colors); + void setColors(const QList & colors); void switchOffLeds(); void requestFirmwareVersion(); int maxLedsCount(); diff --git a/Software/src/LightpackApplication.cpp b/Software/src/LightpackApplication.cpp index 26602573e..b69e17686 100644 --- a/Software/src/LightpackApplication.cpp +++ b/Software/src/LightpackApplication.cpp @@ -145,6 +145,7 @@ void LightpackApplication::initializeAll(const QString & appDirPath) } // Register QMetaType for Qt::QueuedConnection qRegisterMetaType< QList >("QList"); + qRegisterMetaType< QList >("QList"); qRegisterMetaType< QList >("QList"); qRegisterMetaType("Lightpack::Mode"); qRegisterMetaType("Backlight::Status"); @@ -588,7 +589,7 @@ void LightpackApplication::startApiServer() connect(m_apiServer, SIGNAL(errorOnStartListening(QString)), m_settingsWindow, SLOT(onApiServer_ErrorOnStartListening(QString))); } - connect(m_ledDeviceManager, SIGNAL(ledDeviceSetColors(const QList &)), m_pluginInterface, SLOT(updateColorsCache(const QList &)), Qt::QueuedConnection); + connect(m_ledDeviceManager, SIGNAL(ledDeviceSetColors(const QList &)), m_pluginInterface, SLOT(updateColorsCache(const QList &)), Qt::QueuedConnection); connect(m_ledDeviceManager, SIGNAL(ledDeviceSetSmoothSlowdown(int)), m_pluginInterface, SLOT(updateSmoothCache(int)), Qt::QueuedConnection); connect(m_ledDeviceManager, SIGNAL(ledDeviceSetGamma(double)), m_pluginInterface, SLOT(updateGammaCache(double)), Qt::QueuedConnection); connect(m_ledDeviceManager, SIGNAL(ledDeviceSetBrightness(int)), m_pluginInterface, SLOT(updateBrightnessCache(int)), Qt::QueuedConnection); @@ -614,11 +615,11 @@ void LightpackApplication::startLedDeviceManager() // connect(settings(), SIGNAL(connectedDeviceChanged(const SupportedDevices::DeviceType)), this, SLOT(handleConnectedDeviceChange(const SupportedDevices::DeviceType)), Qt::DirectConnection); // connect(settings(), SIGNAL(adalightSerialPortNameChanged(QString)), m_ledDeviceManager, SLOT(recreateLedDevice()), Qt::DirectConnection); // connect(settings(), SIGNAL(adalightSerialPortBaudRateChanged(QString)), m_ledDeviceManager, SLOT(recreateLedDevice()), Qt::DirectConnection); -// connect(m_settingsWindow, SIGNAL(updateLedsColors(const QList &)), m_ledDeviceManager, SLOT(setColors(QList)), Qt::QueuedConnection); +// connect(m_settingsWindow, SIGNAL(updateLedsColors(const QList &)), m_ledDeviceManager, SLOT(setColors(QList)), Qt::QueuedConnection); m_pluginInterface = new LightpackPluginInterface(NULL); connect(m_pluginInterface, SIGNAL(updateDeviceLockStatus(DeviceLocked::DeviceLockStatus, QList)), this, SLOT(setDeviceLockViaAPI(DeviceLocked::DeviceLockStatus, QList))); - connect(m_pluginInterface, SIGNAL(updateLedsColors(const QList &)), m_ledDeviceManager, SLOT(setColors(QList)), Qt::QueuedConnection); + connect(m_pluginInterface, SIGNAL(updateLedsColors(const QList &)), m_ledDeviceManager, SLOT(setColors(QList)), Qt::QueuedConnection); connect(m_pluginInterface, SIGNAL(updateGamma(double)), m_ledDeviceManager, SLOT(setGamma(double)), Qt::QueuedConnection); connect(m_pluginInterface, SIGNAL(updateBrightness(int)), m_ledDeviceManager, SLOT(setBrightness(int)), Qt::QueuedConnection); connect(m_pluginInterface, SIGNAL(updateSmooth(int)), m_ledDeviceManager, SLOT(setSmoothSlowdown(int)), Qt::QueuedConnection); @@ -630,7 +631,7 @@ void LightpackApplication::startLedDeviceManager() if (!m_noGui) { - connect(m_pluginInterface, SIGNAL(updateLedsColors(const QList &)), m_settingsWindow, SLOT(updateVirtualLedsColors(QList))); + connect(m_pluginInterface, SIGNAL(updateLedsColors(const QList &)), m_settingsWindow, SLOT(updateVirtualLedsColors(QList))); connect(m_pluginInterface, SIGNAL(updateDeviceLockStatus(DeviceLocked::DeviceLockStatus, QList)), m_settingsWindow, SLOT(setDeviceLockViaAPI(DeviceLocked::DeviceLockStatus, QList))); connect(m_pluginInterface, SIGNAL(updateProfile(QString)), m_settingsWindow, SLOT(profileSwitch(QString))); connect(m_pluginInterface, SIGNAL(updateStatus(Backlight::Status)), m_settingsWindow, SLOT(setBacklightStatus(Backlight::Status))); @@ -664,7 +665,7 @@ void LightpackApplication::startLedDeviceManager() connect(m_ledDeviceManager, SIGNAL(ioDeviceSuccess(bool)), m_settingsWindow, SLOT(ledDeviceCallSuccess(bool)), Qt::QueuedConnection); connect(m_ledDeviceManager, SIGNAL(firmwareVersion(QString)), m_settingsWindow, SLOT(ledDeviceFirmwareVersionResult(QString)), Qt::QueuedConnection); connect(m_ledDeviceManager, SIGNAL(firmwareVersionUnofficial(int)), m_settingsWindow, SLOT(ledDeviceFirmwareVersionUnofficialResult(int)), Qt::QueuedConnection); - connect(m_ledDeviceManager, SIGNAL(setColors_VirtualDeviceCallback(QList)), m_settingsWindow, SLOT(updateVirtualLedsColors(QList)), Qt::QueuedConnection); + connect(m_ledDeviceManager, SIGNAL(setColors_VirtualDeviceCallback(QList)), m_settingsWindow, SLOT(updateVirtualLedsColors(QList)), Qt::QueuedConnection); } m_ledDeviceManager->moveToThread(m_ledDeviceManagerThread); m_ledDeviceManagerThread->start(); @@ -719,6 +720,7 @@ void LightpackApplication::initGrabManager() connect(settings(), SIGNAL(grabApplyColorTemperatureChanged(bool)), m_grabManager, SLOT(onGrabApplyColorTemperatureChanged(bool)), Qt::QueuedConnection); connect(settings(), SIGNAL(grabColorTemperatureChanged(int)), m_grabManager, SLOT(onGrabColorTemperatureChanged(int)), Qt::QueuedConnection); connect(settings(), SIGNAL(grabGammaChanged(double)), m_grabManager, SLOT(onGrabGammaChanged(double)), Qt::QueuedConnection); + connect(settings(), SIGNAL(deviceGammaChanged(double)), m_grabManager, SLOT(onDeviceGammaChanged(double)), Qt::QueuedConnection); connect(settings(), SIGNAL(sendDataOnlyIfColorsChangesChanged(bool)), m_grabManager, SLOT(onSendDataOnlyIfColorsEnabledChanged(bool)), Qt::QueuedConnection); #ifdef D3D10_GRAB_SUPPORT connect(settings(), SIGNAL(dx1011GrabberEnabledChanged(bool)), m_grabManager, SLOT(onDx1011GrabberEnabledChanged(bool)), Qt::QueuedConnection); @@ -781,15 +783,15 @@ void LightpackApplication::initGrabManager() connect(m_grabManager, SIGNAL(ambilightTimeOfUpdatingColors(double)), m_pluginInterface, SLOT(refreshAmbilightEvaluated(double))); - connect(m_grabManager, SIGNAL(updateLedsColors(const QList &)), m_ledDeviceManager, SLOT(setColors(QList)), Qt::QueuedConnection); - connect(m_moodlampManager, SIGNAL(updateLedsColors(const QList &)), m_ledDeviceManager, SLOT(setColors(QList)), Qt::QueuedConnection); + connect(m_grabManager, SIGNAL(updateLedsColors(const QList &)), m_ledDeviceManager, SLOT(setColors(QList)), Qt::QueuedConnection); + connect(m_moodlampManager, SIGNAL(updateLedsColors(const QList &)), m_ledDeviceManager, SLOT(setColors(QList)), Qt::QueuedConnection); if (!m_noGui && m_settingsWindow) connect(m_moodlampManager, SIGNAL(moodlampFrametime(const double)), m_settingsWindow, SLOT(refreshAmbilightEvaluated(double)), Qt::QueuedConnection); connect(m_ledDeviceManager, SIGNAL(openDeviceSuccess(bool)), m_grabManager, SLOT(ledDeviceOpenSuccess(bool)), Qt::QueuedConnection); connect(m_ledDeviceManager, SIGNAL(ioDeviceSuccess(bool)), m_grabManager, SLOT(ledDeviceCallSuccess(bool)), Qt::QueuedConnection); #ifdef SOUNDVIZ_SUPPORT if (m_soundManager) { - connect(m_soundManager, SIGNAL(updateLedsColors(const QList &)), m_ledDeviceManager, SLOT(setColors(QList)), Qt::QueuedConnection); + connect(m_soundManager, SIGNAL(updateLedsColors(const QList &)), m_ledDeviceManager, SLOT(setColors(QList)), Qt::QueuedConnection); if (!m_noGui && m_settingsWindow) connect(m_soundManager, SIGNAL(visualizerFrametime(const double)), m_settingsWindow, SLOT(refreshAmbilightEvaluated(double)), Qt::QueuedConnection); } @@ -805,8 +807,8 @@ void LightpackApplication::commitData(QSessionManager &sessionManager) if (m_ledDeviceManager != NULL) { // Disable signals with new colors - disconnect(m_settingsWindow, SIGNAL(updateLedsColors(QList)), m_ledDeviceManager, SLOT(setColors(QList))); - disconnect(m_apiServer, SIGNAL(updateLedsColors(QList)), m_ledDeviceManager, SLOT(setColors(QList))); + disconnect(m_settingsWindow, SIGNAL(updateLedsColors(QList)), m_ledDeviceManager, SLOT(setColors(QList))); + disconnect(m_apiServer, SIGNAL(updateLedsColors(QList)), m_ledDeviceManager, SLOT(setColors(QList))); // Process all currently pending signals QApplication::processEvents(QEventLoop::AllEvents, 1000); diff --git a/Software/src/LightpackPluginInterface.cpp b/Software/src/LightpackPluginInterface.cpp index 4c4c632fb..2912b0987 100644 --- a/Software/src/LightpackPluginInterface.cpp +++ b/Software/src/LightpackPluginInterface.cpp @@ -101,8 +101,8 @@ void LightpackPluginInterface::initColors(int numberOfLeds) m_setColors.clear(); for (int i = 0; i < numberOfLeds; i++) { - m_setColors << 0; - m_curColors << 0; + m_setColors << qRgba64(0); + m_curColors << qRgba64(0); } } @@ -157,7 +157,7 @@ void LightpackPluginInterface::refreshScreenRect(QRect rect) screen = rect; } -void LightpackPluginInterface::updateColorsCache(const QList & colors) +void LightpackPluginInterface::updateColorsCache(const QList & colors) { DEBUG_HIGH_LEVEL << Q_FUNC_INFO; m_curColors = colors; @@ -328,7 +328,7 @@ bool LightpackPluginInterface::SetColors(QString sessionKey, int r, int g, int b lockAlive = true; for (int i = 0; i < m_setColors.size(); i++) { - m_setColors[i] = qRgb(r,g,b); + m_setColors[i] = qRgba64(r * 257, g * 257, b * 257, 0); } m_curColors = m_setColors; emit updateLedsColors(m_setColors); @@ -641,7 +641,7 @@ QList LightpackPluginInterface::GetLeds() return leds; } -QList LightpackPluginInterface::GetColors() +QList LightpackPluginInterface::GetColors() { return m_curColors; } diff --git a/Software/src/LightpackPluginInterface.hpp b/Software/src/LightpackPluginInterface.hpp index 653352d65..697e200b8 100644 --- a/Software/src/LightpackPluginInterface.hpp +++ b/Software/src/LightpackPluginInterface.hpp @@ -51,7 +51,7 @@ class LightpackPluginInterface : public QObject QStringList GetProfiles(); QString GetProfile(); QList GetLeds(); - QList GetColors(); + QList GetColors(); double GetFPS(); QRect GetScreenSize(); int GetBacklight(); @@ -84,7 +84,7 @@ class LightpackPluginInterface : public QObject signals: void requestBacklightStatus(); void updateDeviceLockStatus(DeviceLocked::DeviceLockStatus status, QList modules); - void updateLedsColors(const QList & colors); + void updateLedsColors(const QList & colors); void updateGamma(double value); void updateBrightness(int value); void updateSmooth(int value); @@ -106,7 +106,7 @@ public slots: void changeProfile(QString profile); void refreshAmbilightEvaluated(double updateResultMs); void refreshScreenRect(QRect rect); - void updateColorsCache(const QList & colors); + void updateColorsCache(const QList & colors); void updateGammaCache(double value); void updateBrightnessCache(int value); void updateSmoothCache(int value); @@ -132,8 +132,8 @@ private slots: QRect screen; QList lockSessionKeys; - QList m_setColors; - QList m_curColors; + QList m_setColors; + QList m_curColors; QTimer *m_timerLock; double m_gamma; diff --git a/Software/src/MoodLamp.cpp b/Software/src/MoodLamp.cpp index 29640c3ec..00aafece1 100644 --- a/Software/src/MoodLamp.cpp +++ b/Software/src/MoodLamp.cpp @@ -115,12 +115,12 @@ DECLARE_LAMP(Static, "Static (default)", public: int interval() const { return 50; }; - bool shine(const QColor& newColor, QList& colors) + bool shine(const QColor& newColor, QList& colors) { bool changed = false; for (int i = 0; i < colors.size(); i++) { - QRgb rgb = Settings::isLedEnabled(i) ? newColor.rgb() : 0; + QRgba64 rgb = Settings::isLedEnabled(i) ? newColor.rgba64() : qRgba64(0); changed = changed || (colors[i] != rgb); colors[i] = rgb; } @@ -134,7 +134,7 @@ DECLARE_LAMP(Fire, "Fire", m_rnd.seed(QTime(0, 0, 0).secsTo(QTime::currentTime())); }; - bool shine(const QColor& newColor, QList& colors) { + bool shine(const QColor& newColor, QList& colors) { if (colors.size() < 2) return false; @@ -189,7 +189,7 @@ DECLARE_LAMP(Fire, "Fire", { QColor color(newColor); color.setHsl(color.hue(), color.saturation(), m_lightness[i]); - colors[i] = Settings::isLedEnabled(i) ? color.rgb() : 0; + colors[i] = Settings::isLedEnabled(i) ? color.rgba64() : qRgba64(0); } return true; }; @@ -205,7 +205,7 @@ DECLARE_LAMP(Fire, "Fire", DECLARE_LAMP(RGBLife, "RGB is Life", public: - bool shine(const QColor& newColor, QList& colors) + bool shine(const QColor& newColor, QList& colors) { bool changed = false; const int degrees = 360 / colors.size(); @@ -214,7 +214,7 @@ DECLARE_LAMP(RGBLife, "RGB is Life", { QColor color(newColor); color.setHsl(color.hue() + degrees * i + step, color.saturation(), color.lightness()); - QRgb rgb = Settings::isLedEnabled(i) ? color.rgb() : 0; + QRgba64 rgb = Settings::isLedEnabled(i) ? color.rgba64() : qRgba64(0); changed = changed || (colors[i] != rgb); colors[i] = rgb; } diff --git a/Software/src/MoodLamp.hpp b/Software/src/MoodLamp.hpp index 4d4947feb..cc42de3df 100644 --- a/Software/src/MoodLamp.hpp +++ b/Software/src/MoodLamp.hpp @@ -27,6 +27,7 @@ #include #include +#include class MoodLampBase; @@ -54,7 +55,7 @@ class MoodLampBase virtual void init() {}; virtual int interval() const { return DefaultInterval; }; - virtual bool shine(const QColor& newColor, QList& colors) = 0; + virtual bool shine(const QColor& newColor, QList& colors) = 0; protected: size_t m_frames{ 0 }; private: diff --git a/Software/src/MoodLampManager.cpp b/Software/src/MoodLampManager.cpp index 1b0331d17..b11fbf0e3 100644 --- a/Software/src/MoodLampManager.cpp +++ b/Software/src/MoodLampManager.cpp @@ -190,7 +190,7 @@ void MoodLampManager::initColors(int numberOfLeds) m_colors.clear(); for (int i = 0; i < numberOfLeds; i++) - m_colors << 0; + m_colors << qRgba64(0); } void MoodLampManager::requestLampList() diff --git a/Software/src/MoodLampManager.hpp b/Software/src/MoodLampManager.hpp index becd39e84..b0425018d 100644 --- a/Software/src/MoodLampManager.hpp +++ b/Software/src/MoodLampManager.hpp @@ -26,7 +26,7 @@ #pragma once #include -#include +#include #include #include #include "LiquidColorGenerator.hpp" @@ -40,7 +40,7 @@ class MoodLampManager : public QObject ~MoodLampManager(); signals: - void updateLedsColors(const QList & colors); + void updateLedsColors(const QList & colors); void lampList(const QList &, int); void moodlampFrametime(const double frameMs); @@ -71,7 +71,7 @@ private slots: MoodLampBase* m_lamp{ nullptr }; LiquidColorGenerator m_generator; - QList m_colors; + QList m_colors; bool m_isMoodLampEnabled; QColor m_currentColor; diff --git a/Software/src/wizard/GlobalColorCoefPage.cpp b/Software/src/wizard/GlobalColorCoefPage.cpp index 15d025183..96faf0a02 100644 --- a/Software/src/wizard/GlobalColorCoefPage.cpp +++ b/Software/src/wizard/GlobalColorCoefPage.cpp @@ -85,7 +85,7 @@ void GlobalColorCoefPage::initializePage() resetDeviceSettings(); onCoefValueChanged(); - turnLightsOn(qRgb(255, 255, 255)); + turnLightsOn(qRgba64(65535, 65535, 65535, 0)); } bool GlobalColorCoefPage::validatePage() diff --git a/Software/src/wizard/WizardPageUsingDevice.cpp b/Software/src/wizard/WizardPageUsingDevice.cpp index 5ca374b2a..a5f707f7d 100644 --- a/Software/src/wizard/WizardPageUsingDevice.cpp +++ b/Software/src/wizard/WizardPageUsingDevice.cpp @@ -70,20 +70,20 @@ AbstractLedDevice * WizardPageUsingDevice::device() void WizardPageUsingDevice::turnLightOn(int id) { - QList lights; + QList lights; for (int i = 0; i < _transSettings->ledCount; i++) { if (i == id) - lights.append(qRgb(255, 255, 255)); + lights.append(qRgba64(65535, 65535, 65535, 0)); else - lights.append(0); + lights.append(qRgba64(0)); } device()->setColors(lights); } -void WizardPageUsingDevice::turnLightsOn(QRgb color) +void WizardPageUsingDevice::turnLightsOn(QRgba64 color) { - QList lights; + QList lights; for (int i = 0; i < _transSettings->ledCount; i++) { lights.append(color); @@ -93,10 +93,10 @@ void WizardPageUsingDevice::turnLightsOn(QRgb color) void WizardPageUsingDevice::turnLightsOff() { - QList lights; + QList lights; for (int i = 0; i < _transSettings->ledCount; i++) { - lights.append(0); + lights.append(qRgba64(0)); } device()->setColors(lights); } \ No newline at end of file diff --git a/Software/src/wizard/WizardPageUsingDevice.hpp b/Software/src/wizard/WizardPageUsingDevice.hpp index 8b546ee47..ec1732e9d 100644 --- a/Software/src/wizard/WizardPageUsingDevice.hpp +++ b/Software/src/wizard/WizardPageUsingDevice.hpp @@ -43,7 +43,7 @@ class WizardPageUsingDevice : public QWizardPage, protected SettingsAwareTrait protected slots: void turnLightOn(int id); - void turnLightsOn(QRgb color); + void turnLightsOn(QRgba64 color); void turnLightsOff();