Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qpixellayout_p.h
Go to the documentation of this file.
1// Copyright (C) 2020 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 QPIXELLAYOUT_P_H
6#define QPIXELLAYOUT_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/qlist.h>
20#include <QtGui/qimage.h>
21#include <QtGui/qrgba64.h>
22#include <QtGui/qrgbafloat.h>
23#include <QtCore/private/qglobal_p.h>
24
25QT_BEGIN_NAMESPACE
26
27enum QtPixelOrder {
28 PixelOrderRGB,
29 PixelOrderBGR
30};
31
32template<enum QtPixelOrder> inline uint qConvertArgb32ToA2rgb30(QRgb);
33
34template<enum QtPixelOrder> inline uint qConvertRgb32ToRgb30(QRgb);
35
36template<enum QtPixelOrder> inline QRgb qConvertA2rgb30ToArgb32(uint c);
37
38// A combined unpremultiply and premultiply with new simplified alpha.
39// Needed when alpha loses precision relative to other colors during conversion (ARGB32 -> A2RGB30).
40template<unsigned int Shift>
41inline QRgb qRepremultiply(QRgb p)
42{
43 const uint alpha = qAlpha(p);
44 if (alpha == 255 || alpha == 0)
45 return p;
46 p = qUnpremultiply(p);
47 constexpr uint mult = 255 / (255 >> Shift);
48 const uint newAlpha = mult * (alpha >> Shift);
49 p = (p & ~0xff000000) | (newAlpha<<24);
50 return qPremultiply(p);
51}
52
53template<unsigned int Shift>
55{
56 const uint alpha = p.alpha();
57 if (alpha == 65535 || alpha == 0)
58 return p;
60 constexpr uint mult = 65535 / (65535 >> Shift);
61 p.setAlpha(mult * (alpha >> Shift));
62 return p.premultiplied();
63}
64
65template<>
66inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c)
67{
68 c = qRepremultiply<6>(c);
69 return (c & 0xc0000000)
70 | (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000))
71 | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
72 | (((c >> 14) & 0x000003fc) | ((c >> 22) & 0x00000003));
73}
74
75template<>
76inline uint qConvertArgb32ToA2rgb30<PixelOrderRGB>(QRgb c)
77{
78 c = qRepremultiply<6>(c);
79 return (c & 0xc0000000)
80 | (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000))
81 | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
82 | (((c << 2) & 0x000003fc) | ((c >> 6) & 0x00000003));
83}
84
85template<>
86inline uint qConvertRgb32ToRgb30<PixelOrderBGR>(QRgb c)
87{
88 return 0xc0000000
89 | (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000))
90 | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
91 | (((c >> 14) & 0x000003fc) | ((c >> 22) & 0x00000003));
92}
93
94template<>
95inline uint qConvertRgb32ToRgb30<PixelOrderRGB>(QRgb c)
96{
97 return 0xc0000000
98 | (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000))
99 | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
100 | (((c << 2) & 0x000003fc) | ((c >> 6) & 0x00000003));
101}
102
103template<>
104inline QRgb qConvertA2rgb30ToArgb32<PixelOrderBGR>(uint c)
105{
106 uint a = c >> 30;
107 a |= a << 2;
108 a |= a << 4;
109 return (a << 24)
110 | ((c << 14) & 0x00ff0000)
111 | ((c >> 4) & 0x0000ff00)
112 | ((c >> 22) & 0x000000ff);
113}
114
115template<>
116inline QRgb qConvertA2rgb30ToArgb32<PixelOrderRGB>(uint c)
117{
118 uint a = c >> 30;
119 a |= a << 2;
120 a |= a << 4;
121 return (a << 24)
122 | ((c >> 6) & 0x00ff0000)
123 | ((c >> 4) & 0x0000ff00)
124 | ((c >> 2) & 0x000000ff);
125}
126
127template<enum QtPixelOrder> inline QRgba64 qConvertA2rgb30ToRgb64(uint rgb);
128
129template<>
130inline QRgba64 qConvertA2rgb30ToRgb64<PixelOrderBGR>(uint rgb)
131{
132 quint16 alpha = rgb >> 30;
133 quint16 blue = (rgb >> 20) & 0x3ff;
134 quint16 green = (rgb >> 10) & 0x3ff;
135 quint16 red = rgb & 0x3ff;
136 // Expand the range.
137 alpha |= (alpha << 2);
138 alpha |= (alpha << 4);
139 alpha |= (alpha << 8);
140 red = (red << 6) | (red >> 4);
141 green = (green << 6) | (green >> 4);
142 blue = (blue << 6) | (blue >> 4);
143 return qRgba64(red, green, blue, alpha);
144}
145
146template<>
147inline QRgba64 qConvertA2rgb30ToRgb64<PixelOrderRGB>(uint rgb)
148{
149 quint16 alpha = rgb >> 30;
150 quint16 red = (rgb >> 20) & 0x3ff;
151 quint16 green = (rgb >> 10) & 0x3ff;
152 quint16 blue = rgb & 0x3ff;
153 // Expand the range.
154 alpha |= (alpha << 2);
155 alpha |= (alpha << 4);
156 alpha |= (alpha << 8);
157 red = (red << 6) | (red >> 4);
158 green = (green << 6) | (green >> 4);
159 blue = (blue << 6) | (blue >> 4);
160 return qRgba64(red, green, blue, alpha);
161}
162
163template<enum QtPixelOrder> inline unsigned int qConvertRgb64ToRgb30(QRgba64);
164
165template<>
166inline unsigned int qConvertRgb64ToRgb30<PixelOrderBGR>(QRgba64 c)
167{
168 c = qRepremultiply<14>(c);
169 const uint a = c.alpha() >> 14;
170 const uint r = c.red() >> 6;
171 const uint g = c.green() >> 6;
172 const uint b = c.blue() >> 6;
173 return (a << 30) | (b << 20) | (g << 10) | r;
174}
175
176template<>
177inline unsigned int qConvertRgb64ToRgb30<PixelOrderRGB>(QRgba64 c)
178{
179 c = qRepremultiply<14>(c);
180 const uint a = c.alpha() >> 14;
181 const uint r = c.red() >> 6;
182 const uint g = c.green() >> 6;
183 const uint b = c.blue() >> 6;
184 return (a << 30) | (r << 20) | (g << 10) | b;
185}
186
188{
189 return QRgbaFloat16::fromRgba64(c.red(), c.green(), c.blue(), c.alpha());
190}
191
193{
194 return QRgbaFloat32::fromRgba64(c.red(), c.green(), c.blue(), c.alpha());
195}
196
197inline uint qRgbSwapRgb30(uint c)
198{
199 const uint ag = c & 0xc00ffc00;
200 const uint rb = c & 0x3ff003ff;
201 return ag | (rb << 20) | (rb >> 20);
202}
203
204#if Q_BYTE_ORDER == Q_BIG_ENDIAN
205static inline quint32 RGBA2ARGB(quint32 x) {
206 quint32 rgb = x >> 8;
207 quint32 a = x << 24;
208 return a | rgb;
209}
210
211static inline quint32 ARGB2RGBA(quint32 x) {
212 quint32 rgb = x << 8;
213 quint32 a = x >> 24;
214 return a | rgb;
215}
216#else
217static inline quint32 RGBA2ARGB(quint32 x) {
218 // RGBA8888 is ABGR32 on little endian.
219 quint32 ag = x & 0xff00ff00;
220 quint32 rg = x & 0x00ff00ff;
221 return ag | (rg << 16) | (rg >> 16);
222}
223
224static inline quint32 ARGB2RGBA(quint32 x) {
225 return RGBA2ARGB(x);
226}
227#endif
228
229// We manually unalias the variables to make sure the compiler
230// fully optimizes both aliased and unaliased cases.
231#define UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion)
232 if (src == buffer) {
233 for (int i = 0; i < count; ++i)
234 buffer[i] = conversion(buffer[i]);
235 } else {
236 for (int i = 0; i < count; ++i)
237 buffer[i] = conversion(src[i]);
238 }
239
240
241inline const uint *qt_convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count)
242{
243 UNALIASED_CONVERSION_LOOP(buffer, src, count, qPremultiply);
244 return buffer;
245}
246
247inline const uint *qt_convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count)
248{
249 UNALIASED_CONVERSION_LOOP(buffer, src, count, [](uint s) { return qPremultiply(RGBA2ARGB(s));});
250 return buffer;
251}
252
253template<bool RGBA> void qt_convertRGBA64ToARGB32(uint *dst, const QRgba64 *src, int count);
254
256 int x;
257 int y;
258};
259
260typedef const uint *(QT_FASTCALL *FetchAndConvertPixelsFunc)(uint *buffer, const uchar *src,
261 int index, int count,
262 const QList<QRgb> *clut,
263 QDitherInfo *dither);
264typedef void(QT_FASTCALL *ConvertAndStorePixelsFunc)(uchar *dest, const uint *src, int index,
265 int count, const QList<QRgb> *clut,
266 QDitherInfo *dither);
267
268typedef const QRgba64 *(QT_FASTCALL *FetchAndConvertPixelsFunc64)(QRgba64 *buffer, const uchar *src,
269 int index, int count,
270 const QList<QRgb> *clut,
271 QDitherInfo *dither);
272typedef void(QT_FASTCALL *ConvertAndStorePixelsFunc64)(uchar *dest, const QRgba64 *src, int index,
273 int count, const QList<QRgb> *clut,
274 QDitherInfo *dither);
275
276typedef const QRgbaFloat32 *(QT_FASTCALL *FetchAndConvertPixelsFuncFP)(QRgbaFloat32 *buffer, const uchar *src, int index, int count,
277 const QList<QRgb> *clut, QDitherInfo *dither);
278typedef void (QT_FASTCALL *ConvertAndStorePixelsFuncFP)(uchar *dest, const QRgbaFloat32 *src, int index, int count,
279 const QList<QRgb> *clut, QDitherInfo *dither);
280typedef void (QT_FASTCALL *ConvertFunc)(uint *buffer, int count, const QList<QRgb> *clut);
281typedef void (QT_FASTCALL *Convert64Func)(QRgba64 *buffer, int count);
282typedef void (QT_FASTCALL *ConvertFPFunc)(QRgbaFloat32 *buffer, int count);
283typedef void (QT_FASTCALL *Convert64ToFPFunc)(QRgbaFloat32 *buffer, const quint64 *src, int count);
284
285typedef const QRgba64 *(QT_FASTCALL *ConvertTo64Func)(QRgba64 *buffer, const uint *src, int count,
286 const QList<QRgb> *clut, QDitherInfo *dither);
287typedef const QRgbaFloat32 *(QT_FASTCALL *ConvertToFPFunc)(QRgbaFloat32 *buffer, const uint *src, int count,
288 const QList<QRgb> *clut, QDitherInfo *dither);
289typedef void (QT_FASTCALL *RbSwapFunc)(uchar *dst, const uchar *src, int count);
290
291typedef void (*MemRotateFunc)(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl);
292
321
322extern ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats];
323
324#if QT_CONFIG(raster_fp)
325extern ConvertToFPFunc qConvertToRGBA32F[];
326extern FetchAndConvertPixelsFuncFP qFetchToRGBA32F[];
327extern ConvertAndStorePixelsFuncFP qStoreFromRGBA32F[];
328#endif
329
331
333
334QT_END_NAMESPACE
335
336#endif // QPIXELLAYOUT_P_H
constexpr QRgba64 unpremultiplied() const
Definition qrgba64.h:131
constexpr QRgba64 premultiplied() const
Definition qrgba64.h:109
Combined button and popup list for selecting options.
QRgbaFloat< float > QRgbaFloat32
static QT_BEGIN_NAMESPACE const int numCompositionFunctions
constexpr QRgbaFloat32 qConvertRgb64ToRgbaF32(QRgba64 c)
const uint * qt_convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count)
QPixelLayout qPixelLayouts[]
static quint32 RGBA2ARGB(quint32 x)
QRgba64 qRepremultiply(QRgba64 p)
#define UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion)
const uint *(QT_FASTCALL * FetchAndConvertPixelsFunc)(uint *buffer, const uchar *src, int index, int count, const QList< QRgb > *clut, QDitherInfo *dither)
ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats]
uint qConvertArgb32ToA2rgb30(QRgb)
constexpr QRgbaFloat16 qConvertRgb64ToRgbaF16(QRgba64 c)
void qt_convertRGBA64ToARGB32(uint *dst, const QRgba64 *src, int count)
static quint32 ARGB2RGBA(quint32 x)
QRgb qConvertA2rgb30ToArgb32(uint c)
MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3]
void(* MemRotateFunc)(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
unsigned int qConvertRgb64ToRgb30(QRgba64)
QRgba64 qConvertA2rgb30ToRgb64(uint rgb)
QRgb qRepremultiply(QRgb p)
const uint * qt_convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count)
uint qRgbSwapRgb30(uint c)
uint qConvertRgb32ToRgb30(QRgb)
ConvertFunc convertToARGB32PM
ConvertAndStorePixelsFunc storeFromARGB32PM
ConvertTo64Func convertToRGBA64PM
FetchAndConvertPixelsFunc64 fetchToRGBA64PM
FetchAndConvertPixelsFunc fetchToARGB32PM
ConvertAndStorePixelsFunc storeFromRGB32
RbSwapFunc rbSwap