1// Copyright (C) 2016 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
4#ifndef QPIXELFORMAT_H
5#define QPIXELFORMAT_H
6
7#include <QtGui/qtguiglobal.h>
8
9QT_BEGIN_NAMESPACE
10
11class QPixelFormat
12{
13 // QPixelFormat basically is a glorified quint64, split into several fields.
14 // We could use bit-fields, but GCC at least generates horrible, horrible code for them,
15 // so we do the bit-twiddling ourselves.
16 enum FieldWidth {
17 ModelFieldWidth = 4,
18 FirstFieldWidth = 6,
19 SecondFieldWidth = FirstFieldWidth,
20 ThirdFieldWidth = FirstFieldWidth,
21 FourthFieldWidth = FirstFieldWidth,
22 FifthFieldWidth = FirstFieldWidth,
23 AlphaFieldWidth = FirstFieldWidth,
24 AlphaUsageFieldWidth = 1,
25 AlphaPositionFieldWidth = 1,
26 PremulFieldWidth = 1,
27 TypeInterpretationFieldWidth = 4,
28 ByteOrderFieldWidth = 2,
29 SubEnumFieldWidth = 6,
30 UnusedFieldWidth = 9,
31
32 TotalFieldWidthByWidths = ModelFieldWidth + FirstFieldWidth + SecondFieldWidth + ThirdFieldWidth +
33 FourthFieldWidth + FifthFieldWidth + AlphaFieldWidth + AlphaUsageFieldWidth +
34 AlphaPositionFieldWidth + PremulFieldWidth + TypeInterpretationFieldWidth +
35 ByteOrderFieldWidth + SubEnumFieldWidth + UnusedFieldWidth
36 };
37
38 enum Field {
39 ModelField = 0,
40 // work around bug in old clang versions: when building webkit
41 // with XCode 4.6 and older this fails compilation, thus cast to int
42 FirstField = ModelField + int(ModelFieldWidth),
43 SecondField = FirstField + int(FirstFieldWidth),
44 ThirdField = SecondField + int(SecondFieldWidth),
45 FourthField = ThirdField + int(ThirdFieldWidth),
46 FifthField = FourthField + int(FourthFieldWidth),
47 AlphaField = FifthField + int(FifthFieldWidth),
48 AlphaUsageField = AlphaField + int(AlphaFieldWidth),
49 AlphaPositionField = AlphaUsageField + int(AlphaUsageFieldWidth),
50 PremulField = AlphaPositionField + int(AlphaPositionFieldWidth),
51 TypeInterpretationField = PremulField + int(PremulFieldWidth),
52 ByteOrderField = TypeInterpretationField + int(TypeInterpretationFieldWidth),
53 SubEnumField = ByteOrderField + int(ByteOrderFieldWidth),
54 UnusedField = SubEnumField + int(SubEnumFieldWidth),
55
56 TotalFieldWidthByOffsets = UnusedField + int(UnusedFieldWidth)
57 };
58
59 static_assert(uint(TotalFieldWidthByWidths) == uint(TotalFieldWidthByOffsets));
60 static_assert(uint(TotalFieldWidthByWidths) == 8 * sizeof(quint64));
61
62 constexpr inline uchar get(Field offset, FieldWidth width) const noexcept
63 { return uchar((data >> uint(offset)) & ((Q_UINT64_C(1) << uint(width)) - Q_UINT64_C(1))); }
64 constexpr static inline quint64 set(Field offset, FieldWidth width, uchar value)
65 { return (quint64(value) & ((Q_UINT64_C(1) << uint(width)) - Q_UINT64_C(1))) << uint(offset); }
66
67public:
68 enum ColorModel {
69 RGB,
70 BGR,
71 Indexed,
72 Grayscale,
73 CMYK,
74 HSL,
75 HSV,
76 YUV,
77 Alpha
78 };
79
80 enum AlphaUsage {
81 UsesAlpha,
82 IgnoresAlpha
83 };
84
85 enum AlphaPosition {
86 AtBeginning,
87 AtEnd
88 };
89
90 enum AlphaPremultiplied {
91 NotPremultiplied,
92 Premultiplied
93 };
94
95 enum TypeInterpretation {
96 UnsignedInteger,
97 UnsignedShort,
98 UnsignedByte,
99 FloatingPoint
100 };
101
102 enum YUVLayout {
103 YUV444,
104 YUV422,
105 YUV411,
106 YUV420P,
107 YUV420SP,
108 YV12,
109 UYVY,
110 YUYV,
111 NV12,
112 NV21,
113 IMC1,
114 IMC2,
115 IMC3,
116 IMC4,
117 Y8,
118 Y16
119 };
120
121 enum ByteOrder {
122 LittleEndian,
123 BigEndian,
124 CurrentSystemEndian
125 };
126
127 constexpr inline QPixelFormat() noexcept : data(0) {}
128 constexpr inline QPixelFormat(ColorModel colorModel,
129 uchar firstSize,
130 uchar secondSize,
131 uchar thirdSize,
132 uchar fourthSize,
133 uchar fifthSize,
134 uchar alphaSize,
135 AlphaUsage alphaUsage,
136 AlphaPosition alphaPosition,
137 AlphaPremultiplied premultiplied,
138 TypeInterpretation typeInterpretation,
139 ByteOrder byteOrder = CurrentSystemEndian,
140 uchar subEnum = 0) noexcept;
141
142 constexpr inline ColorModel colorModel() const noexcept { return ColorModel(get(offset: ModelField, width: ModelFieldWidth)); }
143 constexpr inline uchar channelCount() const noexcept { return (get(offset: FirstField, width: FirstFieldWidth) > 0) +
144 (get(offset: SecondField, width: SecondFieldWidth) > 0) +
145 (get(offset: ThirdField, width: ThirdFieldWidth) > 0) +
146 (get(offset: FourthField, width: FourthFieldWidth) > 0) +
147 (get(offset: FifthField, width: FifthFieldWidth) > 0) +
148 (get(offset: AlphaField, width: AlphaFieldWidth) > 0); }
149
150 constexpr inline uchar redSize() const noexcept { return get(offset: FirstField, width: FirstFieldWidth); }
151 constexpr inline uchar greenSize() const noexcept { return get(offset: SecondField, width: SecondFieldWidth); }
152 constexpr inline uchar blueSize() const noexcept { return get(offset: ThirdField, width: ThirdFieldWidth); }
153
154 constexpr inline uchar cyanSize() const noexcept { return get(offset: FirstField, width: FirstFieldWidth); }
155 constexpr inline uchar magentaSize() const noexcept { return get(offset: SecondField, width: SecondFieldWidth); }
156 constexpr inline uchar yellowSize() const noexcept { return get(offset: ThirdField, width: ThirdFieldWidth); }
157 constexpr inline uchar blackSize() const noexcept { return get(offset: FourthField, width: FourthFieldWidth); }
158
159 constexpr inline uchar hueSize() const noexcept { return get(offset: FirstField, width: FirstFieldWidth); }
160 constexpr inline uchar saturationSize() const noexcept { return get(offset: SecondField, width: SecondFieldWidth); }
161 constexpr inline uchar lightnessSize() const noexcept { return get(offset: ThirdField, width: ThirdFieldWidth); }
162 constexpr inline uchar brightnessSize() const noexcept { return get(offset: ThirdField, width: ThirdFieldWidth); }
163
164 constexpr inline uchar alphaSize() const noexcept { return get(offset: AlphaField, width: AlphaFieldWidth); }
165
166 constexpr inline uchar bitsPerPixel() const noexcept { return get(offset: FirstField, width: FirstFieldWidth) +
167 get(offset: SecondField, width: SecondFieldWidth) +
168 get(offset: ThirdField, width: ThirdFieldWidth) +
169 get(offset: FourthField, width: FourthFieldWidth) +
170 get(offset: FifthField, width: FifthFieldWidth) +
171 get(offset: AlphaField, width: AlphaFieldWidth); }
172
173 constexpr inline AlphaUsage alphaUsage() const noexcept { return AlphaUsage(get(offset: AlphaUsageField, width: AlphaUsageFieldWidth)); }
174 constexpr inline AlphaPosition alphaPosition() const noexcept { return AlphaPosition(get(offset: AlphaPositionField, width: AlphaPositionFieldWidth)); }
175 constexpr inline AlphaPremultiplied premultiplied() const noexcept { return AlphaPremultiplied(get(offset: PremulField, width: PremulFieldWidth)); }
176 constexpr inline TypeInterpretation typeInterpretation() const noexcept { return TypeInterpretation(get(offset: TypeInterpretationField, width: TypeInterpretationFieldWidth)); }
177 constexpr inline ByteOrder byteOrder() const noexcept { return ByteOrder(get(offset: ByteOrderField, width: ByteOrderFieldWidth)); }
178
179 constexpr inline YUVLayout yuvLayout() const noexcept { return YUVLayout(get(offset: SubEnumField, width: SubEnumFieldWidth)); }
180 constexpr inline uchar subEnum() const noexcept { return get(offset: SubEnumField, width: SubEnumFieldWidth); }
181
182private:
183 constexpr static inline ByteOrder resolveByteOrder(ByteOrder bo)
184 { return bo == CurrentSystemEndian ? Q_BYTE_ORDER == Q_LITTLE_ENDIAN ? LittleEndian : BigEndian : bo ; }
185
186private:
187 quint64 data;
188
189 friend Q_DECL_CONST_FUNCTION constexpr inline bool operator==(QPixelFormat fmt1, QPixelFormat fmt2)
190 { return fmt1.data == fmt2.data; }
191
192 friend Q_DECL_CONST_FUNCTION constexpr inline bool operator!=(QPixelFormat fmt1, QPixelFormat fmt2)
193 { return !(fmt1 == fmt2); }
194};
195static_assert(sizeof(QPixelFormat) == sizeof(quint64));
196Q_DECLARE_TYPEINFO(QPixelFormat, Q_PRIMITIVE_TYPE);
197
198
199namespace QtPrivate {
200 QPixelFormat Q_GUI_EXPORT QPixelFormat_createYUV(QPixelFormat::YUVLayout yuvLayout,
201 uchar alphaSize,
202 QPixelFormat::AlphaUsage alphaUsage,
203 QPixelFormat::AlphaPosition alphaPosition,
204 QPixelFormat::AlphaPremultiplied premultiplied,
205 QPixelFormat::TypeInterpretation typeInterpretation,
206 QPixelFormat::ByteOrder byteOrder);
207}
208
209constexpr QPixelFormat::QPixelFormat(ColorModel mdl,
210 uchar firstSize,
211 uchar secondSize,
212 uchar thirdSize,
213 uchar fourthSize,
214 uchar fifthSize,
215 uchar alfa,
216 AlphaUsage usage,
217 AlphaPosition position,
218 AlphaPremultiplied premult,
219 TypeInterpretation typeInterp,
220 ByteOrder b_order,
221 uchar s_enum) noexcept
222 : data(set(offset: ModelField, width: ModelFieldWidth, value: uchar(mdl)) |
223 set(offset: FirstField, width: FirstFieldWidth, value: firstSize) |
224 set(offset: SecondField, width: SecondFieldWidth, value: secondSize) |
225 set(offset: ThirdField, width: ThirdFieldWidth, value: thirdSize) |
226 set(offset: FourthField, width: FourthFieldWidth, value: fourthSize) |
227 set(offset: FifthField, width: FifthFieldWidth, value: fifthSize) |
228 set(offset: AlphaField, width: AlphaFieldWidth, value: alfa) |
229 set(offset: AlphaUsageField, width: AlphaUsageFieldWidth, value: uchar(usage)) |
230 set(offset: AlphaPositionField, width: AlphaPositionFieldWidth, value: uchar(position)) |
231 set(offset: PremulField, width: PremulFieldWidth, value: uchar(premult)) |
232 set(offset: TypeInterpretationField, width: TypeInterpretationFieldWidth, value: uchar(typeInterp)) |
233 set(offset: ByteOrderField, width: ByteOrderFieldWidth, value: uchar(resolveByteOrder(bo: b_order))) |
234 set(offset: SubEnumField, width: SubEnumFieldWidth, value: s_enum) |
235 set(offset: UnusedField, width: UnusedFieldWidth, value: 0))
236{
237}
238
239constexpr inline QPixelFormat qPixelFormatRgba(uchar red,
240 uchar green,
241 uchar blue,
242 uchar alfa,
243 QPixelFormat::AlphaUsage usage,
244 QPixelFormat::AlphaPosition position,
245 QPixelFormat::AlphaPremultiplied pmul=QPixelFormat::NotPremultiplied,
246 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) noexcept
247{
248 return QPixelFormat(QPixelFormat::RGB,
249 red,
250 green,
251 blue,
252 0,
253 0,
254 alfa,
255 usage,
256 position,
257 pmul,
258 typeInt);
259}
260
261constexpr inline QPixelFormat qPixelFormatGrayscale(uchar channelSize,
262 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) noexcept
263{
264 return QPixelFormat(QPixelFormat::Grayscale,
265 channelSize,
266 0,
267 0,
268 0,
269 0,
270 0,
271 QPixelFormat::IgnoresAlpha,
272 QPixelFormat::AtBeginning,
273 QPixelFormat::NotPremultiplied,
274 typeInt);
275}
276
277constexpr inline QPixelFormat qPixelFormatAlpha(uchar channelSize,
278 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) noexcept
279{
280 return QPixelFormat(QPixelFormat::Alpha,
281 0,
282 0,
283 0,
284 0,
285 0,
286 channelSize,
287 QPixelFormat::UsesAlpha,
288 QPixelFormat::AtBeginning,
289 QPixelFormat::NotPremultiplied,
290 typeInt);
291}
292
293constexpr inline QPixelFormat qPixelFormatCmyk(uchar channelSize,
294 uchar alfa=0,
295 QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
296 QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
297 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) noexcept
298{
299 return QPixelFormat(QPixelFormat::CMYK,
300 channelSize,
301 channelSize,
302 channelSize,
303 channelSize,
304 0,
305 alfa,
306 usage,
307 position,
308 QPixelFormat::NotPremultiplied,
309 typeInt);
310}
311
312constexpr inline QPixelFormat qPixelFormatHsl(uchar channelSize,
313 uchar alfa=0,
314 QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
315 QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
316 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::FloatingPoint) noexcept
317{
318 return QPixelFormat(QPixelFormat::HSL,
319 channelSize,
320 channelSize,
321 channelSize,
322 0,
323 0,
324 alfa,
325 usage,
326 position,
327 QPixelFormat::NotPremultiplied,
328 typeInt);
329}
330
331constexpr inline QPixelFormat qPixelFormatHsv(uchar channelSize,
332 uchar alfa=0,
333 QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
334 QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
335 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::FloatingPoint) noexcept
336{
337 return QPixelFormat(QPixelFormat::HSV,
338 channelSize,
339 channelSize,
340 channelSize,
341 0,
342 0,
343 alfa,
344 usage,
345 position,
346 QPixelFormat::NotPremultiplied,
347 typeInt);
348}
349
350inline QPixelFormat qPixelFormatYuv(QPixelFormat::YUVLayout layout,
351 uchar alfa=0,
352 QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
353 QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
354 QPixelFormat::AlphaPremultiplied p_mul=QPixelFormat::NotPremultiplied,
355 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedByte,
356 QPixelFormat::ByteOrder b_order=QPixelFormat::LittleEndian)
357{
358 return QtPrivate::QPixelFormat_createYUV(yuvLayout: layout,
359 alphaSize: alfa,
360 alphaUsage: usage,
361 alphaPosition: position,
362 premultiplied: p_mul,
363 typeInterpretation: typeInt,
364 byteOrder: b_order);
365}
366
367QT_END_NAMESPACE
368
369#endif //QPIXELFORMAT_H
370

source code of qtbase/src/gui/kernel/qpixelformat.h