File indexing completed on 2026-10-04 09:20:14
0001
0002
0003
0004 #ifndef QRGBA64_H
0005 #define QRGBA64_H
0006
0007 #include <QtGui/qtguiglobal.h>
0008
0009 #include <QtCore/qhashfunctions.h>
0010 #include <QtCore/qprocessordetection.h>
0011
0012 QT_BEGIN_NAMESPACE
0013
0014 class QRgba64 {
0015 quint64 rgba;
0016
0017
0018
0019 enum Shifts {
0020 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
0021 RedShift = 48,
0022 GreenShift = 32,
0023 BlueShift = 16,
0024 AlphaShift = 0
0025 #else
0026 RedShift = 0,
0027 GreenShift = 16,
0028 BlueShift = 32,
0029 AlphaShift = 48
0030 #endif
0031 };
0032
0033 Q_ALWAYS_INLINE explicit constexpr QRgba64(quint64 c) : rgba(c) { }
0034 public:
0035 QRgba64() = default;
0036
0037 constexpr static
0038 QRgba64 fromRgba64(quint64 c)
0039 {
0040 return QRgba64(c);
0041 }
0042 constexpr static
0043 QRgba64 fromRgba64(quint16 red, quint16 green, quint16 blue, quint16 alpha)
0044 {
0045 return fromRgba64(quint64(red) << RedShift
0046 | quint64(green) << GreenShift
0047 | quint64(blue) << BlueShift
0048 | quint64(alpha) << AlphaShift);
0049 }
0050 constexpr static QRgba64 fromRgba(quint8 red, quint8 green, quint8 blue, quint8 alpha)
0051 {
0052 QRgba64 rgb64 = fromRgba64(red, green, blue, alpha);
0053
0054 rgb64.rgba |= rgb64.rgba << 8;
0055 return rgb64;
0056 }
0057 constexpr static
0058 QRgba64 fromArgb32(uint rgb)
0059 {
0060 return fromRgba(quint8(rgb >> 16), quint8(rgb >> 8), quint8(rgb), quint8(rgb >> 24));
0061 }
0062
0063 constexpr bool isOpaque() const
0064 {
0065 return (rgba & alphaMask()) == alphaMask();
0066 }
0067 constexpr bool isTransparent() const
0068 {
0069 return (rgba & alphaMask()) == 0;
0070 }
0071
0072 constexpr quint16 red() const { return quint16(rgba >> RedShift); }
0073 constexpr quint16 green() const { return quint16(rgba >> GreenShift); }
0074 constexpr quint16 blue() const { return quint16(rgba >> BlueShift); }
0075 constexpr quint16 alpha() const { return quint16(rgba >> AlphaShift); }
0076 void setRed(quint16 _red) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << RedShift)) | (quint64(_red) << RedShift); }
0077 void setGreen(quint16 _green) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << GreenShift)) | (quint64(_green) << GreenShift); }
0078 void setBlue(quint16 _blue) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << BlueShift)) | (quint64(_blue) << BlueShift); }
0079 void setAlpha(quint16 _alpha) { rgba = (rgba & ~(Q_UINT64_C(0xffff) << AlphaShift)) | (quint64(_alpha) << AlphaShift); }
0080
0081 constexpr quint8 red8() const { return div_257(red()); }
0082 constexpr quint8 green8() const { return div_257(green()); }
0083 constexpr quint8 blue8() const { return div_257(blue()); }
0084 constexpr quint8 alpha8() const { return div_257(alpha()); }
0085 constexpr uint toArgb32() const
0086 {
0087 quint64 br = rgba & Q_UINT64_C(0xffff0000ffff);
0088 quint64 ag = (rgba >> 16) & Q_UINT64_C(0xffff0000ffff);
0089 br += Q_UINT64_C(0x8000000080);
0090 ag += Q_UINT64_C(0x8000000080);
0091 br = (br - ((br >> 8) & Q_UINT64_C(0xffff0000ffff))) >> 8;
0092 ag = (ag - ((ag >> 8) & Q_UINT64_C(0xffff0000ffff)));
0093 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
0094 return ((br << 24) & 0xff000000)
0095 | ((ag >> 24) & 0xff0000)
0096 | ((br >> 24) & 0xff00)
0097 | ((ag >> 8) & 0xff);
0098 #else
0099 return ((ag >> 16) & 0xff000000)
0100 | ((br << 16) & 0xff0000)
0101 | (ag & 0xff00)
0102 | ((br >> 32) & 0xff);
0103 #endif
0104 }
0105 constexpr ushort toRgb16() const
0106 {
0107 return ushort((red() & 0xf800) | ((green() >> 10) << 5) | (blue() >> 11));
0108 }
0109
0110 constexpr QRgba64 premultiplied() const
0111 {
0112 if (isOpaque())
0113 return *this;
0114 if (isTransparent())
0115 return QRgba64::fromRgba64(0);
0116 const quint64 a = alpha();
0117 quint64 br = (rgba & Q_UINT64_C(0xffff0000ffff)) * a;
0118 quint64 ag = ((rgba >> 16) & Q_UINT64_C(0xffff0000ffff)) * a;
0119 br = (br + ((br >> 16) & Q_UINT64_C(0xffff0000ffff)) + Q_UINT64_C(0x800000008000));
0120 ag = (ag + ((ag >> 16) & Q_UINT64_C(0xffff0000ffff)) + Q_UINT64_C(0x800000008000));
0121 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
0122 ag = ag & Q_UINT64_C(0xffff0000ffff0000);
0123 br = (br >> 16) & Q_UINT64_C(0xffff00000000);
0124 return fromRgba64(a | br | ag);
0125 #else
0126 br = (br >> 16) & Q_UINT64_C(0xffff0000ffff);
0127 ag = ag & Q_UINT64_C(0xffff0000);
0128 return fromRgba64((a << 48) | br | ag);
0129 #endif
0130 }
0131
0132 constexpr QRgba64 unpremultiplied() const
0133 {
0134 #if Q_PROCESSOR_WORDSIZE < 8
0135 return unpremultiplied_32bit();
0136 #else
0137 return unpremultiplied_64bit();
0138 #endif
0139 }
0140
0141 constexpr operator quint64() const
0142 {
0143 return rgba;
0144 }
0145
0146 QRgba64 &operator=(quint64 _rgba) noexcept
0147 {
0148 rgba = _rgba;
0149 return *this;
0150 }
0151
0152 private:
0153 friend constexpr size_t qHash(QRgba64 key, size_t seed = 0) noexcept
0154 { return QHashPrivate::ex1to2arg(key.rgba, seed); }
0155
0156 Q_ALWAYS_INLINE static constexpr quint64 alphaMask() { return Q_UINT64_C(0xffff) << AlphaShift; }
0157
0158 Q_ALWAYS_INLINE static constexpr quint8 div_257_floor(uint x) { return quint8((x - (x >> 8)) >> 8); }
0159 Q_ALWAYS_INLINE static constexpr quint8 div_257(quint16 x) { return div_257_floor(x + 128U); }
0160 Q_ALWAYS_INLINE constexpr QRgba64 unpremultiplied_32bit() const
0161 {
0162 if (isOpaque() || isTransparent())
0163 return *this;
0164 const quint32 a = alpha();
0165 const quint16 r = quint16((red() * 0xffff + a/2) / a);
0166 const quint16 g = quint16((green() * 0xffff + a/2) / a);
0167 const quint16 b = quint16((blue() * 0xffff + a/2) / a);
0168 return fromRgba64(r, g, b, quint16(a));
0169 }
0170 Q_ALWAYS_INLINE constexpr QRgba64 unpremultiplied_64bit() const
0171 {
0172 if (isOpaque() || isTransparent())
0173 return *this;
0174 const quint64 a = alpha();
0175 const quint64 fa = (Q_UINT64_C(0xffff00008000) + a/2) / a;
0176 const quint16 r = quint16((red() * fa + 0x80000000) >> 32);
0177 const quint16 g = quint16((green() * fa + 0x80000000) >> 32);
0178 const quint16 b = quint16((blue() * fa + 0x80000000) >> 32);
0179 return fromRgba64(r, g, b, quint16(a));
0180 }
0181 };
0182
0183 Q_DECLARE_TYPEINFO(QRgba64, Q_PRIMITIVE_TYPE);
0184
0185 constexpr inline QRgba64 qRgba64(quint16 r, quint16 g, quint16 b, quint16 a)
0186 {
0187 return QRgba64::fromRgba64(r, g, b, a);
0188 }
0189
0190 constexpr inline QRgba64 qRgba64(quint64 c)
0191 {
0192 return QRgba64::fromRgba64(c);
0193 }
0194
0195 constexpr inline QRgba64 qPremultiply(QRgba64 c)
0196 {
0197 return c.premultiplied();
0198 }
0199
0200 constexpr inline QRgba64 qUnpremultiply(QRgba64 c)
0201 {
0202 return c.unpremultiplied();
0203 }
0204
0205 inline constexpr uint qRed(QRgba64 rgb)
0206 { return rgb.red8(); }
0207
0208 inline constexpr uint qGreen(QRgba64 rgb)
0209 { return rgb.green8(); }
0210
0211 inline constexpr uint qBlue(QRgba64 rgb)
0212 { return rgb.blue8(); }
0213
0214 inline constexpr uint qAlpha(QRgba64 rgb)
0215 { return rgb.alpha8(); }
0216
0217 QT_END_NAMESPACE
0218
0219 #endif