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
parent
9ceedd5863
commit
f1408d9966
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue