[graphics/krita] /: Create lager model for HDR metadata, use colorimetry::xy for volume.
Wolthera van Hövell tot Westerflier <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit b533c4d976f371d0fcf4aa0aea38fe5b0fa9894f by Wolthera van Hövell tot Westerflier.
Committed on 11/08/2026 at 09:33.
Pushed by woltherav into branch 'master'.
Create lager model for HDR metadata, use colorimetry::xy for volume.
M +2 -0 libs/image/CMakeLists.txt
A +24 -0 libs/image/kis_hdr_metadata.cpp [License: GPL(v2.0+)]
M +13 -17 libs/image/kis_hdr_metadata.h
A +222 -0 libs/image/kis_hdr_metadata_models.cpp [License: GPL(v2.0+)]
A +83 -0 libs/image/kis_hdr_metadata_models.h [License: GPL(v2.0+)]
M +21 -20 libs/ui/animation/KisHDRMetadataOptions.cpp
M +37 -106 libs/ui/dialogs/kis_dlg_image_properties.cc
M +55 -0 libs/widgets/KisWidgetConnectionUtils.cpp
M +2 -0 libs/widgets/KisWidgetConnectionUtils.h
M +23 -8 plugins/impex/libkra/kis_kra_loader.cpp
M +4 -4 plugins/impex/libkra/kis_kra_saver.cpp
https://invent.kde.org/graphics/krita/-/commit/b533c4d976f371d0fcf4aa0aea38fe5b0fa9894f
diff --git a/libs/image/CMakeLists.txt b/libs/image/CMakeLists.txt
index a9361ee5f5b..e8a37ac3e44 100644
--- a/libs/image/CMakeLists.txt
+++ b/libs/image/CMakeLists.txt
@@ -362,6 +362,8 @@ set(kritaimage_LIB_SRCS
kis_convex_hull.cpp
KisSpatialContainer.cpp
+ kis_hdr_metadata.cpp
+ kis_hdr_metadata_models.cpp
)
set(einspline_SRCS
diff --git a/libs/image/kis_hdr_metadata.cpp b/libs/image/kis_hdr_metadata.cpp
new file mode 100644
index 00000000000..c1b68b01c7a
--- /dev/null
+++ b/libs/image/kis_hdr_metadata.cpp
@@ -0,0 +1,24 @@
+/*
+ * SPDX-FileCopyrightText: 2026 Wolthera van Hövell tot Westerflier <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include <kis_hdr_metadata.h>
+#include <KisStaticInitializer.h>
+
+KIS_DECLARE_STATIC_INITIALIZER {
+ qRegisterMetaType<KisRelativeContentLightLevelInformation::CalculationType>();
+}
+
+bool KisRelativeContentLightLevelInformation::operator==(const KisRelativeContentLightLevelInformation &other) const {
+ return qFuzzyCompare(maxContentLightLevel, other.maxContentLightLevel)
+ && qFuzzyCompare(maxFrameAverageLightLevel, other.maxFrameAverageLightLevel)
+ && (type == other.type);
+}
+
+bool KisColorVolumeInformation::operator==(const KisColorVolumeInformation &other) const {
+ return qFuzzyCompare(maxLuminance, other.maxLuminance)
+ && qFuzzyCompare(minLuminance, other.minLuminance)
+ && white == other.white && red == other.red
+ && green == other.green && blue == other.blue;
+}
diff --git a/libs/image/kis_hdr_metadata.h b/libs/image/kis_hdr_metadata.h
index ad22c30e65e..af45987f2b6 100644
--- a/libs/image/kis_hdr_metadata.h
+++ b/libs/image/kis_hdr_metadata.h
@@ -7,14 +7,17 @@
#define KIS_HDR_METADATA_H
#include <QPointF>
+#include <KoColorimetryUtils.h>
#include <boost/operators.hpp>
+
+#include "kritaimage_export.h"
/**
* KisRelativeContentLightLevelInformation is a struct that represents
* HDR10 metadata. It is similar to the same values in MasteringInfo in
* KisSurfaceColorimetry.h, though typically relative to the diffuse white.
*/
-struct KisRelativeContentLightLevelInformation: public boost::equality_comparable<KisRelativeContentLightLevelInformation> {
+struct KRITAIMAGE_EXPORT KisRelativeContentLightLevelInformation: public boost::equality_comparable<KisRelativeContentLightLevelInformation> {
/**
* MaxContentLightLevel or MaxCLL is the brightest pixel in the frame sequence.
*/
@@ -34,11 +37,7 @@ struct KisRelativeContentLightLevelInformation: public boost::equality_comparabl
CalculationType type = XYZLuminance;
- bool operator==(const KisRelativeContentLightLevelInformation & other) const {
- return qFuzzyCompare(maxContentLightLevel, other.maxContentLightLevel)
- && qFuzzyCompare(maxFrameAverageLightLevel, other.maxFrameAverageLightLevel)
- && (type == other.type);
- };
+ bool operator==(const KisRelativeContentLightLevelInformation & other) const;;
};
/**
@@ -46,21 +45,18 @@ struct KisRelativeContentLightLevelInformation: public boost::equality_comparabl
* is a struct that represents the 'mastering' display. It's primary purpose
* is to provide extra information for gamutmapping.
*/
-struct KisColorVolumeInformation: public boost::equality_comparable<KisColorVolumeInformation> {
- QPointF white; ///< xyY location of the whitepoint.
- QPointF red; ///< xyY location of the red colorant.
- QPointF green; ///< xyY location of the green colorant.
- QPointF blue; ///< xyY location of the blue colorant.
+struct KRITAIMAGE_EXPORT KisColorVolumeInformation: public boost::equality_comparable<KisColorVolumeInformation> {
+ KoColorimetryUtils::xy white; ///< xyY location of the whitepoint.
+ KoColorimetryUtils::xy red; ///< xyY location of the red colorant.
+ KoColorimetryUtils::xy green; ///< xyY location of the green colorant.
+ KoColorimetryUtils::xy blue; ///< xyY location of the blue colorant.
double maxLuminance = 0.0; ///< Maximum screen brightness in cd/m²
double minLuminance = 0.0; ///< Minimum screen brightness in cd/m²
- bool operator==(const KisColorVolumeInformation & other) const {
- return qFuzzyCompare(maxLuminance, other.maxLuminance)
- && qFuzzyCompare(minLuminance, other.minLuminance)
- && white == other.white && red == other.red
- && green == other.green && blue == other.blue;
- };
+ bool operator==(const KisColorVolumeInformation & other) const;;
};
+Q_DECLARE_METATYPE(KisRelativeContentLightLevelInformation::CalculationType);
+
#endif // KIS_HDR_METADATA_H
diff --git a/libs/image/kis_hdr_metadata_models.cpp b/libs/image/kis_hdr_metadata_models.cpp
new file mode 100644
index 00000000000..d2995762898
--- /dev/null
+++ b/libs/image/kis_hdr_metadata_models.cpp
@@ -0,0 +1,222 @@
+/*
+ * SPDX-FileCopyrightText: 2026 Wolthera van Hövell tot Westerflier <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "kis_hdr_metadata_models.h"
+#include <KLocalizedString>
+#include <lager/constant.hpp>
+#include <KisZug.h>
+#include <KisLager.h>
+namespace {
+
+ComboBoxState calcTypeComboBoxState(KisRelativeContentLightLevelInformation::CalculationType type, bool enabled)
+{
+ QStringList values;
+ QStringList toolTips;
+
+ values << i18nc("CLLI calculation type", "XYZ Luminance");
+ values << i18nc("CLLI calculation type", "Rec 2020 Per Component");
+ values << i18nc("CLLI calculation type", "RGB Per Component");
+
+ toolTips << i18nc("@info:tooltip", "Calculate the brightness in nits against XYZ luminance.");
+ toolTips << i18nc("@info:tooltip", "Calculate the brightness in nits by testing the components in linear rec 2020.");
+ toolTips << i18nc("@info:tooltip", "Calculate the brightness in nits by testing the components in linear RGB, if possible, falls back to using XYZ luminance.");
+
+ return {values, static_cast<int>(type), enabled, toolTips};
+}
+
+auto multiplyByReferenceWhite = [](double referenceWhite){
+ return lager::lenses::getset(
+ [referenceWhite] (const double &value) -> double {
+ return value * referenceWhite;
+ },
+ [referenceWhite] (double value, const double &newValue) {
+ value = referenceWhite > 0? newValue/referenceWhite: 0.0;
+ return value;
+ }
+ );
+};
+
+auto colorimetryXcoord = []() {
+ return lager::lenses::getset(
+ [] (const KoColorimetryUtils::xy &value) -> double {
+ return value.x;
+ },
+ [] (KoColorimetryUtils::xy value, const double &val) {
+ value.x = val;
+ return value;
+ }
+ );
+};
+
+auto colorimetryYcoord = []() {
+ return lager::lenses::getset(
+ [] (const KoColorimetryUtils::xy &value) -> double {
+ return value.y;
+ },
+ [] (KoColorimetryUtils::xy value, const double &val) {
+ value.y = val;
+ return value;
+ }
+ );
+};
+
+}
+
+using KisWidgetConnectionUtils::ToSpinBoxState;
+using KisWidgetConnectionUtils::ToControlState;
+
+KisHDRMetadataModel::KisHDRMetadataModel(QObject *parent)
+ : QObject{parent}
+ , clliData(lager::make_state(KisRelativeContentLightLevelInformation(), lager::automatic_tag{}))
+ , cviData(lager::make_state(KisColorVolumeInformation(), lager::automatic_tag{}))
+ , referenceWhiteData(lager::make_state(203.0, lager::automatic_tag{}))
+ , imageProfileRelative(lager::make_state(false, lager::automatic_tag{}))
+ , referenceWhiteEnabledData(lager::make_state(false, lager::automatic_tag{}))
+ , clliEnabledData(lager::make_state(false, lager::automatic_tag{}))
+ , cviEnabledData(lager::make_state(false, lager::automatic_tag{}))
+ , LAGER_QT(refWhiteEnabled){lager::with(referenceWhiteEnabledData)}
+ , LAGER_QT(refWhiteEnabledState){lager::with(LAGER_QT(refWhiteEnabled), lager::make_constant(true)).map(ToControlState{})}
+ , LAGER_QT(referenceWhite) {referenceWhiteData}
+ , LAGER_QT(clliEnabled){lager::with(clliEnabledData)}
+ , LAGER_QT(clliEnabledState){lager::with(LAGER_QT(clliEnabled), lager::make_constant(true)).map(ToControlState{})}
+ , LAGER_QT(maxContentLightLevel) {clliData[&KisRelativeContentLightLevelInformation::maxContentLightLevel].zoom(multiplyByReferenceWhite(LAGER_QT(referenceWhite).get()))}
+ , LAGER_QT(maxContentLightLevelState) {lager::with(LAGER_QT(maxContentLightLevel),
+ lager::make_constant(0.0),
+ lager::make_constant(100000.0),
+ LAGER_QT(clliEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(maxFrameAverageLightLevel) {clliData[&KisRelativeContentLightLevelInformation::maxFrameAverageLightLevel].zoom(multiplyByReferenceWhite(LAGER_QT(referenceWhite).get()))}
+ , LAGER_QT(maxFrameAverageLightLevelState) {lager::with(LAGER_QT(maxFrameAverageLightLevel),
+ lager::make_constant(0.0),
+ lager::make_constant(100000.0),
+ LAGER_QT(clliEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(clliCalculationType) {clliData[&KisRelativeContentLightLevelInformation::type]}
+ , LAGER_QT(clliCalculationTypeState) {lager::with(LAGER_QT(clliCalculationType), LAGER_QT(clliEnabled)).map(&calcTypeComboBoxState)}
+ , LAGER_QT(cviEnabled){lager::with(cviEnabledData)}
+ , LAGER_QT(cviEnabledState){lager::with(LAGER_QT(cviEnabled), lager::make_constant(true)).map(ToControlState{})}
+ , LAGER_QT(cviWhiteX){cviData[&KisColorVolumeInformation::white].zoom(colorimetryXcoord())}
+ , LAGER_QT(cviWhiteY){cviData[&KisColorVolumeInformation::white].zoom(colorimetryYcoord())}
+ , LAGER_QT(cviWhiteXState){lager::with(LAGER_QT(cviWhiteX),
+ lager::make_constant(0.0),
+ lager::make_constant(1.0),
+ LAGER_QT(cviEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(cviWhiteYState){lager::with(LAGER_QT(cviWhiteY),
+ lager::make_constant(0.0),
+ lager::make_constant(1.0),
+ LAGER_QT(cviEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(cviRedX){cviData[&KisColorVolumeInformation::red].zoom(colorimetryXcoord())}
+ , LAGER_QT(cviRedY){cviData[&KisColorVolumeInformation::red].zoom(colorimetryYcoord())}
+ , LAGER_QT(cviRedXState){lager::with(LAGER_QT(cviRedX),
+ lager::make_constant(0.0),
+ lager::make_constant(1.0),
+ LAGER_QT(cviEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(cviRedYState){lager::with(LAGER_QT(cviRedY),
+ lager::make_constant(0.0),
+ lager::make_constant(1.0),
+ LAGER_QT(cviEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(cviGreenX){cviData[&KisColorVolumeInformation::green].zoom(colorimetryXcoord())}
+ , LAGER_QT(cviGreenY){cviData[&KisColorVolumeInformation::green].zoom(colorimetryYcoord())}
+ , LAGER_QT(cviGreenXState){lager::with(LAGER_QT(cviGreenX),
+ lager::make_constant(0.0),
+ lager::make_constant(1.0),
+ LAGER_QT(cviEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(cviGreenYState){lager::with(LAGER_QT(cviGreenY),
+ lager::make_constant(0.0),
+ lager::make_constant(1.0),
+ LAGER_QT(cviEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(cviBlueX){cviData[&KisColorVolumeInformation::blue].zoom(colorimetryXcoord())}
+ , LAGER_QT(cviBlueY){cviData[&KisColorVolumeInformation::blue].zoom(colorimetryYcoord())}
+ , LAGER_QT(cviBlueXState){lager::with(LAGER_QT(cviBlueX),
+ lager::make_constant(0.0),
+ lager::make_constant(1.0),
+ LAGER_QT(cviEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(cviBlueYState){lager::with(LAGER_QT(cviBlueY),
+ lager::make_constant(0.0),
+ lager::make_constant(1.0),
+ LAGER_QT(cviEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(cviMaxLuminance){cviData[&KisColorVolumeInformation::maxLuminance]}
+ , LAGER_QT(cviMaxLuminanceState){lager::with(LAGER_QT(cviMaxLuminance),
+ lager::make_constant(0.0),
+ lager::make_constant(10000.0),
+ LAGER_QT(cviEnabled)).map(ToSpinBoxState{})}
+ , LAGER_QT(cviMinLuminance){cviData[&KisColorVolumeInformation::minLuminance]}
+ , LAGER_QT(cviMinLuminanceState){lager::with(LAGER_QT(cviMinLuminance),
+ lager::make_constant(0.0),
+ lager::make_constant(10000.0),
+ LAGER_QT(cviEnabled)).map(ToSpinBoxState{})}
+
+{
+
+}
+
+KisHDRMetadataModel::~KisHDRMetadataModel() {
+
+}
+
+void KisHDRMetadataModel::setClli(const std::optional<KisRelativeContentLightLevelInformation> &clli)
+{
+ if (clli) {
+ clliEnabledData.set(true);
+ clliData.set(*clli);
+ } else {
+ clliEnabledData.set(false);
+ }
+}
+
+std::optional<KisRelativeContentLightLevelInformation> KisHDRMetadataModel::clli() const
+{
+ const bool enabled = clliEnabledData.get();
+ if (enabled) {
+ return std::make_optional(clliData.get());
+ }
+ return std::nullopt;
+}
+
+void KisHDRMetadataModel::setCvi(const std::optional<KisColorVolumeInformation> &cvi)
+{
+ if (cvi) {
+ cviEnabledData.set(true);
+ cviData.set(*cvi);
+ } else {
+ cviEnabledData.set(false);
+ }
+}
+
+std::optional<KisColorVolumeInformation> KisHDRMetadataModel::cvi() const
+{
+ const bool enabled = cviEnabledData.get();
+ if (enabled) {
+ return std::make_optional(cviData.get());
+ }
+ return std::nullopt;
+}
+
+void KisHDRMetadataModel::setRefWhite(const std::optional<double> &refWhite)
+{
+ if (refWhite) {
+ referenceWhiteEnabledData.set(true);
+ referenceWhiteData.set(*refWhite);
+ } else {
+ referenceWhiteEnabledData.set(false);
+ }
+}
+
+std::optional<double> KisHDRMetadataModel::refWhite() const
+{
+ const bool enabled = referenceWhiteEnabledData.get();
+ if (enabled) {
+ return std::make_optional(referenceWhiteData.get());
+ }
+ return std::nullopt;
+}
+
+void KisHDRMetadataModel::setImageProfileRelative(const std::optional<double> &refWhite)
+{
+ if (refWhite) {
+ imageProfileRelative.set(false);
+ referenceWhiteData.set(*refWhite);
+ } else {
+ imageProfileRelative.set(true);
+ }
+}
diff --git a/libs/image/kis_hdr_metadata_models.h b/libs/image/kis_hdr_metadata_models.h
new file mode 100644
index 00000000000..5661c5a5c10
--- /dev/null
+++ b/libs/image/kis_hdr_metadata_models.h
@@ -0,0 +1,83 @@
+/*
+ * SPDX-FileCopyrightText: 2026 Wolthera van Hövell tot Westerflier <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef KIS_HDR_METADATA_MODELS_H
+#define KIS_HDR_METADATA_MODELS_H
+
+#include <QObject>
+
+#include <lager/cursor.hpp>
+#include <lager/extra/qt.hpp>
+#include <lager/state.hpp>
+
+#include <KisWidgetConnectionUtils.h>
+#include <kis_hdr_metadata.h>
+
+#include "kritaimage_export.h"
+
+class KRITAIMAGE_EXPORT KisHDRMetadataModel : public QObject
+{
+ Q_OBJECT
+public:
+ explicit KisHDRMetadataModel(QObject *parent = nullptr);
+ ~KisHDRMetadataModel();
+
+ lager::cursor<KisRelativeContentLightLevelInformation> clliData;
+ lager::cursor<KisColorVolumeInformation> cviData;
+ lager::cursor<double> referenceWhiteData;
+ lager::cursor<bool> imageProfileRelative;
+ lager::cursor<bool> referenceWhiteEnabledData;
+ lager::cursor<bool> clliEnabledData;
+ lager::cursor<bool> cviEnabledData;
+
+ LAGER_QT_CURSOR(bool, refWhiteEnabled);
+ LAGER_QT_READER(CheckBoxState, refWhiteEnabledState);
+ LAGER_QT_CURSOR(double, referenceWhite);
+
+ LAGER_QT_CURSOR(bool, clliEnabled);
+ LAGER_QT_READER(CheckBoxState, clliEnabledState);
+ LAGER_QT_CURSOR(double, maxContentLightLevel);
+ LAGER_QT_READER(DoubleSpinBoxState, maxContentLightLevelState);
+ LAGER_QT_CURSOR(double, maxFrameAverageLightLevel);
+ LAGER_QT_READER(DoubleSpinBoxState, maxFrameAverageLightLevelState);
+ LAGER_QT_CURSOR(KisRelativeContentLightLevelInformation::CalculationType, clliCalculationType);
+ LAGER_QT_READER(ComboBoxState, clliCalculationTypeState);
+
+ LAGER_QT_CURSOR(bool, cviEnabled);
+ LAGER_QT_READER(CheckBoxState, cviEnabledState);
+ LAGER_QT_CURSOR(double, cviWhiteX);
+ LAGER_QT_CURSOR(double, cviWhiteY);
+ LAGER_QT_READER(DoubleSpinBoxState, cviWhiteXState);
+ LAGER_QT_READER(DoubleSpinBoxState, cviWhiteYState);
+ LAGER_QT_CURSOR(double, cviRedX);
+ LAGER_QT_CURSOR(double, cviRedY);
+ LAGER_QT_READER(DoubleSpinBoxState, cviRedXState);
+ LAGER_QT_READER(DoubleSpinBoxState, cviRedYState);
+ LAGER_QT_CURSOR(double, cviGreenX);
+ LAGER_QT_CURSOR(double, cviGreenY);
+ LAGER_QT_READER(DoubleSpinBoxState, cviGreenXState);
+ LAGER_QT_READER(DoubleSpinBoxState, cviGreenYState);
+ LAGER_QT_CURSOR(double, cviBlueX);
+ LAGER_QT_CURSOR(double, cviBlueY);
+ LAGER_QT_READER(DoubleSpinBoxState, cviBlueXState);
+ LAGER_QT_READER(DoubleSpinBoxState, cviBlueYState);
+
+ LAGER_QT_CURSOR(double, cviMaxLuminance);
+ LAGER_QT_READER(DoubleSpinBoxState, cviMaxLuminanceState);
+ LAGER_QT_CURSOR(double, cviMinLuminance);
+ LAGER_QT_READER(DoubleSpinBoxState, cviMinLuminanceState);
+
+
+ void setClli(const std::optional<KisRelativeContentLightLevelInformation> &clli);
+ std::optional<KisRelativeContentLightLevelInformation> clli() const;
+ void setCvi(const std::optional<KisColorVolumeInformation> &cvi);
+ std::optional<KisColorVolumeInformation> cvi() const;
+ void setRefWhite(const std::optional<double> &refWhite);
+ std::optional<double> refWhite() const;
+ void setImageProfileRelative(const std::optional<double> &refWhite);
+
+};
+
+#endif // KIS_HDR_METADATA_MODELS_H
diff --git a/libs/ui/animation/KisHDRMetadataOptions.cpp b/libs/ui/animation/KisHDRMetadataOptions.cpp
index a3fd7fe53a6..fd629b2fa4a 100644
--- a/libs/ui/animation/KisHDRMetadataOptions.cpp
+++ b/libs/ui/animation/KisHDRMetadataOptions.cpp
@@ -20,17 +20,17 @@ KisPropertiesConfigurationSP KisHDRMetadataOptions::toProperties() const
config->setProperty("predefinedMasterDisplayId", predefinedMasterDisplayId);
- config->setProperty("redX", cvi.red.x());
- config->setProperty("redY", cvi.red.y());
+ config->setProperty("redX", cvi.red.x);
+ config->setProperty("redY", cvi.red.y);
- config->setProperty("greenX", cvi.green.x());
- config->setProperty("greenY", cvi.green.y());
+ config->setProperty("greenX", cvi.green.x);
+ config->setProperty("greenY", cvi.green.y);
- config->setProperty("blueX", cvi.blue.x());
- config->setProperty("blueY", cvi.blue.y());
+ config->setProperty("blueX", cvi.blue.x);
+ config->setProperty("blueY", cvi.blue.y);
- config->setProperty("whiteX", cvi.white.x());
- config->setProperty("whiteY", cvi.white.y());
+ config->setProperty("whiteX", cvi.white.x);
+ config->setProperty("whiteY", cvi.white.y);
config->setProperty("minLuminance", cvi.maxLuminance);
config->setProperty("maxLuminance", cvi.minLuminance);
@@ -45,17 +45,17 @@ void KisHDRMetadataOptions::fromProperties(KisPropertiesConfigurationSP config)
{
predefinedMasterDisplayId = config->getPropertyLazy("predefinedMasterDisplayId", predefinedMasterDisplayId);
- cvi.red.setX(config->getPropertyLazy("redX", cvi.red.x()));
- cvi.red.setY(config->getPropertyLazy("redX", cvi.red.y()));
+ cvi.red.x = config->getPropertyLazy("redX", cvi.red.x);
+ cvi.red.y = config->getPropertyLazy("redX", cvi.red.y);
- cvi.green.setX(config->getPropertyLazy("greenX", cvi.green.x()));
- cvi.green.setY(config->getPropertyLazy("greenY", cvi.green.y()));
+ cvi.green.x = (config->getPropertyLazy("greenX", cvi.green.x));
+ cvi.green.y = (config->getPropertyLazy("greenY", cvi.green.y));
- cvi.blue.setX(config->getPropertyLazy("blueX", cvi.blue.x()));
- cvi.blue.setY(config->getPropertyLazy("blueY", cvi.blue.y()));
+ cvi.blue.x = (config->getPropertyLazy("blueX", cvi.blue.x));
+ cvi.blue.y = (config->getPropertyLazy("blueY", cvi.blue.y));
- cvi.white.setX(config->getPropertyLazy("whiteX", cvi.white.x()));
- cvi.white.setY(config->getPropertyLazy("whiteY", cvi.white.y()));
+ cvi.white.x = (config->getPropertyLazy("whiteX", cvi.white.x));
+ cvi.white.y = (config->getPropertyLazy("whiteY", cvi.white.y));
cvi.minLuminance = config->getPropertyLazy("minLuminance", cvi.minLuminance);
cvi.maxLuminance = config->getPropertyLazy("maxLuminance", cvi.maxLuminance);
@@ -73,10 +73,11 @@ QString KisHDRMetadataOptions::generateFFMpegOptions() const
QString("-x265-params ");
if (cvi != KisColorVolumeInformation()) {
- x265Params += QString("master-display=G(%3,%4)B(%5,%6)R(%1,%2)WP(%7,%8)L(%9,%10):") .arg(cprim(cvi.red.x())).arg(cprim(cvi.red.y()))
- .arg(cprim(cvi.green.x())).arg(cprim(cvi.green.y()))
- .arg(cprim(cvi.blue.x())).arg(cprim(cvi.blue.y()))
- .arg(cprim(cvi.white.x())).arg(cprim(cvi.white.y()))
+ x265Params += QString("master-display=G(%3,%4)B(%5,%6)R(%1,%2)WP(%7,%8)L(%9,%10):")
+ .arg(cprim(cvi.red.x)).arg(cprim(cvi.red.y))
+ .arg(cprim(cvi.green.x)).arg(cprim(cvi.green.y))
+ .arg(cprim(cvi.blue.x)).arg(cprim(cvi.blue.y))
+ .arg(cprim(cvi.white.x)).arg(cprim(cvi.white.y))
.arg(lum(cvi.maxLuminance)).arg(lum(cvi.minLuminance));
}
if (clli != KisRelativeContentLightLevelInformation()) {
diff --git a/libs/ui/dialogs/kis_dlg_image_properties.cc b/libs/ui/dialogs/kis_dlg_image_properties.cc
index 76657799144..3d2e2e5f05d 100644
--- a/libs/ui/dialogs/kis_dlg_image_properties.cc
+++ b/libs/ui/dialogs/kis_dlg_image_properties.cc
@@ -20,6 +20,7 @@
#include <kis_signal_compressor.h>
#include <kis_image_config.h>
#include "kis_hdr_metadata.h"
+#include <kis_hdr_metadata_models.h>
#include "kis_layer_utils.h"
#include <kis_display_color_converter.h>
#include <KisWidgetConnectionUtils.h>
@@ -53,6 +54,7 @@ struct KisDlgImageProperties::Private {
KisSignalCompressor compressor ;
KisDisplayColorConverter *colorConverter;
KisSignalCompressor colorVolumeCompressor;
+ KisHDRMetadataModel hdrMetadataModel;
};
KisDlgImageProperties::KisDlgImageProperties(KisImageWSP image, KisDisplayColorConverter *colorConverter, QWidget *parent, const char *name)
@@ -125,8 +127,9 @@ KisDlgImageProperties::KisDlgImageProperties(KisImageWSP image, KisDisplayColorC
this,
&KisDlgImageProperties::setProofingConfigToImage);
- updateHDRLightLevels();
- updateHDRColorVolume();
+ d->hdrMetadataModel.setClli(d->image->relativeContentLightLevelInformation());
+ d->hdrMetadataModel.setCvi(d->image->colorVolumeInformation());
+ d->hdrMetadataModel.setRefWhite(d->image->diffuseWhiteLightLevel());
connect(m_page->btnCalculateClli, &QPushButton::clicked, this, &KisDlgImageProperties::slotCalculateLightLevels);
connect(d->image, &KisImage::sigContentLightLevelInformationChanged, this, &KisDlgImageProperties::updateHDRLightLevels);
connect(d->image, &KisImage::sigDiffuseWhiteLightLevelChanged, this, &KisDlgImageProperties::updateHDRDiffuseWhite);
@@ -135,37 +138,30 @@ KisDlgImageProperties::KisDlgImageProperties(KisImageWSP image, KisDisplayColorC
m_page->cmbDiffuseWhite->addItem(i18n("80 cd/m²"), 80.0);
m_page->cmbDiffuseWhite->addItem(i18n("203 cd/m²"), 203.0);
- connect(m_page->gbxDiffuseWhite, &QGroupBox::clicked, this, &KisDlgImageProperties::setHDRDiffuseWhiteOnImage);
- connect(m_page->cmbDiffuseWhite, SIGNAL(activated(int)), this, SLOT(setHDRDiffuseWhiteOnImage()));
-
- connect(m_page->gbxContentLightLevel, &QGroupBox::clicked, this, &KisDlgImageProperties::setHDRLightLevelsOnImage);
- connect(m_page->spnMaxCll, &QDoubleSpinBox::valueChanged, this, &KisDlgImageProperties::setHDRLightLevelsOnImage);
- connect(m_page->spnMaxFall, &QDoubleSpinBox::valueChanged, this, &KisDlgImageProperties::setHDRLightLevelsOnImage);
-
m_page->cmbColorVolumePresets->addItem(i18n("Rec. 2100 PQ"), "p2100-pq");
m_page->cmbColorVolumePresets->addItem(i18n("DCI-P3 D65"), "dci-p3-d65");
- m_page->cmbLumiCalcType->addItem(i18n("XYZ Luminance"), KisRelativeContentLightLevelInformation::XYZLuminance);
- m_page->cmbLumiCalcType->addItem(i18n("Rec 2020 Per Component"), KisRelativeContentLightLevelInformation::Rec2020Component);
- m_page->cmbLumiCalcType->addItem(i18n("RGB Per Component"), KisRelativeContentLightLevelInformation::RGBComponent);
- m_page->cmbLumiCalcType->setItemData(0, i18nc("@tooltip", "Calculate the brightness in nits against XYZ luminance."), Qt::ToolTipRole);
- m_page->cmbLumiCalcType->setItemData(1, i18nc("@tooltip", "Calculate the brightness in nits by testing the components in linear rec 2020."), Qt::ToolTipRole);
- m_page->cmbLumiCalcType->setItemData(2, i18nc("@tooltip", "Calculate the brightness in nits by testing the components in linear RGB, if possible, falls back to using XYZ luminance."), Qt::ToolTipRole);
+ connect(m_page->gbxDiffuseWhite, &QGroupBox::clicked, this, &KisDlgImageProperties::setHDRDiffuseWhiteOnImage);
+ connect(m_page->cmbDiffuseWhite, SIGNAL(activated(int)), this, SLOT(setHDRDiffuseWhiteOnImage()));
+ KisWidgetConnectionUtils::connectControlState( m_page->gbxContentLightLevel, &d->hdrMetadataModel, "clliEnabledState", "clliEnabled");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnMaxCll, &d->hdrMetadataModel, "maxContentLightLevelState", "maxContentLightLevel");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnMaxFall, &d->hdrMetadataModel, "maxFrameAverageLightLevelState", "maxFrameAverageLightLevel");
+ KisWidgetConnectionUtils::connectControlState( m_page->cmbLumiCalcType, &d->hdrMetadataModel, "clliCalculationTypeState", "clliCalculationType");
+
+ KisWidgetConnectionUtils::connectControlState( m_page->gbxColorVolume, &d->hdrMetadataModel, "cviEnabledState", "cviEnabled");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnWhiteX, &d->hdrMetadataModel, "cviWhiteXState", "cviWhiteX");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnWhiteY, &d->hdrMetadataModel, "cviWhiteYState", "cviWhiteY");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnRedX, &d->hdrMetadataModel, "cviRedXState", "cviRedX");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnRedY, &d->hdrMetadataModel, "cviRedYState", "cviRedY");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnGreenX, &d->hdrMetadataModel, "cviGreenXState", "cviGreenX");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnGreenY, &d->hdrMetadataModel, "cviGreenYState", "cviGreenY");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnBlueX, &d->hdrMetadataModel, "cviBlueXState", "cviBlueX");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnBlueY, &d->hdrMetadataModel, "cviBlueYState", "cviBlueY");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnMinLuminance, &d->hdrMetadataModel, "cviMinLuminanceState", "cviMinLuminance");
+ KisWidgetConnectionUtils::connectControlState( m_page->spnMaxLuminance, &d->hdrMetadataModel, "cviMaxLuminanceState", "cviMaxLuminance");
connect(m_page->cmbColorVolumePresets, SIGNAL(activated(int)), this, SLOT(changeColorVolumePreset()));
- connect(m_page->gbxColorVolume, &QGroupBox::clicked, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(m_page->spnWhiteX, &QDoubleSpinBox::valueChanged, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(m_page->spnWhiteY, &QDoubleSpinBox::valueChanged, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(m_page->spnRedX, &QDoubleSpinBox::valueChanged, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(m_page->spnRedY, &QDoubleSpinBox::valueChanged, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(m_page->spnGreenX, &QDoubleSpinBox::valueChanged, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(m_page->spnGreenY, &QDoubleSpinBox::valueChanged, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(m_page->spnBlueX, &QDoubleSpinBox::valueChanged, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(m_page->spnBlueX, &QDoubleSpinBox::valueChanged, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(m_page->spnMinLuminance, &QDoubleSpinBox::valueChanged, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(m_page->spnMaxLuminance, &QDoubleSpinBox::valueChanged, &d->colorVolumeCompressor, &KisSignalCompressor::start);
- connect(&d->colorVolumeCompressor, &KisSignalCompressor::timeout, this, &KisDlgImageProperties::setHDRColorVolumeOnImage);
const bool hdr = (d->image->colorSpace()->hasHighDynamicRange()
|| d->image->colorSpace()->profile()->getTransferCharacteristics() == TRC_ITU_R_BT_2100_0_PQ);
@@ -218,6 +214,9 @@ int KisDlgImageProperties::exec()
} else {
d->image->setProofingConfiguration(nullptr);
}
+ setHDRDiffuseWhiteOnImage();
+ setHDRLightLevelsOnImage();
+ setHDRColorVolumeOnImage();
} else {
d->image->setProofingConfiguration(d->originalProofingConfig);
}
@@ -261,71 +260,23 @@ void KisDlgImageProperties::updateDisplayConfigInfo()
void KisDlgImageProperties::updateHDRDiffuseWhite()
{
- if (d->image->diffuseWhiteLightLevel()) {
- m_page->gbxDiffuseWhite->setChecked(true);
- m_page->cmbDiffuseWhite->setCurrentIndex(m_page->cmbDiffuseWhite->findData(*d->image->diffuseWhiteLightLevel()));
- if (d->image->colorSpace()->profile()->hdrReferenceWhite()) {
- m_page->gbxDiffuseWhite->setEnabled(false);
- m_page->cmbDiffuseWhite->setEnabled(false);
- }
-
- } else {
- m_page->gbxDiffuseWhite->setChecked(false);
- m_page->cmbDiffuseWhite->setCurrentIndex(0);
- }
+ d->hdrMetadataModel.setRefWhite(d->image->diffuseWhiteLightLevel());
}
void KisDlgImageProperties::updateHDRLightLevels()
{
- if (d->image->relativeContentLightLevelInformation()) {
- m_page->gbxContentLightLevel->setChecked(true);
- double diffuseWhite = d->image->diffuseWhiteLightLevel()? *d->image->diffuseWhiteLightLevel(): 80.0;
- KisRelativeContentLightLevelInformation clli = *d->image->relativeContentLightLevelInformation();
- m_page->spnMaxCll->setValue(clli.maxContentLightLevel*diffuseWhite);
- m_page->spnMaxFall->setValue(clli.maxFrameAverageLightLevel*diffuseWhite);
- m_page->cmbLumiCalcType->setCurrentIndex(clli.type);
- } else {
- m_page->gbxContentLightLevel->setChecked(false);
- }
+ d->hdrMetadataModel.setClli(d->image->relativeContentLightLevelInformation());
}
void KisDlgImageProperties::updateHDRColorVolume()
{
- if (d->image->colorVolumeInformation()) {
- m_page->gbxColorVolume->setChecked(true);
- KisColorVolumeInformation cvi = *d->image->colorVolumeInformation();
- m_page->spnWhiteX->setValue(cvi.white.x());
- m_page->spnWhiteY->setValue(cvi.white.y());
-
- m_page->spnRedX->setValue(cvi.red.x());
- m_page->spnRedY->setValue(cvi.red.y());
-
- m_page->spnGreenX->setValue(cvi.green.x());
- m_page->spnGreenY->setValue(cvi.green.y());
-
- m_page->spnBlueX->setValue(cvi.blue.x());
- m_page->spnBlueY->setValue(cvi.blue.y());
-
- m_page->spnMaxLuminance->setValue(cvi.maxLuminance);
- m_page->spnMinLuminance->setValue(cvi.minLuminance);
-
- } else {
- m_page->gbxColorVolume->setChecked(false);
- }
+ d->hdrMetadataModel.setCvi(d->image->colorVolumeInformation());
}
void KisDlgImageProperties::setHDRLightLevelsOnImage()
{
- std::optional<KisRelativeContentLightLevelInformation> optClli = std::nullopt;
-
- if (m_page->gbxContentLightLevel->isChecked()) {
- double diffuseWhite = d->image->diffuseWhiteLightLevel().value_or(80.0);
- KisRelativeContentLightLevelInformation clli;
- clli.maxContentLightLevel = m_page->spnMaxCll->value() / diffuseWhite;
- clli.maxFrameAverageLightLevel = m_page->spnMaxFall->value() / diffuseWhite;
- clli.type = KisRelativeContentLightLevelInformation::CalculationType(m_page->cmbLumiCalcType->currentData().toInt());
- optClli = std::make_optional(clli);
- }
+ std::optional<KisRelativeContentLightLevelInformation> optClli = d->hdrMetadataModel.clli();
+
if (d->image->relativeContentLightLevelInformation() != optClli) {
KisProcessingApplicator::runSingleCommandStroke(d->image,
new KisChangeImageHdrContentLightLevelCommand(d->image, optClli));
@@ -334,10 +285,7 @@ void KisDlgImageProperties::setHDRLightLevelsOnImage()
void KisDlgImageProperties::setHDRDiffuseWhiteOnImage()
{
- std::optional<double> dw = std::nullopt;
- if (m_page->gbxDiffuseWhite->isChecked()) {
- dw = std::make_optional(m_page->cmbDiffuseWhite->currentData().toDouble());
- }
+ std::optional<double> dw = d->hdrMetadataModel.refWhite();
if (d->image->diffuseWhiteLightLevel() != dw) {
KUndo2Command *cmd = new KisChangeImageHdrDiffuseWhiteCommand(d->image, dw);
d->image->undoAdapter()->addCommand(cmd);
@@ -346,22 +294,7 @@ void KisDlgImageProperties::setHDRDiffuseWhiteOnImage()
void KisDlgImageProperties::setHDRColorVolumeOnImage()
{
- std::optional<KisColorVolumeInformation> optCvi = std::nullopt;
- if (m_page->gbxColorVolume->isChecked()) {
- KisColorVolumeInformation cvi;
-
- cvi.white = QPointF(m_page->spnWhiteX->value(), m_page->spnWhiteY->value());
-
- cvi.red = QPointF(m_page->spnRedX->value(), m_page->spnRedY->value());
- cvi.green = QPointF(m_page->spnGreenX->value(), m_page->spnGreenY->value());
- cvi.blue = QPointF(m_page->spnBlueX->value(), m_page->spnBlueY->value());
-
- cvi.maxLuminance = m_page->spnMaxLuminance->value();
- cvi.minLuminance = m_page->spnMinLuminance->value();
-
- optCvi = std::make_optional(cvi);
-
- }
+ std::optional<KisColorVolumeInformation> optCvi = d->hdrMetadataModel.cvi();
if (d->image->colorVolumeInformation() != optCvi) {
KUndo2Command *cmd = new KisChangeImageHdrColorVolumeCommand(d->image, optCvi);
d->image->undoAdapter()->addCommand(cmd);
@@ -411,7 +344,7 @@ void KisDlgImageProperties::changeColorVolumePreset()
void KisDlgImageProperties::slotCalculateLightLevels()
{
- KisRelativeContentLightLevelInformation::CalculationType type = KisRelativeContentLightLevelInformation::CalculationType(m_page->cmbLumiCalcType->currentData().toInt());
+ KisRelativeContentLightLevelInformation::CalculationType type = d->hdrMetadataModel.clliCalculationType();
KisSharedPtr<KisContentLightLevelProcessingVistor> visitor =
new KisContentLightLevelProcessingVistor(type, d->image->bounds());
@@ -426,12 +359,10 @@ void KisDlgImageProperties::slotCalculateLightLevels()
// has completed its execution
QSharedPointer<FunctionToSignalProxy> completionSignalProxy(new FunctionToSignalProxy);
connect(completionSignalProxy.get(), &FunctionToSignalProxy::timeout, this,
- [visitor, image = d->image]() {
+ [visitor, model = &d->hdrMetadataModel, image = d->image]() {
auto info = visitor->contentLightLevelInformation();
- if (info != image->relativeContentLightLevelInformation()) {
- KisProcessingApplicator::runSingleCommandStroke(image,
- new KisChangeImageHdrContentLightLevelCommand(image, info));
- }
+
+ model->setClli(info);
});
// add the command **after** the signal has been set up; this
diff --git a/libs/widgets/KisWidgetConnectionUtils.cpp b/libs/widgets/KisWidgetConnectionUtils.cpp
index 0a2c16b5103..28d4c8036f9 100644
--- a/libs/widgets/KisWidgetConnectionUtils.cpp
+++ b/libs/widgets/KisWidgetConnectionUtils.cpp
@@ -17,6 +17,7 @@
#include <QLineEdit>
#include <QSlider>
#include <QCheckBox>
+#include <QGroupBox>
#include "kis_debug.h"
#include "kis_spacing_selection_widget.h"
#include "kis_multipliers_double_slider_spinbox.h"
@@ -63,6 +64,29 @@ private:
QAbstractButton *m_button;
};
+class ConnectGroupBoxStateHelper : public QObject
+{
+ Q_OBJECT
+public:
+
+ ConnectGroupBoxStateHelper(QGroupBox *parent)
+ : QObject(parent),
+ m_button(parent)
+ {
+ }
+public Q_SLOTS:
+ void updateState(const CheckBoxState &state) {
+ QSignalBlocker b(m_button);
+ m_button->setEnabled(state.enabled);
+ m_button->setChecked(state.value);
+
+ // TODO: verify if the two properties are equal or the control is disabled
+ }
+
+private:
+ QGroupBox *m_button;
+};
+
class ConnectComboBoxStateHelper : public QObject
{
Q_OBJECT
@@ -494,6 +518,37 @@ void connectControlState(QAbstractButton *button, QObject *source, const char *r
}
}
+void connectControlState(QGroupBox *button, QObject *source, const char *readStatePropertyName, const char *writePropertyName)
+{
+ const QMetaObject* meta = source->metaObject();
+ QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStatePropertyName));
+ SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
+
+ KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
+
+ QMetaMethod signal = readStateProp.notifySignal();
+
+ KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
+ KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("CheckBoxState"));
+
+ ConnectGroupBoxStateHelper *helper = new ConnectGroupBoxStateHelper(button);
+
+ const QMetaObject* dstMeta = helper->metaObject();
+
+ QMetaMethod updateSlot = dstMeta->method(
+ dstMeta->indexOfSlot("updateState(CheckBoxState)"));
+ QObject::connect(source, signal, helper, updateSlot);
+
+ helper->updateState(readStateProp.read(source).value<CheckBoxState>());
+
+ QMetaProperty writeProp = meta->property(meta->indexOfProperty(writePropertyName));
+ SANITY_CHECK_PROPERTY_EXISTS_AND_WRITABLE(writeProp);
+ if (writeProp.isWritable()) {
+ button->connect(button, &QGroupBox::toggled,
+ source, [writeProp, source] (bool value) { writeProp.write(source, value); });
+ }
+}
+
void connectControlState(QComboBox *button, QObject *source, const char *readStatePropertyName, const char *writePropertyName)
{
diff --git a/libs/widgets/KisWidgetConnectionUtils.h b/libs/widgets/KisWidgetConnectionUtils.h
index 0060140d511..b2113a75717 100644
--- a/libs/widgets/KisWidgetConnectionUtils.h
+++ b/libs/widgets/KisWidgetConnectionUtils.h
@@ -21,6 +21,7 @@ class QDoubleSpinBox;
class QObject;
class QSlider;
class QCheckBox;
+class QGroupBox;
class KisSpacingSelectionWidget;
class KisAngleSelector;
class KisColorButton;
@@ -148,6 +149,7 @@ void KRITAWIDGETS_EXPORT connectControl(QButtonGroup *button, QObject *source, c
void KRITAWIDGETS_EXPORT connectControl(QComboBox *button, QObject *source, const char *property);
void KRITAWIDGETS_EXPORT connectControl(QComboBox *button, QObject *source, const char *property);
void KRITAWIDGETS_EXPORT connectControlState(QAbstractButton *button, QObject *source, const char *readStateProperty, const char *writeProperty);
+void KRITAWIDGETS_EXPORT connectControlState(QGroupBox *button, QObject *source, const char *readStateProperty, const char *writeProperty);
void KRITAWIDGETS_EXPORT connectControlState(QButtonGroup *group, QObject *source, const char *readStateProperty, const char *writeProperty);
void KRITAWIDGETS_EXPORT connectControlState(QComboBox *button, QObject *source, const char *readStateProperty, const char *writeProperty);
void KRITAWIDGETS_EXPORT connectControl(KisSpacingSelectionWidget *widget, QObject *source, const char *property);
diff --git a/plugins/impex/libkra/kis_kra_loader.cpp b/plugins/impex/libkra/kis_kra_loader.cpp
index 43a73fa111c..43a90255737 100644
--- a/plugins/impex/libkra/kis_kra_loader.cpp
+++ b/plugins/impex/libkra/kis_kra_loader.cpp
@@ -1559,8 +1559,8 @@ void KisKraLoader::loadHDRMetadata(const QDomElement &elem, KisImageSP image)
}
if (child.tagName() == CONTENTLIGHTLEVEL) {
KisRelativeContentLightLevelInformation clli;
- clli.maxContentLightLevel = child.attribute(MAXCLL, "0.0").toDouble();
- clli.maxFrameAverageLightLevel = child.attribute(MAXFALL, "0.0").toDouble();
+ clli.maxContentLightLevel = KisDomUtils::toDouble(child.attribute(MAXCLL, "0.0"));
+ clli.maxFrameAverageLightLevel = KisDomUtils::toDouble(child.attribute(MAXFALL, "0.0"));
const QString type = child.attribute(CLLI_CALCTYPE);
if (type == CLLI_CALC_RGB_XYZ_FALLBACK) {
clli.type = KisRelativeContentLightLevelInformation::RGBComponent;
@@ -1574,17 +1574,32 @@ void KisKraLoader::loadHDRMetadata(const QDomElement &elem, KisImageSP image)
}
if (child.tagName() == COLORVOLUME) {
KisColorVolumeInformation cv;
- cv.maxLuminance = child.attribute(COLORVOLUMEMAXLUMINANCE, "0.0").toDouble();
- cv.minLuminance = child.attribute(COLORVOLUMEMINLUMINANCE, "0.0").toDouble();
+ //TODO: Kisdomutils!!!
+ cv.maxLuminance = KisDomUtils::toDouble(child.attribute(COLORVOLUMEMAXLUMINANCE, "0.0"));
+ cv.minLuminance = KisDomUtils::toDouble(child.attribute(COLORVOLUMEMINLUMINANCE, "0.0"));
QDomElement red = child.firstChildElement(COLORVOLUMERED);
QDomElement green = child.firstChildElement(COLORVOLUMEGREEN);
QDomElement blue = child.firstChildElement(COLORVOLUMEBLUE);
QDomElement white = child.firstChildElement(COLORVOLUMEWHITE);
- KisDomUtils::loadValue(red, &cv.red);
- KisDomUtils::loadValue(green, &cv.green);
- KisDomUtils::loadValue(blue, &cv.blue);
- KisDomUtils::loadValue(white, &cv.white);
+
+ QPointF temp;
+ if (KisDomUtils::loadValue(red, &temp)) {
+ cv.red.x = temp.x();
+ cv.red.y = temp.y();
+ }
+ if (KisDomUtils::loadValue(green, &temp)) {
+ cv.green.x = temp.x();
+ cv.green.y = temp.y();
+ }
+ if (KisDomUtils::loadValue(blue, &temp)) {
+ cv.blue.x = temp.x();
+ cv.blue.y = temp.y();
+ }
+ if (KisDomUtils::loadValue(white, &temp)) {
+ cv.white.x = temp.x();
+ cv.white.y = temp.y();
+ }
std::optional<KisColorVolumeInformation> cvi = std::make_optional(cv);
image->setColorVolumeInformation(cvi);
}
diff --git a/plugins/impex/libkra/kis_kra_saver.cpp b/plugins/impex/libkra/kis_kra_saver.cpp
index eccd099e00a..98d8bb45d65 100644
--- a/plugins/impex/libkra/kis_kra_saver.cpp
+++ b/plugins/impex/libkra/kis_kra_saver.cpp
@@ -732,10 +732,10 @@ void KisKraSaver::saveHDRMetadata(QDomDocument &doc, QDomElement &element, KisIm
cvi.setAttribute(COLORVOLUMEMAXLUMINANCE, KisDomUtils::toString(cv.maxLuminance));
cvi.setAttribute(COLORVOLUMEMINLUMINANCE, KisDomUtils::toString(cv.minLuminance));
- KisDomUtils::saveValue(&cvi, COLORVOLUMERED, cv.red);
- KisDomUtils::saveValue(&cvi, COLORVOLUMEGREEN, cv.green);
- KisDomUtils::saveValue(&cvi, COLORVOLUMEBLUE, cv.blue);
- KisDomUtils::saveValue(&cvi, COLORVOLUMEWHITE, cv.white);
+ KisDomUtils::saveValue(&cvi, COLORVOLUMERED, cv.red.asVector().toPointF());
+ KisDomUtils::saveValue(&cvi, COLORVOLUMEGREEN, cv.green.asVector().toPointF());
+ KisDomUtils::saveValue(&cvi, COLORVOLUMEBLUE, cv.blue.asVector().toPointF());
+ KisDomUtils::saveValue(&cvi, COLORVOLUMEWHITE, cv.white.asVector().toPointF());
hdr.appendChild(cvi);
}