summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-04-22 16:22:10 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-05-31 22:23:40 +0200
commit567ffafe7fed4536359e8a6b925aaf4379d67b67 (patch)
treee3a4eafd243bd6ea909d9e83a27dffa3e5d2bbaa
parent5ea6da55e0d29a0dc526d4fa78a0590e0e4df8f6 (diff)
Add new map methods for QColorTransform
Change-Id: I520fc4f4bd958472c6d6359bf671835796c677fe Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
-rw-r--r--src/gui/painting/qcolortransform.cpp42
-rw-r--r--src/gui/painting/qcolortransform.h8
-rw-r--r--src/gui/painting/qrgbafloat.h8
-rw-r--r--tests/auto/gui/painting/qcolortransform/tst_qcolortransform.cpp93
4 files changed, 151 insertions, 0 deletions
diff --git a/src/gui/painting/qcolortransform.cpp b/src/gui/painting/qcolortransform.cpp
index 958d2fd2db..698696877b 100644
--- a/src/gui/painting/qcolortransform.cpp
+++ b/src/gui/painting/qcolortransform.cpp
@@ -223,6 +223,48 @@ QRgba64 QColorTransform::map(QRgba64 rgba64) const
}
/*!
+ Applies the color transformation on the QRgbaFloat16 value \a rgbafp16.
+
+ The input should be opaque or unpremultiplied.
+ \since 6.4
+*/
+QRgbaFloat16 QColorTransform::map(QRgbaFloat16 rgbafp16) const
+{
+ if (!d)
+ return rgbafp16;
+ QColorVector c;
+ c.x = d->colorSpaceIn->trc[0].applyExtended(rgbafp16.r);
+ c.y = d->colorSpaceIn->trc[1].applyExtended(rgbafp16.g);
+ c.z = d->colorSpaceIn->trc[2].applyExtended(rgbafp16.b);
+ c = d->colorMatrix.map(c);
+ rgbafp16.r = d->colorSpaceOut->trc[0].applyInverseExtended(c.x);
+ rgbafp16.g = d->colorSpaceOut->trc[1].applyInverseExtended(c.y);
+ rgbafp16.b = d->colorSpaceOut->trc[2].applyInverseExtended(c.z);
+ return rgbafp16;
+}
+
+/*!
+ Applies the color transformation on the QRgbaFloat32 value \a rgbafp32.
+
+ The input should be opaque or unpremultiplied.
+ \since 6.4
+*/
+QRgbaFloat32 QColorTransform::map(QRgbaFloat32 rgbafp32) const
+{
+ if (!d)
+ return rgbafp32;
+ QColorVector c;
+ c.x = d->colorSpaceIn->trc[0].applyExtended(rgbafp32.r);
+ c.y = d->colorSpaceIn->trc[1].applyExtended(rgbafp32.g);
+ c.z = d->colorSpaceIn->trc[2].applyExtended(rgbafp32.b);
+ c = d->colorMatrix.map(c);
+ rgbafp32.r = d->colorSpaceOut->trc[0].applyInverseExtended(c.x);
+ rgbafp32.g = d->colorSpaceOut->trc[1].applyInverseExtended(c.y);
+ rgbafp32.b = d->colorSpaceOut->trc[2].applyInverseExtended(c.z);
+ return rgbafp32;
+}
+
+/*!
Applies the color transformation on the QColor value \a color.
*/
diff --git a/src/gui/painting/qcolortransform.h b/src/gui/painting/qcolortransform.h
index 14673fe924..02f15ee89f 100644
--- a/src/gui/painting/qcolortransform.h
+++ b/src/gui/painting/qcolortransform.h
@@ -14,6 +14,12 @@ class QColor;
class QRgba64;
class QColorSpacePrivate;
class QColorTransformPrivate;
+class qfloat16;
+template<typename T>
+class QRgbaFloat;
+typedef QRgbaFloat<qfloat16> QRgbaFloat16;
+typedef QRgbaFloat<float> QRgbaFloat32;
+
QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QColorTransformPrivate, Q_GUI_EXPORT)
class QColorTransform
@@ -35,6 +41,8 @@ public:
Q_GUI_EXPORT QRgb map(QRgb argb) const;
Q_GUI_EXPORT QRgba64 map(QRgba64 rgba64) const;
+ Q_GUI_EXPORT QRgbaFloat16 map(QRgbaFloat16 rgbafp16) const;
+ Q_GUI_EXPORT QRgbaFloat32 map(QRgbaFloat32 rgbafp32) const;
Q_GUI_EXPORT QColor map(const QColor &color) const;
friend bool operator==(const QColorTransform &ct1, const QColorTransform &ct2)
diff --git a/src/gui/painting/qrgbafloat.h b/src/gui/painting/qrgbafloat.h
index 04b2115399..a7cd2d70d3 100644
--- a/src/gui/painting/qrgbafloat.h
+++ b/src/gui/painting/qrgbafloat.h
@@ -94,6 +94,14 @@ public:
const FastType ia = 1.0f / a;
return QRgbaFloat{r * ia, g * ia, b * ia, a};
}
+ constexpr bool operator==(QRgbaFloat f) const
+ {
+ return r == f.r && g == f.g && b == f.b && a == f.a;
+ }
+ constexpr bool operator!=(QRgbaFloat f) const
+ {
+ return !(*this == f);
+ }
};
typedef QRgbaFloat<qfloat16> QRgbaFloat16;
diff --git a/tests/auto/gui/painting/qcolortransform/tst_qcolortransform.cpp b/tests/auto/gui/painting/qcolortransform/tst_qcolortransform.cpp
index 17f115c308..6fbf7ddf27 100644
--- a/tests/auto/gui/painting/qcolortransform/tst_qcolortransform.cpp
+++ b/tests/auto/gui/painting/qcolortransform/tst_qcolortransform.cpp
@@ -31,6 +31,7 @@
#include <qcolorspace.h>
#include <qcolortransform.h>
+#include <qrgbafloat.h>
#include <QtGui/private/qcolortransform_p.h>
class tst_QColorTransform : public QObject
@@ -45,6 +46,10 @@ private slots:
void mapRGB32();
void mapRGB64_data();
void mapRGB64();
+ void mapRGBAFP16x4_data();
+ void mapRGBAFP16x4();
+ void mapRGBAFP32x4_data();
+ void mapRGBAFP32x4();
void mapQColor_data();
void mapQColor();
void mapRGB32Prepared_data();
@@ -182,6 +187,94 @@ void tst_QColorTransform::mapRGB64()
QCOMPARE(result.alpha(), 0xffff);
}
+void tst_QColorTransform::mapRGBAFP16x4_data()
+{
+ mapRGB32_data();
+}
+
+void tst_QColorTransform::mapRGBAFP16x4()
+{
+ QFETCH(QColorTransform, transform);
+ QFETCH(bool, sharesRed);
+
+ QRgbaFloat16 testColor = QRgbaFloat16::fromRgba(128, 64, 32, 255);
+ QRgbaFloat16 result = transform.map(testColor);
+ QVERIFY(result.red() > result.green());
+ QVERIFY(result.green() > result.blue());
+ QCOMPARE(result.alpha(), 1.0f);
+ if (transform.isIdentity())
+ QVERIFY(result == testColor);
+ else
+ QVERIFY(result != testColor);
+
+ testColor = QRgbaFloat16{0.0f, 0.0f, 0.0f, 1.0f};
+ result = transform.map(testColor);
+ QCOMPARE(result, testColor);
+
+ testColor = QRgbaFloat16{1.0f, 1.0f, 1.0f, 1.0f};
+ result = transform.map(testColor);
+ QCOMPARE(result, testColor);
+
+ testColor = QRgbaFloat16{1.0f, 1.0f, 0.0f, 1.0f};
+ result = transform.map(testColor);
+ QCOMPARE(result.alpha(), 1.0f);
+ if (sharesRed)
+ QCOMPARE(result.red(), 1.0f);
+
+ testColor = QRgbaFloat16{0.0f, 1.0f, 1.0f, 1.0f};
+ result = transform.map(testColor);
+ // QRgbaFloat16 might overflow blue if we convert to a smaller gamut:
+ QCOMPARE(result.blue16(), 65535);
+ QCOMPARE(result.alpha(), 1.0f);
+}
+
+void tst_QColorTransform::mapRGBAFP32x4_data()
+{
+ mapRGB32_data();
+}
+
+void tst_QColorTransform::mapRGBAFP32x4()
+{
+ QFETCH(QColorTransform, transform);
+ QFETCH(bool, sharesRed);
+
+ QRgbaFloat32 testColor = QRgbaFloat32::fromRgba(128, 64, 32, 255);
+ QRgbaFloat32 result = transform.map(testColor);
+ QVERIFY(result.red() > result.green());
+ QVERIFY(result.green() > result.blue());
+ QCOMPARE(result.alpha(), 1.0f);
+ if (transform.isIdentity())
+ QVERIFY(result == testColor);
+ else
+ QVERIFY(result != testColor);
+
+ testColor = QRgbaFloat32{0.0f, 0.0f, 0.0f, 1.0f};
+ result = transform.map(testColor);
+ QCOMPARE(result.red(), 0.0f);
+ QCOMPARE(result.green(), 0.0f);
+ QCOMPARE(result.blue(), 0.0f);
+ QCOMPARE(result.alpha(), 1.0f);
+
+ testColor = QRgbaFloat32{1.0f, 1.0f, 1.0f, 1.0f};
+ result = transform.map(testColor);
+ QCOMPARE(result.red(), 1.0f);
+ QCOMPARE(result.green(), 1.0f);
+ QCOMPARE(result.blue(), 1.0f);
+ QCOMPARE(result.alpha(), 1.0f);
+
+ testColor = QRgbaFloat32{1.0f, 1.0f, 0.0f, 1.0f};
+ result = transform.map(testColor);
+ QCOMPARE(result.alpha(), 1.0f);
+ if (sharesRed)
+ QCOMPARE(result.red(), 1.0f);
+
+ testColor = QRgbaFloat32{0.0f, 1.0f, 1.0f, 1.0f};
+ result = transform.map(testColor);
+ // QRgbaFloat16 might overflow blue if we convert to a smaller gamut:
+ QCOMPARE(result.blue16(), 65535);
+ QCOMPARE(result.alpha(), 1.0f);
+}
+
void tst_QColorTransform::mapQColor_data()
{
mapRGB32_data();