diff options
Diffstat (limited to 'src/gui/painting/qcolorspace.cpp')
-rw-r--r-- | src/gui/painting/qcolorspace.cpp | 66 |
1 files changed, 46 insertions, 20 deletions
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index 930e5aec87..dd30c64640 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -46,6 +46,7 @@ #include "qcolortransform_p.h" #include "qicc_p.h" +#include <qatomic.h> #include <qmath.h> #include <qtransform.h> @@ -55,6 +56,18 @@ QT_BEGIN_NAMESPACE QBasicMutex QColorSpacePrivate::s_lutWriteLock; +static QAtomicPointer<QColorSpacePrivate> s_predefinedColorspacePrivates[QColorSpace::ProPhotoRgb] = {}; +static void cleanupPredefinedColorspaces() +{ + for (QAtomicPointer<QColorSpacePrivate> &ptr : s_predefinedColorspacePrivates) { + QColorSpacePrivate *prv = ptr.fetchAndStoreAcquire(nullptr); + if (prv && !prv->ref.deref()) + delete prv; + } +} + +Q_DESTRUCTOR_FUNCTION(cleanupPredefinedColorspaces) + QColorSpacePrimaries::QColorSpacePrimaries(QColorSpace::Primaries primaries) { switch (primaries) { @@ -133,13 +146,17 @@ QColorMatrix QColorSpacePrimaries::toXyzMatrix() const QColorVector srcCone = abrad.map(wXyz); QColorVector dstCone = abrad.map(wXyzD50); - QColorMatrix wToD50 = { { dstCone.x / srcCone.x, 0, 0 }, - { 0, dstCone.y / srcCone.y, 0 }, - { 0, 0, dstCone.z / srcCone.z } }; + if (srcCone.x && srcCone.y && srcCone.z) { + QColorMatrix wToD50 = { { dstCone.x / srcCone.x, 0, 0 }, + { 0, dstCone.y / srcCone.y, 0 }, + { 0, 0, dstCone.z / srcCone.z } }; - QColorMatrix chromaticAdaptation = abradinv * (wToD50 * abrad); - toXyz = chromaticAdaptation * toXyz; + QColorMatrix chromaticAdaptation = abradinv * (wToD50 * abrad); + toXyz = chromaticAdaptation * toXyz; + } else { + toXyz.r = {0, 0, 0}; // set to invalid value + } } return toXyz; @@ -185,9 +202,9 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSp initialize(); } -QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Primaries primaries, QColorSpace::TransferFunction fun, float gamma) +QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Primaries primaries, QColorSpace::TransferFunction transferFunction, float gamma) : primaries(primaries) - , transferFunction(fun) + , transferFunction(transferFunction) , gamma(gamma) { identifyColorSpace(); @@ -195,10 +212,10 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Primaries primaries, QColorS } QColorSpacePrivate::QColorSpacePrivate(const QColorSpacePrimaries &primaries, - QColorSpace::TransferFunction fun, + QColorSpace::TransferFunction transferFunction, float gamma) : primaries(QColorSpace::Primaries::Custom) - , transferFunction(fun) + , transferFunction(transferFunction) , gamma(gamma) { Q_ASSERT(primaries.areValid()); @@ -318,6 +335,7 @@ void QColorSpacePrivate::setTransferFunction() } trc[1] = trc[0]; trc[2] = trc[0]; + lut.generated.storeRelease(0); } QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpacePrivate *out) const @@ -426,22 +444,28 @@ QColorSpace::QColorSpace(NamedColorSpace namedColorSpace) qWarning() << "QColorSpace attempted constructed from invalid QColorSpace::NamedColorSpace: " << int(namedColorSpace); return; } - static QColorSpacePrivate *predefinedColorspacePrivates[QColorSpace::ProPhotoRgb + 1]; - if (!predefinedColorspacePrivates[namedColorSpace]) { - predefinedColorspacePrivates[namedColorSpace] = new QColorSpacePrivate(namedColorSpace); - predefinedColorspacePrivates[namedColorSpace]->ref.ref(); + // The defined namespaces start at 1: + auto &atomicRef = s_predefinedColorspacePrivates[static_cast<int>(namedColorSpace) - 1]; + QColorSpacePrivate *cspriv = atomicRef.loadAcquire(); + if (!cspriv) { + auto *tmp = new QColorSpacePrivate(namedColorSpace); + tmp->ref.ref(); + if (atomicRef.testAndSetOrdered(nullptr, tmp, cspriv)) + cspriv = tmp; + else + delete tmp; } - d_ptr = predefinedColorspacePrivates[namedColorSpace]; + d_ptr = cspriv; d_ptr->ref.ref(); Q_ASSERT(isValid()); } /*! - Creates a custom color space with the primaries \a primaries, using the transfer function \a fun and + Creates a custom color space with the primaries \a primaries, using the transfer function \a transferFunction and optionally \a gamma. */ -QColorSpace::QColorSpace(QColorSpace::Primaries primaries, QColorSpace::TransferFunction fun, float gamma) - : d_ptr(new QColorSpacePrivate(primaries, fun, gamma)) +QColorSpace::QColorSpace(QColorSpace::Primaries primaries, QColorSpace::TransferFunction transferFunction, float gamma) + : d_ptr(new QColorSpacePrivate(primaries, transferFunction, gamma)) { d_ptr->ref.ref(); } @@ -458,11 +482,11 @@ QColorSpace::QColorSpace(QColorSpace::Primaries primaries, float gamma) /*! Creates a custom colorspace with a primaries based on the chromaticities of the primary colors \a whitePoint, - \a redPoint, \a greenPoint and \a bluePoint, and using the transfer function \a fun and optionally \a gamma. + \a redPoint, \a greenPoint and \a bluePoint, and using the transfer function \a transferFunction and optionally \a gamma. */ QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint, const QPointF &greenPoint, const QPointF &bluePoint, - QColorSpace::TransferFunction fun, float gamma) + QColorSpace::TransferFunction transferFunction, float gamma) { QColorSpacePrimaries primaries(whitePoint, redPoint, greenPoint, bluePoint); if (!primaries.areValid()) { @@ -470,7 +494,7 @@ QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint, d_ptr = nullptr; return; } - d_ptr = new QColorSpacePrivate(primaries, fun, gamma); + d_ptr = new QColorSpacePrivate(primaries, transferFunction, gamma); d_ptr->ref.ref(); } @@ -824,3 +848,5 @@ QDebug operator<<(QDebug dbg, const QColorSpace &colorSpace) #endif QT_END_NAMESPACE + +#include "moc_qcolorspace.cpp" |