Add API for creating QColorSpace with multiple color-transfer tables

One table per color channel, as is possible from many inputs.

Change-Id: I9fc723c68f222a228dd2b1458207b028422913bf
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
This commit is contained in:
Allan Sandfeld Jensen 2020-12-15 12:40:30 +01:00
parent cefef116ef
commit 92ed274475
3 changed files with 157 additions and 15 deletions

View File

@ -221,7 +221,7 @@ QColorSpacePrivate::QColorSpacePrivate(const QColorSpacePrimaries &primaries,
setTransferFunction();
}
QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Primaries primaries, const QVector<uint16_t> &transferFunctionTable)
QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Primaries primaries, const QList<uint16_t> &transferFunctionTable)
: primaries(primaries)
, transferFunction(QColorSpace::TransferFunction::Custom)
, gamma(0)
@ -231,7 +231,7 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Primaries primaries, const Q
initialize();
}
QColorSpacePrivate::QColorSpacePrivate(const QColorSpacePrimaries &primaries, const QVector<uint16_t> &transferFunctionTable)
QColorSpacePrivate::QColorSpacePrivate(const QColorSpacePrimaries &primaries, const QList<uint16_t> &transferFunctionTable)
: primaries(QColorSpace::Primaries::Custom)
, transferFunction(QColorSpace::TransferFunction::Custom)
, gamma(0)
@ -244,6 +244,24 @@ QColorSpacePrivate::QColorSpacePrivate(const QColorSpacePrimaries &primaries, co
initialize();
}
QColorSpacePrivate::QColorSpacePrivate(const QColorSpacePrimaries &primaries,
const QList<uint16_t> &redTransferFunctionTable,
const QList<uint16_t> &greenTransferFunctionTable,
const QList<uint16_t> &blueTransferFunctionTable)
: primaries(QColorSpace::Primaries::Custom)
, transferFunction(QColorSpace::TransferFunction::Custom)
, gamma(0)
{
Q_ASSERT(primaries.areValid());
toXyz = primaries.toXyzMatrix();
whitePoint = QColorVector(primaries.whitePoint);
setTransferFunctionTables(redTransferFunctionTable,
greenTransferFunctionTable,
blueTransferFunctionTable);
identifyColorSpace();
setToXyzMatrix();
}
void QColorSpacePrivate::identifyColorSpace()
{
switch (primaries) {
@ -321,7 +339,7 @@ void QColorSpacePrivate::setToXyzMatrix()
whitePoint = QColorVector(colorSpacePrimaries.whitePoint);
}
void QColorSpacePrivate::setTransferFunctionTable(const QVector<uint16_t> &transferFunctionTable)
void QColorSpacePrivate::setTransferFunctionTable(const QList<uint16_t> &transferFunctionTable)
{
QColorTransferTable table(transferFunctionTable.size(), transferFunctionTable);
if (!table.isEmpty() && !table.checkValidity()) {
@ -347,6 +365,46 @@ void QColorSpacePrivate::setTransferFunctionTable(const QVector<uint16_t> &trans
}
}
void QColorSpacePrivate::setTransferFunctionTables(const QList<uint16_t> &redTransferFunctionTable,
const QList<uint16_t> &greenTransferFunctionTable,
const QList<uint16_t> &blueTransferFunctionTable)
{
QColorTransferTable redTable(redTransferFunctionTable.size(), redTransferFunctionTable);
QColorTransferTable greenTable(greenTransferFunctionTable.size(), greenTransferFunctionTable);
QColorTransferTable blueTable(blueTransferFunctionTable.size(), blueTransferFunctionTable);
if (!redTable.isEmpty() && !greenTable.isEmpty() && !blueTable.isEmpty() &&
!redTable.checkValidity() && !greenTable.checkValidity() && !blueTable.checkValidity()) {
qWarning() << "Invalid transfer function table given to QColorSpace";
trc[0].m_type = QColorTrc::Type::Uninitialized;
trc[1].m_type = QColorTrc::Type::Uninitialized;
trc[2].m_type = QColorTrc::Type::Uninitialized;
return;
}
transferFunction = QColorSpace::TransferFunction::Custom;
QColorTransferFunction curve;
if (redTable.asColorTransferFunction(&curve)) {
trc[0].m_type = QColorTrc::Type::Function;
trc[0].m_fun = curve;
} else {
trc[0].m_type = QColorTrc::Type::Table;
trc[0].m_table = redTable;
}
if (greenTable.asColorTransferFunction(&curve)) {
trc[1].m_type = QColorTrc::Type::Function;
trc[1].m_fun = curve;
} else {
trc[1].m_type = QColorTrc::Type::Table;
trc[1].m_table = greenTable;
}
if (blueTable.asColorTransferFunction(&curve)) {
trc[2].m_type = QColorTrc::Type::Function;
trc[2].m_fun = curve;
} else {
trc[2].m_type = QColorTrc::Type::Table;
trc[2].m_table = blueTable;
}
}
void QColorSpacePrivate::setTransferFunction()
{
switch (transferFunction) {
@ -528,7 +586,7 @@ QColorSpace::QColorSpace(QColorSpace::Primaries primaries, float gamma)
\since 6.1
*/
QColorSpace::QColorSpace(QColorSpace::Primaries gamut, const QVector<uint16_t> &transferFunctionTable)
QColorSpace::QColorSpace(QColorSpace::Primaries gamut, const QList<uint16_t> &transferFunctionTable)
: d_ptr(new QColorSpacePrivate(gamut, transferFunctionTable))
{
}
@ -558,11 +616,30 @@ QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
*/
QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
const QPointF &greenPoint, const QPointF &bluePoint,
const QVector<uint16_t> &transferFunctionTable)
const QList<uint16_t> &transferFunctionTable)
: d_ptr(new QColorSpacePrivate({whitePoint, redPoint, greenPoint, bluePoint}, transferFunctionTable))
{
}
/*!
Creates a custom color space with primaries based on the chromaticities of the primary colors \a whitePoint,
\a redPoint, \a greenPoint and \a bluePoint, and using the custom transfer functions described by
\a redTransferFunctionTable, \a greenTransferFunctionTable, and \a blueTransferFunctionTable.
\since 6.1
*/
QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
const QPointF &greenPoint, const QPointF &bluePoint,
const QList<uint16_t> &redTransferFunctionTable,
const QList<uint16_t> &greenTransferFunctionTable,
const QList<uint16_t> &blueTransferFunctionTable)
: d_ptr(new QColorSpacePrivate({whitePoint, redPoint, greenPoint, bluePoint},
redTransferFunctionTable,
greenTransferFunctionTable,
blueTransferFunctionTable))
{
}
QColorSpace::~QColorSpace() = default;
QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QColorSpacePrivate)
@ -640,9 +717,9 @@ void QColorSpace::setTransferFunction(QColorSpace::TransferFunction transferFunc
Sets the transfer function to \a transferFunctionTable.
\since 6.1
\sa transferFunction()
\sa withTransferFunction()
*/
void QColorSpace::setTransferFunction(const QVector<uint16_t> &transferFunctionTable)
void QColorSpace::setTransferFunction(const QList<uint16_t> &transferFunctionTable)
{
if (!d_ptr) {
d_ptr = new QColorSpacePrivate(Primaries::Custom, transferFunctionTable);
@ -657,6 +734,34 @@ void QColorSpace::setTransferFunction(const QVector<uint16_t> &transferFunctionT
d_ptr->setTransferFunction();
}
/*!
Sets the transfer functions to \a redTransferFunctionTable,
\a greenTransferFunctionTable and \a blueTransferFunctionTable.
\since 6.1
\sa withTransferFunctions()
*/
void QColorSpace::setTransferFunctions(const QList<uint16_t> &redTransferFunctionTable,
const QList<uint16_t> &greenTransferFunctionTable,
const QList<uint16_t> &blueTransferFunctionTable)
{
if (!d_ptr) {
d_ptr = new QColorSpacePrivate();
d_ptr->setTransferFunctionTables(redTransferFunctionTable,
greenTransferFunctionTable,
blueTransferFunctionTable);
d_ptr->ref.ref();
return;
}
detach();
d_ptr->description.clear();
d_ptr->setTransferFunctionTables(redTransferFunctionTable,
greenTransferFunctionTable,
blueTransferFunctionTable);
d_ptr->gamma = 0;
d_ptr->identifyColorSpace();
}
/*!
Returns a copy of this color space, except using the transfer function
\a transferFunction and \a gamma.
@ -681,7 +786,7 @@ QColorSpace QColorSpace::withTransferFunction(QColorSpace::TransferFunction tran
\since 6.1
\sa transferFunction(), setTransferFunction()
*/
QColorSpace QColorSpace::withTransferFunction(const QVector<uint16_t> &transferFunctionTable) const
QColorSpace QColorSpace::withTransferFunction(const QList<uint16_t> &transferFunctionTable) const
{
if (!isValid())
return *this;
@ -690,6 +795,25 @@ QColorSpace QColorSpace::withTransferFunction(const QVector<uint16_t> &transferF
return out;
}
/*!
Returns a copy of this color space, except using the transfer functions
described by \a redTransferFunctionTable, \a greenTransferFunctionTable and
\a blueTransferFunctionTable.
\since 6.1
\sa setTransferFunctions()
*/
QColorSpace QColorSpace::withTransferFunctions(const QList<uint16_t> &redTransferFunctionTable,
const QList<uint16_t> &greenTransferFunctionTable,
const QList<uint16_t> &blueTransferFunctionTable) const
{
if (!isValid())
return *this;
QColorSpace out(*this);
out.setTransferFunctions(redTransferFunctionTable, greenTransferFunctionTable, blueTransferFunctionTable);
return out;
}
/*!
Sets the primaries to those of the \a primariesId set.

View File

@ -86,13 +86,18 @@ public:
QColorSpace(NamedColorSpace namedColorSpace);
QColorSpace(Primaries primaries, TransferFunction transferFunction, float gamma = 0.0f);
QColorSpace(Primaries primaries, float gamma);
QColorSpace(Primaries primaries, const QVector<uint16_t> &transferFunctionTable);
QColorSpace(Primaries primaries, const QList<uint16_t> &transferFunctionTable);
QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
const QPointF &greenPoint, const QPointF &bluePoint,
TransferFunction transferFunction, float gamma = 0.0f);
QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
const QPointF &greenPoint, const QPointF &bluePoint,
const QVector<uint16_t> &transferFunctionTable);
const QList<uint16_t> &transferFunctionTable);
QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
const QPointF &greenPoint, const QPointF &bluePoint,
const QList<uint16_t> &redTransferFunctionTable,
const QList<uint16_t> &greenTransferFunctionTable,
const QList<uint16_t> &blueTransferFunctionTable);
~QColorSpace();
QColorSpace(const QColorSpace &colorSpace) noexcept;
@ -114,9 +119,15 @@ public:
float gamma() const noexcept;
void setTransferFunction(TransferFunction transferFunction, float gamma = 0.0f);
void setTransferFunction(const QVector<uint16_t> &transferFunctionTable);
void setTransferFunction(const QList<uint16_t> &transferFunctionTable);
void setTransferFunctions(const QList<uint16_t> &redTransferFunctionTable,
const QList<uint16_t> &greenTransferFunctionTable,
const QList<uint16_t> &blueTransferFunctionTable);
QColorSpace withTransferFunction(TransferFunction transferFunction, float gamma = 0.0f) const;
QColorSpace withTransferFunction(const QVector<uint16_t> &transferFunctionTable) const;
QColorSpace withTransferFunction(const QList<uint16_t> &transferFunctionTable) const;
QColorSpace withTransferFunctions(const QList<uint16_t> &redTransferFunctionTable,
const QList<uint16_t> &greenTransferFunctionTable,
const QList<uint16_t> &blueTransferFunctionTable) const;
void setPrimaries(Primaries primariesId);
void setPrimaries(const QPointF &whitePoint, const QPointF &redPoint,

View File

@ -92,9 +92,13 @@ public:
QColorSpacePrivate();
QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSpace);
QColorSpacePrivate(QColorSpace::Primaries primaries, QColorSpace::TransferFunction transferFunction, float gamma);
QColorSpacePrivate(QColorSpace::Primaries primaries, const QVector<uint16_t> &transferFunctionTable);
QColorSpacePrivate(QColorSpace::Primaries primaries, const QList<uint16_t> &transferFunctionTable);
QColorSpacePrivate(const QColorSpacePrimaries &primaries, QColorSpace::TransferFunction transferFunction, float gamma);
QColorSpacePrivate(const QColorSpacePrimaries &primaries, const QVector<uint16_t> &transferFunctionTable);
QColorSpacePrivate(const QColorSpacePrimaries &primaries, const QList<uint16_t> &transferFunctionTable);
QColorSpacePrivate(const QColorSpacePrimaries &primaries,
const QList<uint16_t> &redTransferFunctionTable,
const QList<uint16_t> &greenTransferFunctionTable,
const QList<uint16_t> &blueRransferFunctionTable);
QColorSpacePrivate(const QColorSpacePrivate &other) = default;
static const QColorSpacePrivate *get(const QColorSpace &colorSpace)
@ -111,7 +115,10 @@ public:
void setToXyzMatrix();
void setTransferFunction();
void identifyColorSpace();
void setTransferFunctionTable(const QVector<uint16_t> &transferFunctionTable);
void setTransferFunctionTable(const QList<uint16_t> &transferFunctionTable);
void setTransferFunctionTables(const QList<uint16_t> &redTransferFunctionTable,
const QList<uint16_t> &greenTransferFunctionTable,
const QList<uint16_t> &blueTransferFunctionTable);
QColorTransform transformationToColorSpace(const QColorSpacePrivate *out) const;
static constexpr QColorSpace::NamedColorSpace Unknown = QColorSpace::NamedColorSpace(0);