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