summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qcolorspace.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting/qcolorspace.cpp')
-rw-r--r--src/gui/painting/qcolorspace.cpp66
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"