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