Improve QColorTrc::isLinear and rename it isIdentity

Pick-to: 6.7
Change-Id: Id697fa3844610606c202e3fa717d631a3621e774
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
bb10
Allan Sandfeld Jensen 2024-02-28 10:41:29 +01:00
parent cee8a11d73
commit e9f5bb7cbe
5 changed files with 53 additions and 24 deletions

View File

@ -319,7 +319,7 @@ void QColorSpacePrivate::setTransferFunctionTable(const QList<uint16_t> &transfe
QColorTransferFunction curve;
if (table.asColorTransferFunction(&curve)) {
// Table recognized as a specific curve
if (curve.isLinear()) {
if (curve.isIdentity()) {
transferFunction = QColorSpace::TransferFunction::Linear;
gamma = 1.0f;
} else if (curve.isSRgb()) {

View File

@ -26,7 +26,8 @@ class Q_GUI_EXPORT QColorTransferFunction
{
public:
QColorTransferFunction() noexcept
: m_a(1.0f), m_b(0.0f), m_c(1.0f), m_d(0.0f), m_e(0.0f), m_f(0.0f), m_g(1.0f), m_flags(0)
: m_a(1.0f), m_b(0.0f), m_c(1.0f), m_d(0.0f), m_e(0.0f), m_f(0.0f), m_g(1.0f)
, m_flags(quint32(Hints::Calculated) | quint32(Hints::IsGamma) | quint32(Hints::IsIdentity))
{ }
QColorTransferFunction(float a, float b, float c, float d, float e, float f, float g) noexcept
: m_a(a), m_b(b), m_c(c), m_d(d), m_e(e), m_f(f), m_g(g), m_flags(0)
@ -37,10 +38,10 @@ public:
updateHints();
return m_flags & quint32(Hints::IsGamma);
}
bool isLinear() const
bool isIdentity() const
{
updateHints();
return m_flags & quint32(Hints::IsLinear);
return m_flags & quint32(Hints::IsIdentity);
}
bool isSRgb() const
{
@ -88,15 +89,19 @@ public:
// A few predefined curves:
static QColorTransferFunction fromGamma(float gamma)
{
return QColorTransferFunction(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, gamma);
return QColorTransferFunction(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, gamma,
quint32(Hints::Calculated) | quint32(Hints::IsGamma) |
(paramCompare(gamma, 1.0f) ? quint32(Hints::IsIdentity) : 0));
}
static QColorTransferFunction fromSRgb()
{
return QColorTransferFunction(1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045f, 0.0f, 0.0f, 2.4f);
return QColorTransferFunction(1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045f, 0.0f, 0.0f, 2.4f,
quint32(Hints::Calculated) | quint32(Hints::IsSRgb));
}
static QColorTransferFunction fromProPhotoRgb()
{
return QColorTransferFunction(1.0f, 0.0f, 1.0f / 16.0f, 16.0f / 512.0f, 0.0f, 0.0f, 1.8f);
return QColorTransferFunction(1.0f, 0.0f, 1.0f / 16.0f, 16.0f / 512.0f, 0.0f, 0.0f, 1.8f,
quint32(Hints::Calculated));
}
bool matches(const QColorTransferFunction &o) const
{
@ -117,6 +122,9 @@ public:
float m_g;
private:
QColorTransferFunction(float a, float b, float c, float d, float e, float f, float g, quint32 flags) noexcept
: m_a(a), m_b(b), m_c(c), m_d(d), m_e(e), m_f(f), m_g(g), m_flags(flags)
{ }
static inline bool paramCompare(float p1, float p2)
{
// Much fuzzier than fuzzy compare.
@ -137,7 +145,7 @@ private:
if (simple) {
m_flags |= quint32(Hints::IsGamma);
if (qFuzzyCompare(m_g, 1.0f))
m_flags |= quint32(Hints::IsLinear);
m_flags |= quint32(Hints::IsIdentity);
} else {
if (*this == fromSRgb())
m_flags |= quint32(Hints::IsSRgb);
@ -147,7 +155,7 @@ private:
enum class Hints : quint32 {
Calculated = 1,
IsGamma = 2,
IsLinear = 4,
IsIdentity = 4,
IsSRgb = 8
};
mutable quint32 m_flags;

View File

@ -48,6 +48,17 @@ public:
return m_tableSize == 0;
}
bool isIdentity() const
{
if (isEmpty())
return true;
if (m_tableSize != 2)
return false;
if (!m_table8.isEmpty())
return m_table8[0] == 0 && m_table8[1] == 255;
return m_table16[0] == 0 && m_table16[1] == 65535;
}
bool checkValidity() const
{
if (isEmpty())
@ -137,6 +148,10 @@ public:
bool asColorTransferFunction(QColorTransferFunction *transferFn)
{
Q_ASSERT(transferFn);
if (isEmpty()) {
*transferFn = QColorTransferFunction();
return true;
}
if (m_tableSize < 2)
return false;
if (!m_table8.isEmpty() && (m_table8[0] != 0 || m_table8[m_tableSize - 1] != 255))

View File

@ -39,9 +39,11 @@ public:
Table
};
bool isLinear() const
bool isIdentity() const
{
return m_type == Type::Uninitialized || (m_type == Type::Function && m_fun.isLinear());
return m_type == Type::Uninitialized
|| (m_type == Type::Function && m_fun.isIdentity())
|| (m_type == Type::Table && m_table.isIdentity());
}
bool isValid() const
{

View File

@ -238,7 +238,7 @@ static bool isValidIccProfile(const ICCProfileHeader &header)
static int writeColorTrc(QDataStream &stream, const QColorTrc &trc)
{
if (trc.isLinear()) {
if (trc.isIdentity()) {
stream << uint(Tag::curv) << uint(0);
stream << uint(0);
return 12;
@ -698,26 +698,30 @@ static bool parseTRCs(const QByteArray &data, const QHash<Tag, TagEntry> &tagInd
qCWarning(lcIcc) << "fromIccProfile: Invalid bTRC";
return false;
}
if (rCurve == gCurve && gCurve == bCurve && rCurve.m_type == QColorTrc::Type::Function) {
if (rCurve.m_fun.isLinear()) {
if (rCurve == gCurve && gCurve == bCurve) {
if (rCurve.isIdentity()) {
qCDebug(lcIcc) << "fromIccProfile: Linear gamma detected";
colorspaceDPtr->trc[0] = QColorTransferFunction();
colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Linear;
colorspaceDPtr->gamma = 1.0f;
} else if (rCurve.m_fun.isGamma()) {
qCDebug(lcIcc) << "fromIccProfile: Simple gamma detected";
colorspaceDPtr->trc[0] = QColorTransferFunction::fromGamma(rCurve.m_fun.m_g);
colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Gamma;
colorspaceDPtr->gamma = rCurve.m_fun.m_g;
} else if (rCurve.m_fun.isSRgb()) {
qCDebug(lcIcc) << "fromIccProfile: sRGB gamma detected";
colorspaceDPtr->trc[0] = QColorTransferFunction::fromSRgb();
colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::SRgb;
} else if (rCurve.m_type == QColorTrc::Type::Function) {
if (rCurve.m_fun.isGamma()) {
qCDebug(lcIcc) << "fromIccProfile: Simple gamma detected";
colorspaceDPtr->trc[0] = QColorTransferFunction::fromGamma(rCurve.m_fun.m_g);
colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Gamma;
colorspaceDPtr->gamma = rCurve.m_fun.m_g;
} else if (rCurve.m_fun.isSRgb()) {
qCDebug(lcIcc) << "fromIccProfile: sRGB gamma detected";
colorspaceDPtr->trc[0] = QColorTransferFunction::fromSRgb();
colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::SRgb;
} else {
colorspaceDPtr->trc[0] = rCurve;
colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Custom;
}
} else {
colorspaceDPtr->trc[0] = rCurve;
colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Custom;
}
colorspaceDPtr->trc[1] = colorspaceDPtr->trc[0];
colorspaceDPtr->trc[2] = colorspaceDPtr->trc[0];
} else {