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 Q_STATIC_ASSERT(uint(TotalFieldWidthByWidths) == uint(TotalFieldWidthByOffsets));
96 Q_STATIC_ASSERT(uint(TotalFieldWidthByWidths) == 8 * sizeof(quint64));
97
98 Q_DECL_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 Q_DECL_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 Q_DECL_CONSTEXPR inline QPixelFormat() noexcept : data(0) {}
164 Q_DECL_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 Q_DECL_CONSTEXPR inline ColorModel colorModel() const noexcept { return ColorModel(get(ModelField, ModelFieldWidth)); }
179 Q_DECL_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 Q_DECL_CONSTEXPR inline uchar redSize() const noexcept { return get(FirstField, FirstFieldWidth); }
187 Q_DECL_CONSTEXPR inline uchar greenSize() const noexcept { return get(SecondField, SecondFieldWidth); }
188 Q_DECL_CONSTEXPR inline uchar blueSize() const noexcept { return get(ThirdField, ThirdFieldWidth); }
189
190 Q_DECL_CONSTEXPR inline uchar cyanSize() const noexcept { return get(FirstField, FirstFieldWidth); }
191 Q_DECL_CONSTEXPR inline uchar magentaSize() const noexcept { return get(SecondField, SecondFieldWidth); }
192 Q_DECL_CONSTEXPR inline uchar yellowSize() const noexcept { return get(ThirdField, ThirdFieldWidth); }
193 Q_DECL_CONSTEXPR inline uchar blackSize() const noexcept { return get(FourthField, FourthFieldWidth); }
194
195 Q_DECL_CONSTEXPR inline uchar hueSize() const noexcept { return get(FirstField, FirstFieldWidth); }
196 Q_DECL_CONSTEXPR inline uchar saturationSize() const noexcept { return get(SecondField, SecondFieldWidth); }
197 Q_DECL_CONSTEXPR inline uchar lightnessSize() const noexcept { return get(ThirdField, ThirdFieldWidth); }
198 Q_DECL_CONSTEXPR inline uchar brightnessSize() const noexcept { return get(ThirdField, ThirdFieldWidth); }
199
200 Q_DECL_CONSTEXPR inline uchar alphaSize() const noexcept { return get(AlphaField, AlphaFieldWidth); }
201
202 Q_DECL_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 Q_DECL_CONSTEXPR inline AlphaUsage alphaUsage() const noexcept { return AlphaUsage(get(AlphaUsageField, AlphaUsageFieldWidth)); }
210 Q_DECL_CONSTEXPR inline AlphaPosition alphaPosition() const noexcept { return AlphaPosition(get(AlphaPositionField, AlphaPositionFieldWidth)); }
211 Q_DECL_CONSTEXPR inline AlphaPremultiplied premultiplied() const noexcept { return AlphaPremultiplied(get(PremulField, PremulFieldWidth)); }
212 Q_DECL_CONSTEXPR inline TypeInterpretation typeInterpretation() const noexcept { return TypeInterpretation(get(TypeInterpretationField, TypeInterpretationFieldWidth)); }
213 Q_DECL_CONSTEXPR inline ByteOrder byteOrder() const noexcept { return ByteOrder(get(ByteOrderField, ByteOrderFieldWidth)); }
214
215 Q_DECL_CONSTEXPR inline YUVLayout yuvLayout() const noexcept { return YUVLayout(get(SubEnumField, SubEnumFieldWidth)); }
216 Q_DECL_CONSTEXPR inline uchar subEnum() const noexcept { return get(SubEnumField, SubEnumFieldWidth); }
217
218private:
219 Q_DECL_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 Q_DECL_CONSTEXPR inline bool operator==(QPixelFormat fmt1, QPixelFormat fmt2)
226 { return fmt1.data == fmt2.data; }
227
228 friend Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator!=(QPixelFormat fmt1, QPixelFormat fmt2)
229 { return !(fmt1 == fmt2); }
230};
231Q_STATIC_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
245Q_DECL_CONSTEXPR
246QPixelFormat::QPixelFormat(ColorModel mdl,
247 uchar firstSize,
248 uchar secondSize,
249 uchar thirdSize,
250 uchar fourthSize,
251 uchar fifthSize,
252 uchar alfa,
253 AlphaUsage usage,
254 AlphaPosition position,
255 AlphaPremultiplied premult,
256 TypeInterpretation typeInterp,
257 ByteOrder b_order,
258 uchar s_enum) noexcept
259 : data(set(ModelField, ModelFieldWidth, uchar(mdl)) |
260 set(FirstField, FirstFieldWidth, firstSize) |
261 set(SecondField, SecondFieldWidth, secondSize) |
262 set(ThirdField, ThirdFieldWidth, thirdSize) |
263 set(FourthField, FourthFieldWidth, fourthSize) |
264 set(FifthField, FifthFieldWidth, fifthSize) |
265 set(AlphaField, AlphaFieldWidth, alfa) |
266 set(AlphaUsageField, AlphaUsageFieldWidth, uchar(usage)) |
267 set(AlphaPositionField, AlphaPositionFieldWidth, uchar(position)) |
268 set(PremulField, PremulFieldWidth, uchar(premult)) |
269 set(TypeInterpretationField, TypeInterpretationFieldWidth, uchar(typeInterp)) |
270 set(ByteOrderField, ByteOrderFieldWidth, uchar(resolveByteOrder(b_order))) |
271 set(SubEnumField, SubEnumFieldWidth, s_enum) |
272 set(UnusedField, UnusedFieldWidth, 0))
273{
274}
275
276Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatRgba(uchar red,
277 uchar green,
278 uchar blue,
279 uchar alfa,
280 QPixelFormat::AlphaUsage usage,
281 QPixelFormat::AlphaPosition position,
282 QPixelFormat::AlphaPremultiplied pmul=QPixelFormat::NotPremultiplied,
283 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) noexcept
284{
285 return QPixelFormat(QPixelFormat::RGB,
286 red,
287 green,
288 blue,
289 0,
290 0,
291 alfa,
292 usage,
293 position,
294 pmul,
295 typeInt);
296}
297
298Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatGrayscale(uchar channelSize,
299 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) noexcept
300{
301 return QPixelFormat(QPixelFormat::Grayscale,
302 channelSize,
303 0,
304 0,
305 0,
306 0,
307 0,
308 QPixelFormat::IgnoresAlpha,
309 QPixelFormat::AtBeginning,
310 QPixelFormat::NotPremultiplied,
311 typeInt);
312}
313
314Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatAlpha(uchar channelSize,
315 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) noexcept
316{
317 return QPixelFormat(QPixelFormat::Alpha,
318 0,
319 0,
320 0,
321 0,
322 0,
323 channelSize,
324 QPixelFormat::UsesAlpha,
325 QPixelFormat::AtBeginning,
326 QPixelFormat::NotPremultiplied,
327 typeInt);
328}
329
330Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatCmyk(uchar channelSize,
331 uchar alfa=0,
332 QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
333 QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
334 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) noexcept
335{
336 return QPixelFormat(QPixelFormat::CMYK,
337 channelSize,
338 channelSize,
339 channelSize,
340 channelSize,
341 0,
342 alfa,
343 usage,
344 position,
345 QPixelFormat::NotPremultiplied,
346 typeInt);
347}
348
349Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatHsl(uchar channelSize,
350 uchar alfa=0,
351 QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
352 QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
353 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::FloatingPoint) noexcept
354{
355 return QPixelFormat(QPixelFormat::HSL,
356 channelSize,
357 channelSize,
358 channelSize,
359 0,
360 0,
361 alfa,
362 usage,
363 position,
364 QPixelFormat::NotPremultiplied,
365 typeInt);
366}
367
368Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatHsv(uchar channelSize,
369 uchar alfa=0,
370 QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
371 QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
372 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::FloatingPoint) noexcept
373{
374 return QPixelFormat(QPixelFormat::HSV,
375 channelSize,
376 channelSize,
377 channelSize,
378 0,
379 0,
380 alfa,
381 usage,
382 position,
383 QPixelFormat::NotPremultiplied,
384 typeInt);
385}
386
387inline QPixelFormat qPixelFormatYuv(QPixelFormat::YUVLayout layout,
388 uchar alfa=0,
389 QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
390 QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
391 QPixelFormat::AlphaPremultiplied p_mul=QPixelFormat::NotPremultiplied,
392 QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedByte,
393 QPixelFormat::ByteOrder b_order=QPixelFormat::LittleEndian)
394{
395 return QtPrivate::QPixelFormat_createYUV(layout,
396 alfa,
397 usage,
398 position,
399 p_mul,
400 typeInt,
401 b_order);
402}
403
404QT_END_NAMESPACE
405
406#endif //QPIXELFORMAT_H
407