diff options
| author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2024-04-11 15:00:32 +0200 |
|---|---|---|
| committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2024-05-16 19:40:03 +0200 |
| commit | abed1a41e1dfc6b1cc6eaa7cc8072c6638230811 (patch) | |
| tree | c4d1a6862b4b48c45d3e6a0e2ef841441f354fbb /src | |
| parent | 7dbf070dd1a15ea99b3d5d2e528c9d4c75eafff6 (diff) | |
Merge two color conversion methods
We can do both conversions with the logic from
applyElementListTransform with a few simple changes.
Change-Id: I560a2954b3a4c1acfee57813fa0caa418b1fc5d6
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src')
| -rw-r--r-- | src/gui/painting/qcolorspace.cpp | 8 | ||||
| -rw-r--r-- | src/gui/painting/qcolortransform.cpp | 116 | ||||
| -rw-r--r-- | src/gui/painting/qcolortransform_p.h | 6 |
3 files changed, 39 insertions, 91 deletions
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index 7a1d34a4083..f21e6ec7382 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -448,11 +448,15 @@ QColorTransform QColorSpacePrivate::transformationToXYZ() const transform.d = ptr; ptr->colorSpaceIn = this; ptr->colorSpaceOut = this; - // Convert to XYZ relative to our white point, not the regular D50 white point. if (isThreeComponentMatrix()) - ptr->colorMatrix = QColorMatrix::chromaticAdaptation(whitePoint).inverted() * toXyz; + ptr->colorMatrix = toXyz; else ptr->colorMatrix = QColorMatrix::identity(); + // Convert to XYZ relative to our white point, not the regular D50 white point. + if (!chad.isNull()) + ptr->colorMatrix = chad.inverted() * ptr->colorMatrix; + else if (!whitePoint.isNull()) + ptr->colorMatrix = QColorMatrix::chromaticAdaptation(whitePoint).inverted() * ptr->colorMatrix; return transform; } diff --git a/src/gui/painting/qcolortransform.cpp b/src/gui/painting/qcolortransform.cpp index aac07bdc090..33b1dcdeb01 100644 --- a/src/gui/painting/qcolortransform.cpp +++ b/src/gui/painting/qcolortransform.cpp @@ -1640,7 +1640,7 @@ void QColorTransformPrivate::applyConvertIn(const S *src, QColorVector *buffer, loadUnpremultiplied(buffer, src, len, this); if (!colorSpaceOut->isThreeComponentMatrix()) - applyMatrix<DoClamp>(buffer, len, colorMatrix); // colorMatrix should have the first half only. + applyMatrix<DoClamp>(buffer, len, colorSpaceIn->toXyz); return; } } @@ -1666,7 +1666,7 @@ void QColorTransformPrivate::applyConvertOut(D *dst, const S *src, QColorVector // Avoid compiling this part for D=QCmyk32: if constexpr (!std::is_same_v<D, QCmyk32>) { if (colorSpaceOut->isThreeComponentMatrix()) { - applyMatrix<doClamp>(buffer, len, colorMatrix); // colorMatrix should have the latter half only. + applyMatrix<doClamp>(buffer, len, colorMatrix); if constexpr (std::is_same_v<S, QCmyk32>) { storeOpaque(dst, buffer, len, this); @@ -1695,14 +1695,34 @@ void QColorTransformPrivate::applyConvertOut(D *dst, const S *src, QColorVector storeUnpremultipliedLUT(dst, src, buffer, len); } -template<typename D, typename S> -void QColorTransformPrivate::applyElementListTransform(D *dst, const S *src, qsizetype count, TransformFlags flags) const +/*! + \internal + Adapt Profile Connecting Color spaces. +*/ +void QColorTransformPrivate::pcsAdapt(QColorVector *buffer, qsizetype count) const { - Q_ASSERT(!colorSpaceIn->isThreeComponentMatrix() || !colorSpaceOut->isThreeComponentMatrix()); + // Match Profile Connection Spaces (PCS): + if (colorSpaceOut->isPcsLab && !colorSpaceIn->isPcsLab) { + for (qsizetype j = 0; j < count; ++j) + buffer[j] = buffer[j].xyzToLab(); + } else if (colorSpaceIn->isPcsLab && !colorSpaceOut->isPcsLab) { + for (qsizetype j = 0; j < count; ++j) + buffer[j] = buffer[j].labToXyz(); + } +} - if (!colorMatrix.isValid()) - return; +/*! + \internal + Applies the color transformation on \a count S pixels starting from + \a src and stores the result in \a dst as D pixels . + Assumes unpremultiplied data by default. Set \a flags to change defaults. + + \sa prepare() +*/ +template<typename D, typename S> +void QColorTransformPrivate::apply(D *dst, const S *src, qsizetype count, TransformFlags flags) const +{ if (colorSpaceIn->isThreeComponentMatrix()) updateLutsIn(); if (colorSpaceOut->isThreeComponentMatrix()) @@ -1715,14 +1735,7 @@ void QColorTransformPrivate::applyElementListTransform(D *dst, const S *src, qsi applyConvertIn(src + i, buffer, len, flags); - // Match Profile Connection Spaces (PCS): - if (colorSpaceOut->isPcsLab && !colorSpaceIn->isPcsLab) { - for (qsizetype j = 0; j < len; ++j) - buffer[j] = buffer[j].xyzToLab(); - } else if (colorSpaceIn->isPcsLab && !colorSpaceOut->isPcsLab) { - for (qsizetype j = 0; j < len; ++j) - buffer[j] = buffer[j].labToXyz(); - } + pcsAdapt(buffer, len); applyConvertOut(dst + i, src + i, buffer, len, flags); @@ -1730,64 +1743,6 @@ void QColorTransformPrivate::applyElementListTransform(D *dst, const S *src, qsi } } -template<typename D, typename S> -void QColorTransformPrivate::applyThreeComponentMatrix(D *dst, const S *src, qsizetype count, TransformFlags flags) const -{ - Q_ASSERT(colorSpaceIn->isThreeComponentMatrix() && colorSpaceOut->isThreeComponentMatrix()); - - if (!colorMatrix.isValid()) - return; - - updateLutsIn(); - updateLutsOut(); - - bool doApplyMatrix = !colorMatrix.isIdentity(); - constexpr ApplyMatrixForm doClamp = (std::is_same_v<D, QRgbaFloat16> || std::is_same_v<D, QRgbaFloat32>) ? DoNotClamp : DoClamp; - - QUninitialized<QColorVector, WorkBlockSize> buffer; - qsizetype i = 0; - while (i < count) { - const qsizetype len = qMin(count - i, WorkBlockSize); - if (flags & InputPremultiplied) - loadPremultiplied(buffer, src + i, len, this); - else - loadUnpremultiplied(buffer, src + i, len, this); - - if (doApplyMatrix) - applyMatrix<doClamp>(buffer, len, colorMatrix); - else - clampIfNeeded<doClamp>(buffer, len); - - if (flags & InputOpaque) - storeOpaque(dst + i, buffer, len, this); - else if (flags & OutputPremultiplied) - storePremultiplied(dst + i, src + i, buffer, len, this); - else - storeUnpremultiplied(dst + i, src + i, buffer, len, this); - - i += len; - } -} - -/*! - \internal - Applies the color transformation on \a count S pixels starting from - \a src and stores the result in \a dst as D pixels . - - Assumes unpremultiplied data by default. Set \a flags to change defaults. - - \sa prepare() -*/ -template<typename D, typename S> -void QColorTransformPrivate::apply(D *dst, const S *src, qsizetype count, TransformFlags flags) const -{ - if constexpr (!std::is_same_v<D, QCmyk32> && !std::is_same_v<S, QCmyk32>) { - if (isThreeComponentMatrix()) - return applyThreeComponentMatrix<D, S>(dst, src, count, flags); - } - applyElementListTransform<D, S>(dst, src, count, flags); -} - /*! \internal Is to be called on a color-transform to XYZ, returns only luminance values. @@ -1970,15 +1925,6 @@ template void QColorTransformPrivate::apply<QRgbaFloat32, QCmyk32>(QRgbaFloat32 template void QColorTransformPrivate::apply<QRgbaFloat32, QRgba64>(QRgbaFloat32 *dst, const QRgba64 *src, qsizetype count, TransformFlags flags) const; template void QColorTransformPrivate::apply<QRgbaFloat32, QRgbaFloat32>(QRgbaFloat32 *dst, const QRgbaFloat32 *src, qsizetype count, TransformFlags flags) const; -bool QColorTransformPrivate::isThreeComponentMatrix() const -{ - if (colorSpaceIn && !colorSpaceIn->isThreeComponentMatrix()) - return false; - if (colorSpaceOut && !colorSpaceOut->isThreeComponentMatrix()) - return false; - return true; -} - /*! \internal */ @@ -1991,7 +1937,7 @@ bool QColorTransformPrivate::isIdentity() const if (colorSpaceIn && colorSpaceOut) { if (colorSpaceIn->equals(colorSpaceOut.constData())) return true; - if (!isThreeComponentMatrix()) + if (!colorSpaceIn->isThreeComponentMatrix() || !colorSpaceOut->isThreeComponentMatrix()) return false; if (colorSpaceIn->transferFunction != colorSpaceOut->transferFunction) return false; @@ -2001,7 +1947,9 @@ bool QColorTransformPrivate::isIdentity() const && colorSpaceIn->trc[2] == colorSpaceOut->trc[2]; } } else { - if (!isThreeComponentMatrix()) + if (colorSpaceIn && !colorSpaceIn->isThreeComponentMatrix()) + return false; + if (colorSpaceOut && !colorSpaceOut->isThreeComponentMatrix()) return false; if (colorSpaceIn && colorSpaceIn->transferFunction != QColorSpace::TransferFunction::Linear) return false; diff --git a/src/gui/painting/qcolortransform_p.h b/src/gui/painting/qcolortransform_p.h index 59ea6a2405b..c74fe100eb1 100644 --- a/src/gui/painting/qcolortransform_p.h +++ b/src/gui/painting/qcolortransform_p.h @@ -37,7 +37,6 @@ public: void updateLutsIn() const; void updateLutsOut() const; bool isIdentity() const; - bool isThreeComponentMatrix() const; Q_GUI_EXPORT void prepare(); enum TransformFlag { @@ -60,14 +59,11 @@ public: void applyReturnGray(D *dst, const S *src, qsizetype count, TransformFlags flags) const; private: + void pcsAdapt(QColorVector *buffer, qsizetype len) const; template<typename S> void applyConvertIn(const S *src, QColorVector *buffer, qsizetype len, TransformFlags flags) const; template<typename D, typename S> void applyConvertOut(D *dst, const S *src, QColorVector *buffer, qsizetype len, TransformFlags flags) const; - template<typename D, typename S> - void applyElementListTransform(D *dst, const S *src, qsizetype count, TransformFlags flags) const; - template<typename D, typename S> - void applyThreeComponentMatrix(D *dst, const S *src, qsizetype count, TransformFlags flags) const; }; QT_END_NAMESPACE |
