diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-01-29 11:41:31 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-10 12:49:06 +0100 |
commit | a7b8ef08415b8056661c3db5950842ee546891b9 (patch) | |
tree | f010dbec1421980535be48705b51b7c62d079a16 /src/gui/painting/qrgb.h | |
parent | 143d591aab7a2d244913e9d13f079de05eb7a65c (diff) |
Export optimized premultiply and unpremultiply methods
This patch optimizes the unpremultiply method further by using a
lookup table to avoid any divisions at all.
The opportunity is taken to export both premultiply and unpremultiply
since they are commonly used methods relevant to the exported QRgb type
that can be both premultiplied and unpremultipled ARGB.
[ChangeLog][QtGui][QColor] Exported highly optimized methods for
premultiply and unpremultiply of QRgb values.
Change-Id: I658bcf57b0bc73c34c1765b64617d43b63ae820b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
Diffstat (limited to 'src/gui/painting/qrgb.h')
-rw-r--r-- | src/gui/painting/qrgb.h | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/gui/painting/qrgb.h b/src/gui/painting/qrgb.h index 3c2bc5b97a..d8e19302d1 100644 --- a/src/gui/painting/qrgb.h +++ b/src/gui/painting/qrgb.h @@ -43,6 +43,7 @@ #define QRGB_H #include <QtCore/qglobal.h> +#include <QtCore/qprocessordetection.h> QT_BEGIN_NAMESPACE @@ -79,6 +80,48 @@ inline Q_DECL_CONSTEXPR int qGray(QRgb rgb) // convert RGB to gra inline Q_DECL_CONSTEXPR bool qIsGray(QRgb rgb) { return qRed(rgb) == qGreen(rgb) && qRed(rgb) == qBlue(rgb); } + +#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit version +inline QRgb qPremultiply(QRgb x) +{ + const uint a = qAlpha(x); + quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; + t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8; + t &= 0x000000ff00ff00ff; + return (uint(t)) | (uint(t >> 24)) | (a << 24); +} +#else // 32-bit version +inline QRgb qPremultiply(QRgb x) +{ + const uint a = qAlpha(x); + uint t = (x & 0xff00ff) * a; + t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; + t &= 0xff00ff; + + x = ((x >> 8) & 0xff) * a; + x = (x + ((x >> 8) & 0xff) + 0x80); + x &= 0xff00; + x |= t | (a << 24); + return x; +} +#endif + +Q_GUI_EXPORT extern const uint qt_inv_premul_factor[]; + +inline QRgb qUnpremultiply(QRgb p) +{ + const uint alpha = qAlpha(p); + // Alpha 255 and 0 are the two most common values, which makes them beneficial to short-cut. + if (alpha == 255) + return p; + if (alpha == 0) + return 0; + // (p*(0x00ff00ff/alpha)) >> 16 == (p*255)/alpha for all p and alpha <= 256. + const uint invAlpha = qt_inv_premul_factor[alpha]; + // We add 0x8000 to get even rounding. The rounding also ensures that qPremultiply(qUnpremultiply(p)) == p for all p. + return qRgba((qRed(p)*invAlpha + 0x8000)>>16, (qGreen(p)*invAlpha + 0x8000)>>16, (qBlue(p)*invAlpha + 0x8000)>>16, alpha); +} + QT_END_NAMESPACE #endif // QRGB_H |