Test prepared qcolortransform

Add test of explicitly prepared qcolortransform, this is a state
a transform can get into if used for an image transform.

Also cleans up the test code.

Change-Id: I9445ed114bed0edc790e14024aaae6a42989220b
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
bb10
Allan Sandfeld Jensen 2022-05-31 14:43:07 +02:00
parent fb8a88b05c
commit 5ea6da55e0
4 changed files with 109 additions and 24 deletions

View File

@ -159,9 +159,15 @@ QRgb QColorTransform::map(QRgb argb) const
return argb;
constexpr float f = 1.0f / 255.0f;
QColorVector c = { qRed(argb) * f, qGreen(argb) * f, qBlue(argb) * f };
c.x = d->colorSpaceIn->trc[0].apply(c.x);
c.y = d->colorSpaceIn->trc[1].apply(c.y);
c.z = d->colorSpaceIn->trc[2].apply(c.z);
if (d->colorSpaceIn->lut.generated.loadAcquire()) {
c.x = d->colorSpaceIn->lut[0]->toLinear(c.x);
c.y = d->colorSpaceIn->lut[1]->toLinear(c.y);
c.z = d->colorSpaceIn->lut[2]->toLinear(c.z);
} else {
c.x = d->colorSpaceIn->trc[0].apply(c.x);
c.y = d->colorSpaceIn->trc[1].apply(c.y);
c.z = d->colorSpaceIn->trc[2].apply(c.z);
}
c = d->colorMatrix.map(c);
c.x = std::max(0.0f, std::min(1.0f, c.x));
c.y = std::max(0.0f, std::min(1.0f, c.y));
@ -190,9 +196,15 @@ QRgba64 QColorTransform::map(QRgba64 rgba64) const
return rgba64;
constexpr float f = 1.0f / 65535.0f;
QColorVector c = { rgba64.red() * f, rgba64.green() * f, rgba64.blue() * f };
c.x = d->colorSpaceIn->trc[0].apply(c.x);
c.y = d->colorSpaceIn->trc[1].apply(c.y);
c.z = d->colorSpaceIn->trc[2].apply(c.z);
if (d->colorSpaceIn->lut.generated.loadAcquire()) {
c.x = d->colorSpaceIn->lut[0]->toLinear(c.x);
c.y = d->colorSpaceIn->lut[1]->toLinear(c.y);
c.z = d->colorSpaceIn->lut[2]->toLinear(c.z);
} else {
c.x = d->colorSpaceIn->trc[0].apply(c.x);
c.y = d->colorSpaceIn->trc[1].apply(c.y);
c.z = d->colorSpaceIn->trc[2].apply(c.z);
}
c = d->colorMatrix.map(c);
c.x = std::max(0.0f, std::min(1.0f, c.x));
c.y = std::max(0.0f, std::min(1.0f, c.y));

View File

@ -38,7 +38,7 @@ public:
bool simpleGammaCorrection() const;
bool isIdentity() const;
void prepare();
Q_GUI_EXPORT void prepare();
enum TransformFlag {
Unpremultiplied = 0,
InputOpaque = 1,

View File

@ -7,4 +7,5 @@ qt_internal_add_test(tst_qcolortransform
tst_qcolortransform.cpp
PUBLIC_LIBRARIES
Qt::Gui
Qt::GuiPrivate
)

View File

@ -31,6 +31,7 @@
#include <qcolorspace.h>
#include <qcolortransform.h>
#include <QtGui/private/qcolortransform_p.h>
class tst_QColorTransform : public QObject
{
@ -46,6 +47,8 @@ private slots:
void mapRGB64();
void mapQColor_data();
void mapQColor();
void mapRGB32Prepared_data();
void mapRGB32Prepared();
void transformIsIdentity();
};
@ -59,23 +62,22 @@ void tst_QColorTransform::mapRGB32_data()
QTest::addColumn<QColorTransform>("transform");
QTest::addColumn<bool>("sharesRed");
QTest::newRow("default") << QColorTransform() << true;
QTest::newRow("sRGB to Linear") << QColorSpace(QColorSpace::SRgb).transformationToColorSpace(QColorSpace::SRgbLinear) << true;
QTest::newRow("AdobeRGB to sRGB") << QColorSpace(QColorSpace::AdobeRgb).transformationToColorSpace(QColorSpace::SRgb) << true;
QTest::newRow("Linear AdobeRGB to Linear sRGB")
<< QColorSpace(QColorSpace::AdobeRgb).withTransferFunction(QColorSpace::TransferFunction::Linear).transformationToColorSpace(
QColorSpace::SRgb)
<< true;
QTest::newRow("sRgb to AdobeRGB") << QColorSpace(QColorSpace::SRgb).transformationToColorSpace(QColorSpace::AdobeRgb) << true;
QTest::newRow("DP3 to sRGB") << QColorSpace(QColorSpace::DisplayP3).transformationToColorSpace(QColorSpace::SRgb) << false;
QTest::newRow("DP3 to Linear DP3")
<< QColorSpace(QColorSpace::DisplayP3).transformationToColorSpace(
QColorSpace(QColorSpace::DisplayP3).withTransferFunction(QColorSpace::TransferFunction::Linear))
<< false;
QTest::newRow("Linear DP3 to Linear sRGB")
<< QColorSpace(QColorSpace::DisplayP3).withTransferFunction(QColorSpace::TransferFunction::Linear).transformationToColorSpace(
QColorSpace::SRgb)
<< false;
QColorSpace srgb(QColorSpace::SRgb);
QColorSpace srgbLinear(QColorSpace::SRgbLinear);
QColorSpace adobeRgb(QColorSpace::AdobeRgb);
QColorSpace adobeRgbLinear = adobeRgb.withTransferFunction(QColorSpace::TransferFunction::Linear);
QColorSpace dp3(QColorSpace::DisplayP3);
QColorSpace dp3Linear = dp3.withTransferFunction(QColorSpace::TransferFunction::Linear);
QTest::newRow("default") << QColorTransform() << true;
QTest::newRow("sRGB to Linear sRGB") << srgb.transformationToColorSpace(srgbLinear) << true;
QTest::newRow("AdobeRGB to sRGB") << adobeRgb.transformationToColorSpace(srgb) << true;
QTest::newRow("Linear AdobeRGB to AdobeRGB") << adobeRgbLinear.transformationToColorSpace(adobeRgb) << true;
QTest::newRow("Linear AdobeRGB to Linear sRGB") << adobeRgbLinear.transformationToColorSpace(srgbLinear) << true;
QTest::newRow("sRgb to AdobeRGB") << srgb.transformationToColorSpace(adobeRgb) << true;
QTest::newRow("DP3 to sRGB") << dp3.transformationToColorSpace(srgb) << false;
QTest::newRow("DP3 to Linear DP3") << dp3.transformationToColorSpace(dp3Linear) << false;
QTest::newRow("Linear DP3 to Linear sRGB") << dp3Linear.transformationToColorSpace(srgbLinear) << false;
}
void tst_QColorTransform::mapRGB32()
@ -220,6 +222,76 @@ void tst_QColorTransform::mapQColor()
QVERIFY(result.blueF() >= 1.0f);
}
void tst_QColorTransform::mapRGB32Prepared_data()
{
mapRGB32_data();
}
void tst_QColorTransform::mapRGB32Prepared()
{
QFETCH(QColorTransform, transform);
QFETCH(bool, sharesRed);
// The same tests as mapRGB32 but prepared, to use the LUT code-paths
if (!transform.isIdentity())
QColorTransformPrivate::get(transform)->prepare();
QRgb testColor = qRgb(32, 64, 128);
QRgb result = transform.map(testColor);
QVERIFY(qRed(result) < qGreen(result));
QVERIFY(qGreen(result) < qBlue(result));
QCOMPARE(qAlpha(result), 255);
if (transform.isIdentity())
QVERIFY(result == testColor);
else
QVERIFY(result != testColor);
testColor = qRgb(128, 64, 32);
result = transform.map(testColor);
QVERIFY(qRed(result) > qGreen(result));
QVERIFY(qGreen(result) > qBlue(result));
QCOMPARE(qAlpha(result), 255);
if (transform.isIdentity())
QVERIFY(result == testColor);
else
QVERIFY(result != testColor);
testColor = qRgba(15, 31, 63, 128);
result = transform.map(testColor);
QVERIFY(qRed(result) < qGreen(result));
QVERIFY(qGreen(result) < qBlue(result));
QCOMPARE(qAlpha(result), 128);
if (transform.isIdentity())
QVERIFY(result == testColor);
else
QVERIFY(result != testColor);
testColor = qRgb(0, 0, 0);
result = transform.map(testColor);
QCOMPARE(qRed(result), 0);
QCOMPARE(qGreen(result), 0);
QCOMPARE(qBlue(result), 0);
QCOMPARE(qAlpha(result), 255);
testColor = qRgb(255, 255, 255);
result = transform.map(testColor);
QCOMPARE(qRed(result), 255);
QCOMPARE(qGreen(result), 255);
QCOMPARE(qBlue(result), 255);
QCOMPARE(qAlpha(result), 255);
testColor = qRgb(255, 255, 0);
result = transform.map(testColor);
QCOMPARE(qAlpha(result), 255);
if (sharesRed)
QCOMPARE(qRed(result), 255);
testColor = qRgb(0, 255, 255);
result = transform.map(testColor);
QCOMPARE(qBlue(result), 255);
QCOMPARE(qAlpha(result), 255);
}
void tst_QColorTransform::transformIsIdentity()
{
QColorTransform ct;