QColorSpace: port to QESDP

Replace the hand-rolled refcount management with QESDP.
Since the class has a default-constructed / moved-from state
where the d-pointer can be nullptr, add a in-class detach() that
ensures a private object.

Change-Id: Id81431fa60132dbc0eed45bb60b38d4f7d73833f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
bb10
Giuseppe D'Angelo 2020-10-04 21:19:32 +02:00
parent 9ceedd5863
commit f1408d9966
5 changed files with 44 additions and 63 deletions

View File

@ -592,7 +592,7 @@ bool QPngHandlerPrivate::readPngHeader()
if (!colorSpace.isValid()) {
qCWarning(lcImageIo) << "QPngHandler: Failed to parse ICC profile";
} else {
QColorSpacePrivate *csD = QColorSpacePrivate::getWritable(colorSpace);
QColorSpacePrivate *csD = QColorSpacePrivate::get(colorSpace);
if (csD->description.isEmpty())
csD->description = QString::fromLatin1((const char *)name);
colorSpaceState = Icc;

View File

@ -423,11 +423,10 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
*/
/*!
\fn QColorSpace::QColorSpace()
Creates a new colorspace object that represents an undefined and invalid colorspace.
*/
QColorSpace::QColorSpace()
{
}
/*!
Creates a new colorspace object that represents a \a namedColorSpace.
@ -450,7 +449,6 @@ QColorSpace::QColorSpace(NamedColorSpace namedColorSpace)
delete tmp;
}
d_ptr = cspriv;
d_ptr->ref.ref();
Q_ASSERT(isValid());
}
@ -461,7 +459,6 @@ QColorSpace::QColorSpace(NamedColorSpace namedColorSpace)
QColorSpace::QColorSpace(QColorSpace::Primaries primaries, QColorSpace::TransferFunction fun, float gamma)
: d_ptr(new QColorSpacePrivate(primaries, fun, gamma))
{
d_ptr->ref.ref();
}
/*!
@ -471,7 +468,6 @@ QColorSpace::QColorSpace(QColorSpace::Primaries primaries, QColorSpace::Transfer
QColorSpace::QColorSpace(QColorSpace::Primaries primaries, float gamma)
: d_ptr(new QColorSpacePrivate(primaries, TransferFunction::Gamma, gamma))
{
d_ptr->ref.ref();
}
/*!
@ -485,36 +481,16 @@ QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
QColorSpacePrimaries primaries(whitePoint, redPoint, greenPoint, bluePoint);
if (!primaries.areValid()) {
qWarning() << "QColorSpace attempted constructed from invalid primaries:" << whitePoint << redPoint << greenPoint << bluePoint;
d_ptr = nullptr;
return;
}
d_ptr = new QColorSpacePrivate(primaries, fun, gamma);
d_ptr->ref.ref();
}
QColorSpace::~QColorSpace()
{
if (d_ptr && !d_ptr->ref.deref())
delete d_ptr;
}
QColorSpace::~QColorSpace() = default;
QColorSpace::QColorSpace(const QColorSpace &colorSpace)
: d_ptr(colorSpace.d_ptr)
{
if (d_ptr)
d_ptr->ref.ref();
}
QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QColorSpacePrivate)
QColorSpace &QColorSpace::operator=(const QColorSpace &colorSpace)
{
QColorSpacePrivate *oldD = d_ptr;
d_ptr = colorSpace.d_ptr;
if (d_ptr)
d_ptr->ref.ref();
if (oldD && !oldD->ref.deref())
delete oldD;
return *this;
}
QColorSpace::QColorSpace(const QColorSpace &colorSpace) noexcept = default;
/*! \fn void QColorSpace::swap(QColorSpace &other)
@ -571,12 +547,11 @@ void QColorSpace::setTransferFunction(QColorSpace::TransferFunction transferFunc
return;
if (!d_ptr) {
d_ptr = new QColorSpacePrivate(Primaries::Custom, transferFunction, gamma);
d_ptr->ref.ref();
return;
}
if (d_ptr->transferFunction == transferFunction && d_ptr->gamma == gamma)
return;
QColorSpacePrivate::getWritable(*this); // detach
detach();
d_ptr->description.clear();
d_ptr->transferFunction = transferFunction;
d_ptr->gamma = gamma;
@ -612,12 +587,11 @@ void QColorSpace::setPrimaries(QColorSpace::Primaries primariesId)
return;
if (!d_ptr) {
d_ptr = new QColorSpacePrivate(primariesId, TransferFunction::Custom, 0.0f);
d_ptr->ref.ref();
return;
}
if (d_ptr->primaries == primariesId)
return;
QColorSpacePrivate::getWritable(*this); // detach
detach();
d_ptr->description.clear();
d_ptr->primaries = primariesId;
d_ptr->identifyColorSpace();
@ -638,13 +612,12 @@ void QColorSpace::setPrimaries(const QPointF &whitePoint, const QPointF &redPoin
return;
if (!d_ptr) {
d_ptr = new QColorSpacePrivate(primaries, TransferFunction::Custom, 0.0f);
d_ptr->ref.ref();
return;
}
QColorMatrix toXyz = primaries.toXyzMatrix();
if (QColorVector(primaries.whitePoint) == d_ptr->whitePoint && toXyz == d_ptr->toXyz)
return;
QColorSpacePrivate::getWritable(*this); // detach
detach();
d_ptr->description.clear();
d_ptr->primaries = QColorSpace::Primaries::Custom;
d_ptr->toXyz = toXyz;
@ -652,6 +625,17 @@ void QColorSpace::setPrimaries(const QPointF &whitePoint, const QPointF &redPoin
d_ptr->identifyColorSpace();
}
/*!
\internal
*/
void QColorSpace::detach()
{
if (d_ptr)
d_ptr.detach();
else
d_ptr = new QColorSpacePrivate;
}
/*!
Returns an ICC profile representing the color space.
@ -691,8 +675,8 @@ QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile)
QColorSpace colorSpace;
if (QIcc::fromIccProfile(iccProfile, &colorSpace))
return colorSpace;
QColorSpacePrivate *d = QColorSpacePrivate::getWritable(colorSpace);
d->iccProfile = iccProfile;
colorSpace.detach();
colorSpace.d_ptr->iccProfile = iccProfile;
return colorSpace;
}
@ -774,7 +758,7 @@ QColorTransform QColorSpace::transformationToColorSpace(const QColorSpace &color
if (!isValid() || !colorspace.isValid())
return QColorTransform();
return d_ptr->transformationToColorSpace(colorspace.d_ptr);
return d_ptr->transformationToColorSpace(colorspace.d_ptr.get());
}
/*!

View File

@ -51,6 +51,8 @@ QT_BEGIN_NAMESPACE
class QColorSpacePrivate;
class QPointF;
QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QColorSpacePrivate, Q_GUI_EXPORT)
class Q_GUI_EXPORT QColorSpace
{
Q_GADGET
@ -80,7 +82,7 @@ public:
};
Q_ENUM(TransferFunction)
QColorSpace();
QColorSpace() noexcept = default;
QColorSpace(NamedColorSpace namedColorSpace);
QColorSpace(Primaries primaries, TransferFunction fun, float gamma = 0.0f);
QColorSpace(Primaries primaries, float gamma);
@ -89,12 +91,15 @@ public:
TransferFunction fun, float gamma = 0.0f);
~QColorSpace();
QColorSpace(const QColorSpace &colorSpace);
QColorSpace &operator=(const QColorSpace &colorSpace);
QColorSpace(const QColorSpace &colorSpace) noexcept;
QColorSpace &operator=(const QColorSpace &colorSpace) noexcept
{
QColorSpace copy(colorSpace);
swap(copy);
return *this;
}
QColorSpace(QColorSpace &&colorSpace) noexcept
: d_ptr(qExchange(colorSpace.d_ptr, nullptr))
{ }
QColorSpace(QColorSpace &&colorSpace) noexcept = default;
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QColorSpace)
void swap(QColorSpace &colorSpace) noexcept
@ -111,6 +116,7 @@ public:
void setPrimaries(const QPointF &whitePoint, const QPointF &redPoint,
const QPointF &greenPoint, const QPointF &bluePoint);
void detach();
bool isValid() const noexcept;
friend Q_GUI_EXPORT bool operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2);
@ -125,7 +131,7 @@ public:
private:
friend class QColorSpacePrivate;
QColorSpacePrivate *d_ptr = nullptr;
QExplicitlySharedDataPointer<QColorSpacePrivate> d_ptr;
#ifndef QT_NO_DEBUG_STREAM
friend Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QColorSpace &colorSpace);

View File

@ -95,24 +95,14 @@ public:
QColorSpacePrivate(const QColorSpacePrimaries &primaries, QColorSpace::TransferFunction fun, float gamma);
QColorSpacePrivate(const QColorSpacePrivate &other) = default;
// named different from get to avoid accidental detachs
static QColorSpacePrivate *getWritable(QColorSpace &colorSpace)
{
if (!colorSpace.d_ptr) {
colorSpace.d_ptr = new QColorSpacePrivate;
colorSpace.d_ptr->ref.ref();
} else if (colorSpace.d_ptr->ref.loadRelaxed() != 1) {
colorSpace.d_ptr->ref.deref();
colorSpace.d_ptr = new QColorSpacePrivate(*colorSpace.d_ptr);
colorSpace.d_ptr->ref.ref();
}
Q_ASSERT(colorSpace.d_ptr->ref.loadRelaxed() == 1);
return colorSpace.d_ptr;
}
static const QColorSpacePrivate *get(const QColorSpace &colorSpace)
{
return colorSpace.d_ptr;
return colorSpace.d_ptr.get();
}
static QColorSpacePrivate *get(QColorSpace &colorSpace)
{
return colorSpace.d_ptr.get();
}
void initialize();

View File

@ -709,7 +709,8 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
}
}
QColorSpacePrivate *colorspaceDPtr = QColorSpacePrivate::getWritable(*colorSpace);
colorSpace->detach();
QColorSpacePrivate *colorspaceDPtr = QColorSpacePrivate::get(*colorSpace);
if (header.inputColorSpace == uint(ColorSpaceType::Rgb)) {
// Parse XYZ tags