/src/qtbase/src/gui/painting/qrgbafloat.h
Line | Count | Source |
1 | | // Copyright (C) 2021 The Qt Company Ltd. |
2 | | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | | // Qt-Security score:significant reason:default |
4 | | |
5 | | #ifndef QRGBAFLOAT_H |
6 | | #define QRGBAFLOAT_H |
7 | | |
8 | | #include <QtGui/qtguiglobal.h> |
9 | | #include <QtCore/qfloat16.h> |
10 | | |
11 | | #include <algorithm> |
12 | | #include <cmath> |
13 | | #include <type_traits> |
14 | | |
15 | | QT_BEGIN_NAMESPACE |
16 | | |
17 | | template<typename F> |
18 | | class alignas(sizeof(F) * 4) QRgbaFloat |
19 | | { |
20 | | static_assert(std::is_same<F, qfloat16>::value || std::is_same<F, float>::value); |
21 | | public: |
22 | | using Type = F; |
23 | | #if defined(__AVX512FP16__) && QFLOAT16_IS_NATIVE |
24 | | // AVX512FP16 has multiplication instructions |
25 | | using FastType = F; |
26 | | #else |
27 | | // use FP32 for multiplications |
28 | | using FastType = float; |
29 | | #endif |
30 | | F r; |
31 | | F g; |
32 | | F b; |
33 | | F a; |
34 | | |
35 | | static constexpr |
36 | | QRgbaFloat fromRgba64(quint16 red, quint16 green, quint16 blue, quint16 alpha) |
37 | 0 | { |
38 | 0 | constexpr FastType scale = FastType(1.0f / 65535.0f); |
39 | 0 | return QRgbaFloat{ |
40 | 0 | F(red * scale), |
41 | 0 | F(green * scale), |
42 | 0 | F(blue * scale), |
43 | 0 | F(alpha * scale) }; |
44 | 0 | } Unexecuted instantiation: QRgbaFloat<qfloat16>::fromRgba64(unsigned short, unsigned short, unsigned short, unsigned short) Unexecuted instantiation: QRgbaFloat<float>::fromRgba64(unsigned short, unsigned short, unsigned short, unsigned short) |
45 | | |
46 | | static constexpr |
47 | | QRgbaFloat fromRgba(quint8 red, quint8 green, quint8 blue, quint8 alpha) |
48 | 781k | { |
49 | 781k | constexpr FastType scale = FastType(1.0f / 255.0f); |
50 | 781k | return QRgbaFloat{ |
51 | 781k | F(red * scale), |
52 | 781k | F(green * scale), |
53 | 781k | F(blue * scale), |
54 | 781k | F(alpha * scale) }; |
55 | 781k | } QRgbaFloat<qfloat16>::fromRgba(unsigned char, unsigned char, unsigned char, unsigned char) Line | Count | Source | 48 | 157k | { | 49 | 157k | constexpr FastType scale = FastType(1.0f / 255.0f); | 50 | 157k | return QRgbaFloat{ | 51 | 157k | F(red * scale), | 52 | 157k | F(green * scale), | 53 | 157k | F(blue * scale), | 54 | 157k | F(alpha * scale) }; | 55 | 157k | } |
QRgbaFloat<float>::fromRgba(unsigned char, unsigned char, unsigned char, unsigned char) Line | Count | Source | 48 | 623k | { | 49 | 623k | constexpr FastType scale = FastType(1.0f / 255.0f); | 50 | 623k | return QRgbaFloat{ | 51 | 623k | F(red * scale), | 52 | 623k | F(green * scale), | 53 | 623k | F(blue * scale), | 54 | 623k | F(alpha * scale) }; | 55 | 623k | } |
|
56 | | static constexpr |
57 | | QRgbaFloat fromArgb32(uint rgb) |
58 | 781k | { |
59 | 781k | return fromRgba(quint8(rgb >> 16), quint8(rgb >> 8), quint8(rgb), quint8(rgb >> 24)); |
60 | 781k | } QRgbaFloat<qfloat16>::fromArgb32(unsigned int) Line | Count | Source | 58 | 157k | { | 59 | 157k | return fromRgba(quint8(rgb >> 16), quint8(rgb >> 8), quint8(rgb), quint8(rgb >> 24)); | 60 | 157k | } |
QRgbaFloat<float>::fromArgb32(unsigned int) Line | Count | Source | 58 | 623k | { | 59 | 623k | return fromRgba(quint8(rgb >> 16), quint8(rgb >> 8), quint8(rgb), quint8(rgb >> 24)); | 60 | 623k | } |
|
61 | | |
62 | | constexpr bool isOpaque() const { return a >= FastType(1.0f); } |
63 | | constexpr bool isTransparent() const { return a <= FastType(0.0f); } |
64 | | |
65 | 0 | constexpr float red() const { return r; }Unexecuted instantiation: QRgbaFloat<qfloat16>::red() const Unexecuted instantiation: QRgbaFloat<float>::red() const |
66 | 0 | constexpr float green() const { return g; }Unexecuted instantiation: QRgbaFloat<qfloat16>::green() const Unexecuted instantiation: QRgbaFloat<float>::green() const |
67 | 0 | constexpr float blue() const { return b; }Unexecuted instantiation: QRgbaFloat<qfloat16>::blue() const Unexecuted instantiation: QRgbaFloat<float>::blue() const |
68 | 0 | constexpr float alpha() const { return a; }Unexecuted instantiation: QRgbaFloat<qfloat16>::alpha() const Unexecuted instantiation: QRgbaFloat<float>::alpha() const |
69 | | void setRed(float _red) { r = F(_red); } |
70 | | void setGreen(float _green) { g = F(_green); } |
71 | | void setBlue(float _blue) { b = F(_blue); } |
72 | 0 | void setAlpha(float _alpha) { a = F(_alpha); }Unexecuted instantiation: QRgbaFloat<qfloat16>::setAlpha(float) Unexecuted instantiation: QRgbaFloat<float>::setAlpha(float) |
73 | | |
74 | 63.6M | constexpr float redNormalized() const { return clamp01(r); }QRgbaFloat<qfloat16>::redNormalized() const Line | Count | Source | 74 | 1.66M | constexpr float redNormalized() const { return clamp01(r); } |
QRgbaFloat<float>::redNormalized() const Line | Count | Source | 74 | 62.0M | constexpr float redNormalized() const { return clamp01(r); } |
|
75 | 63.6M | constexpr float greenNormalized() const { return clamp01(g); }QRgbaFloat<qfloat16>::greenNormalized() const Line | Count | Source | 75 | 1.66M | constexpr float greenNormalized() const { return clamp01(g); } |
QRgbaFloat<float>::greenNormalized() const Line | Count | Source | 75 | 62.0M | constexpr float greenNormalized() const { return clamp01(g); } |
|
76 | 63.6M | constexpr float blueNormalized() const { return clamp01(b); }QRgbaFloat<qfloat16>::blueNormalized() const Line | Count | Source | 76 | 1.66M | constexpr float blueNormalized() const { return clamp01(b); } |
QRgbaFloat<float>::blueNormalized() const Line | Count | Source | 76 | 62.0M | constexpr float blueNormalized() const { return clamp01(b); } |
|
77 | 63.6M | constexpr float alphaNormalized() const { return clamp01(a); }QRgbaFloat<qfloat16>::alphaNormalized() const Line | Count | Source | 77 | 1.66M | constexpr float alphaNormalized() const { return clamp01(a); } |
QRgbaFloat<float>::alphaNormalized() const Line | Count | Source | 77 | 62.0M | constexpr float alphaNormalized() const { return clamp01(a); } |
|
78 | | |
79 | 45.4M | constexpr quint8 red8() const { return qRound(redNormalized() * FastType(255.0f)); }QRgbaFloat<qfloat16>::red8() const Line | Count | Source | 79 | 1.66M | constexpr quint8 red8() const { return qRound(redNormalized() * FastType(255.0f)); } |
QRgbaFloat<float>::red8() const Line | Count | Source | 79 | 43.7M | constexpr quint8 red8() const { return qRound(redNormalized() * FastType(255.0f)); } |
|
80 | 45.4M | constexpr quint8 green8() const { return qRound(greenNormalized() * FastType(255.0f)); }QRgbaFloat<qfloat16>::green8() const Line | Count | Source | 80 | 1.66M | constexpr quint8 green8() const { return qRound(greenNormalized() * FastType(255.0f)); } |
QRgbaFloat<float>::green8() const Line | Count | Source | 80 | 43.7M | constexpr quint8 green8() const { return qRound(greenNormalized() * FastType(255.0f)); } |
|
81 | 45.4M | constexpr quint8 blue8() const { return qRound(blueNormalized() * FastType(255.0f)); }QRgbaFloat<qfloat16>::blue8() const Line | Count | Source | 81 | 1.66M | constexpr quint8 blue8() const { return qRound(blueNormalized() * FastType(255.0f)); } |
QRgbaFloat<float>::blue8() const Line | Count | Source | 81 | 43.7M | constexpr quint8 blue8() const { return qRound(blueNormalized() * FastType(255.0f)); } |
|
82 | 45.4M | constexpr quint8 alpha8() const { return qRound(alphaNormalized() * FastType(255.0f)); }QRgbaFloat<qfloat16>::alpha8() const Line | Count | Source | 82 | 1.66M | constexpr quint8 alpha8() const { return qRound(alphaNormalized() * FastType(255.0f)); } |
QRgbaFloat<float>::alpha8() const Line | Count | Source | 82 | 43.7M | constexpr quint8 alpha8() const { return qRound(alphaNormalized() * FastType(255.0f)); } |
|
83 | | constexpr uint toArgb32() const |
84 | 45.4M | { |
85 | 45.4M | return uint((alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8()); |
86 | 45.4M | } QRgbaFloat<qfloat16>::toArgb32() const Line | Count | Source | 84 | 1.66M | { | 85 | 1.66M | return uint((alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8()); | 86 | 1.66M | } |
QRgbaFloat<float>::toArgb32() const Line | Count | Source | 84 | 43.7M | { | 85 | 43.7M | return uint((alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8()); | 86 | 43.7M | } |
|
87 | | |
88 | 18.2M | constexpr quint16 red16() const { return qRound(redNormalized() * FastType(65535.0f)); }Unexecuted instantiation: QRgbaFloat<qfloat16>::red16() const QRgbaFloat<float>::red16() const Line | Count | Source | 88 | 18.2M | constexpr quint16 red16() const { return qRound(redNormalized() * FastType(65535.0f)); } |
|
89 | 18.2M | constexpr quint16 green16() const { return qRound(greenNormalized() * FastType(65535.0f)); }Unexecuted instantiation: QRgbaFloat<qfloat16>::green16() const QRgbaFloat<float>::green16() const Line | Count | Source | 89 | 18.2M | constexpr quint16 green16() const { return qRound(greenNormalized() * FastType(65535.0f)); } |
|
90 | 18.2M | constexpr quint16 blue16() const { return qRound(blueNormalized() * FastType(65535.0f)); }Unexecuted instantiation: QRgbaFloat<qfloat16>::blue16() const QRgbaFloat<float>::blue16() const Line | Count | Source | 90 | 18.2M | constexpr quint16 blue16() const { return qRound(blueNormalized() * FastType(65535.0f)); } |
|
91 | 18.2M | constexpr quint16 alpha16() const { return qRound(alphaNormalized() * FastType(65535.0f)); }Unexecuted instantiation: QRgbaFloat<qfloat16>::alpha16() const QRgbaFloat<float>::alpha16() const Line | Count | Source | 91 | 18.2M | constexpr quint16 alpha16() const { return qRound(alphaNormalized() * FastType(65535.0f)); } |
|
92 | | |
93 | | Q_ALWAYS_INLINE constexpr QRgbaFloat premultiplied() const |
94 | 16.9M | { |
95 | 16.9M | return QRgbaFloat{r * a, g * a, b * a, a}; |
96 | 16.9M | } Unexecuted instantiation: QRgbaFloat<qfloat16>::premultiplied() const QRgbaFloat<float>::premultiplied() const Line | Count | Source | 94 | 16.9M | { | 95 | 16.9M | return QRgbaFloat{r * a, g * a, b * a, a}; | 96 | 16.9M | } |
|
97 | | Q_ALWAYS_INLINE constexpr QRgbaFloat unpremultiplied() const |
98 | 0 | { |
99 | 0 | if (a <= F{0.0f}) |
100 | 0 | return QRgbaFloat{}; // default-initialization: zeroes |
101 | 0 | if (a >= F{1.0f}) |
102 | 0 | return *this; |
103 | 0 | const FastType ia = FastType(1.0f) / FastType(a); |
104 | 0 | return QRgbaFloat{F(r * ia), F(g * ia), F(b * ia), F(a)}; |
105 | 0 | } Unexecuted instantiation: QRgbaFloat<qfloat16>::unpremultiplied() const Unexecuted instantiation: QRgbaFloat<float>::unpremultiplied() const |
106 | | constexpr bool operator==(QRgbaFloat f) const |
107 | | { |
108 | | return r == f.r && g == f.g && b == f.b && a == f.a; |
109 | | } |
110 | | constexpr bool operator!=(QRgbaFloat f) const |
111 | | { |
112 | | return !(*this == f); |
113 | | } |
114 | | |
115 | | private: |
116 | | constexpr static FastType clamp01(Type f) |
117 | 254M | { |
118 | 254M | return std::clamp(FastType(f), FastType(0.0f), FastType(1.0f)); |
119 | 254M | } QRgbaFloat<qfloat16>::clamp01(qfloat16) Line | Count | Source | 117 | 6.66M | { | 118 | 6.66M | return std::clamp(FastType(f), FastType(0.0f), FastType(1.0f)); | 119 | 6.66M | } |
QRgbaFloat<float>::clamp01(float) Line | Count | Source | 117 | 248M | { | 118 | 248M | return std::clamp(FastType(f), FastType(0.0f), FastType(1.0f)); | 119 | 248M | } |
|
120 | | }; |
121 | | |
122 | | typedef QRgbaFloat<qfloat16> QRgbaFloat16; |
123 | | typedef QRgbaFloat<float> QRgbaFloat32; |
124 | | |
125 | | QT_END_NAMESPACE |
126 | | |
127 | | #endif // QRGBAFLOAT_H |