Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-04 09:20:14

0001 // Copyright (C) 2016 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
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     // Make sure that the representation always has the order: red green blue alpha, independent
0018     // of byte order. This way, vector operations that assume 4 16-bit values see the correct ones.
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 // little endian:
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         // Expand the range so that 0x00 maps to 0x0000 and 0xff maps to 0xffff.
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 // QRGBA64_H