Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qcolorspace.cpp
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
4#include "qcolorspace.h"
5#include "qcolorspace_p.h"
6
7#include "qcolortransform.h"
8#include "qcolormatrix_p.h"
10#include "qcolortransform_p.h"
11#include "qicc_p.h"
12
13#include <qatomic.h>
14#include <qmath.h>
15#include <qtransform.h>
16
17#include <qdebug.h>
18
20
22
25{
27 QColorSpacePrivate *prv = ptr.fetchAndStoreAcquire(nullptr);
28 if (prv && !prv->ref.deref())
29 delete prv;
30 }
31}
32
33Q_DESTRUCTOR_FUNCTION(cleanupPredefinedColorspaces)
34
36{
37 switch (primaries) {
39 redPoint = QPointF(0.640, 0.330);
40 greenPoint = QPointF(0.300, 0.600);
41 bluePoint = QPointF(0.150, 0.060);
42 whitePoint = QColorVector::D65Chromaticity();
43 break;
45 redPoint = QPointF(0.680, 0.320);
46 greenPoint = QPointF(0.265, 0.690);
47 bluePoint = QPointF(0.150, 0.060);
48 whitePoint = QColorVector::D65Chromaticity();
49 break;
51 redPoint = QPointF(0.640, 0.330);
52 greenPoint = QPointF(0.210, 0.710);
53 bluePoint = QPointF(0.150, 0.060);
54 whitePoint = QColorVector::D65Chromaticity();
55 break;
57 redPoint = QPointF(0.7347, 0.2653);
58 greenPoint = QPointF(0.1596, 0.8404);
59 bluePoint = QPointF(0.0366, 0.0001);
60 whitePoint = QColorVector::D50Chromaticity();
61 break;
62 default:
63 Q_UNREACHABLE();
64 }
65}
66
68{
70 return false;
72 return false;
74 return false;
76 return false;
77 return true;
78}
79
81{
82 // This converts to XYZ in some undefined scale.
86
87 // Since the white point should be (1.0, 1.0, 1.0) in the
88 // input, we can figure out the scale by using the
89 // inverse conversion on the white point.
91 QColorVector whiteScale = toXyz.inverted().map(wXyz);
92
93 // Now we have scaled conversion to XYZ relative to the given whitepoint
94 toXyz = toXyz * QColorMatrix::fromScale(whiteScale);
95
96 // But we want a conversion to XYZ relative to D50
98
99 if (wXyz != wXyzD50) {
100 // Do chromatic adaptation to map our white point to XYZ D50.
101
102 // The Bradford method chromatic adaptation matrix:
103 QColorMatrix abrad = { { 0.8951f, -0.7502f, 0.0389f },
104 { 0.2664f, 1.7135f, -0.0685f },
105 { -0.1614f, 0.0367f, 1.0296f } };
106 QColorMatrix abradinv = { { 0.9869929f, 0.4323053f, -0.0085287f },
107 { -0.1470543f, 0.5183603f, 0.0400428f },
108 { 0.1599627f, 0.0492912f, 0.9684867f } };
109
110 QColorVector srcCone = abrad.map(wXyz);
111 QColorVector dstCone = abrad.map(wXyzD50);
112
113 if (srcCone.x && srcCone.y && srcCone.z) {
114 QColorMatrix wToD50 = { { dstCone.x / srcCone.x, 0, 0 },
115 { 0, dstCone.y / srcCone.y, 0 },
116 { 0, 0, dstCone.z / srcCone.z } };
117
118
119 QColorMatrix chromaticAdaptation = abradinv * (wToD50 * abrad);
120 toXyz = chromaticAdaptation * toXyz;
121 } else {
122 toXyz.r = {0, 0, 0}; // set to invalid value
123 }
124 }
126 return toXyz;
127}
128
130{
131}
132
134 : namedColorSpace(namedColorSpace)
135{
136 switch (namedColorSpace) {
140 description = QStringLiteral("sRGB");
141 break;
145 description = QStringLiteral("Linear sRGB");
146 break;
150 gamma = 2.19921875f; // Not quite 2.2, see https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
151 description = QStringLiteral("Adobe RGB");
152 break;
156 description = QStringLiteral("Display P3");
157 break;
161 description = QStringLiteral("ProPhoto RGB");
162 break;
163 default:
164 Q_UNREACHABLE();
165 }
166 initialize();
167}
168
170 : primaries(primaries)
171 , transferFunction(transferFunction)
172 , gamma(gamma)
173{
175 initialize();
176}
177
179 QColorSpace::TransferFunction transferFunction,
180 float gamma)
181 : primaries(QColorSpace::Primaries::Custom)
182 , transferFunction(transferFunction)
183 , gamma(gamma)
184{
185 Q_ASSERT(primaries.areValid());
186 toXyz = primaries.toXyzMatrix();
187 whitePoint = QColorVector(primaries.whitePoint);
190}
191
193 : primaries(primaries)
194 , transferFunction(QColorSpace::TransferFunction::Custom)
195 , gamma(0)
196{
197 setTransferFunctionTable(transferFunctionTable);
199 initialize();
200}
201
203 : primaries(QColorSpace::Primaries::Custom)
204 , transferFunction(QColorSpace::TransferFunction::Custom)
205 , gamma(0)
206{
207 Q_ASSERT(primaries.areValid());
208 toXyz = primaries.toXyzMatrix();
209 whitePoint = QColorVector(primaries.whitePoint);
210 setTransferFunctionTable(transferFunctionTable);
212 initialize();
213}
214
216 const QList<uint16_t> &redTransferFunctionTable,
217 const QList<uint16_t> &greenTransferFunctionTable,
218 const QList<uint16_t> &blueTransferFunctionTable)
219 : primaries(QColorSpace::Primaries::Custom)
220 , transferFunction(QColorSpace::TransferFunction::Custom)
221 , gamma(0)
222{
223 Q_ASSERT(primaries.areValid());
224 toXyz = primaries.toXyzMatrix();
225 whitePoint = QColorVector(primaries.whitePoint);
226 setTransferFunctionTables(redTransferFunctionTable,
227 greenTransferFunctionTable,
228 blueTransferFunctionTable);
231}
232
234{
235 switch (primaries) {
239 if (description.isEmpty())
240 description = QStringLiteral("sRGB");
241 return;
242 }
245 if (description.isEmpty())
246 description = QStringLiteral("Linear sRGB");
247 return;
248 }
249 break;
252 if (qAbs(gamma - 2.19921875f) < (1/1024.0f)) {
254 if (description.isEmpty())
255 description = QStringLiteral("Adobe RGB");
256 return;
257 }
258 }
259 break;
263 if (description.isEmpty())
264 description = QStringLiteral("Display P3");
265 return;
266 }
267 break;
271 if (description.isEmpty())
272 description = QStringLiteral("ProPhoto RGB");
273 return;
274 }
276 // ProPhoto RGB's curve is effectively gamma 1.8 for 8bit precision.
277 if (qAbs(gamma - 1.8f) < (1/1024.0f)) {
279 if (description.isEmpty())
280 description = QStringLiteral("ProPhoto RGB");
281 return;
282 }
283 }
284 break;
285 default:
286 break;
287 }
288
290}
291
293{
296}
297
299{
303 return;
304 }
305 QColorSpacePrimaries colorSpacePrimaries(primaries);
306 toXyz = colorSpacePrimaries.toXyzMatrix();
307 whitePoint = QColorVector(colorSpacePrimaries.whitePoint);
308}
309
311{
312 QColorTransferTable table(transferFunctionTable.size(), transferFunctionTable);
313 if (!table.isEmpty() && !table.checkValidity()) {
314 qWarning() << "Invalid transfer function table given to QColorSpace";
315 trc[0].m_type = QColorTrc::Type::Uninitialized;
316 return;
317 }
320 if (table.asColorTransferFunction(&curve)) {
321 // Table recognized as a specific curve
322 if (curve.isLinear()) {
324 gamma = 1.0f;
325 } else if (curve.isSRgb()) {
327 }
328 trc[0].m_type = QColorTrc::Type::Function;
329 trc[0].m_fun = curve;
330 } else {
331 trc[0].m_type = QColorTrc::Type::Table;
332 trc[0].m_table = table;
333 }
334}
335
337 const QList<uint16_t> &greenTransferFunctionTable,
338 const QList<uint16_t> &blueTransferFunctionTable)
339{
340 QColorTransferTable redTable(redTransferFunctionTable.size(), redTransferFunctionTable);
341 QColorTransferTable greenTable(greenTransferFunctionTable.size(), greenTransferFunctionTable);
342 QColorTransferTable blueTable(blueTransferFunctionTable.size(), blueTransferFunctionTable);
343 if (!redTable.isEmpty() && !greenTable.isEmpty() && !blueTable.isEmpty() &&
344 !redTable.checkValidity() && !greenTable.checkValidity() && !blueTable.checkValidity()) {
345 qWarning() << "Invalid transfer function table given to QColorSpace";
346 trc[0].m_type = QColorTrc::Type::Uninitialized;
347 trc[1].m_type = QColorTrc::Type::Uninitialized;
348 trc[2].m_type = QColorTrc::Type::Uninitialized;
349 return;
350 }
353 if (redTable.asColorTransferFunction(&curve)) {
354 trc[0].m_type = QColorTrc::Type::Function;
355 trc[0].m_fun = curve;
356 } else {
357 trc[0].m_type = QColorTrc::Type::Table;
358 trc[0].m_table = redTable;
359 }
360 if (greenTable.asColorTransferFunction(&curve)) {
361 trc[1].m_type = QColorTrc::Type::Function;
362 trc[1].m_fun = curve;
363 } else {
364 trc[1].m_type = QColorTrc::Type::Table;
365 trc[1].m_table = greenTable;
366 }
367 if (blueTable.asColorTransferFunction(&curve)) {
368 trc[2].m_type = QColorTrc::Type::Function;
369 trc[2].m_fun = curve;
370 } else {
371 trc[2].m_type = QColorTrc::Type::Table;
372 trc[2].m_table = blueTable;
373 }
375}
376
378{
379 switch (transferFunction) {
381 trc[0].m_type = QColorTrc::Type::Function;
383 if (qFuzzyIsNull(gamma))
384 gamma = 1.0f;
385 break;
387 trc[0].m_type = QColorTrc::Type::Function;
389 break;
391 trc[0].m_type = QColorTrc::Type::Function;
393 if (qFuzzyIsNull(gamma))
394 gamma = 2.31f;
395 break;
397 trc[0].m_type = QColorTrc::Type::Function;
399 if (qFuzzyIsNull(gamma))
400 gamma = 1.8f;
401 break;
403 break;
404 default:
405 Q_UNREACHABLE();
406 break;
407 }
408 trc[1] = trc[0];
409 trc[2] = trc[0];
411}
412
414{
415 Q_ASSERT(out);
416 QColorTransform combined;
417 auto ptr = new QColorTransformPrivate;
418 combined.d = ptr;
419 ptr->colorSpaceIn = this;
420 ptr->colorSpaceOut = out;
421 ptr->colorMatrix = out->toXyz.inverted() * toXyz;
422 if (ptr->isIdentity())
423 return QColorTransform();
424 return combined;
425}
426
428{
430 auto ptr = new QColorTransformPrivate;
431 transform.d = ptr;
432 ptr->colorSpaceIn = this;
433 ptr->colorSpaceOut = this;
434 ptr->colorMatrix = toXyz;
435 return transform;
436}
437
525{
526 if (namedColorSpace < QColorSpace::SRgb || namedColorSpace > QColorSpace::ProPhotoRgb) {
527 qWarning() << "QColorSpace attempted constructed from invalid QColorSpace::NamedColorSpace: " << int(namedColorSpace);
528 return;
529 }
530 // The defined namespaces start at 1:
531 auto &atomicRef = s_predefinedColorspacePrivates[static_cast<int>(namedColorSpace) - 1];
532 QColorSpacePrivate *cspriv = atomicRef.loadAcquire();
533 if (!cspriv) {
534 auto *tmp = new QColorSpacePrivate(namedColorSpace);
535 tmp->ref.ref();
536 if (atomicRef.testAndSetOrdered(nullptr, tmp, cspriv))
537 cspriv = tmp;
538 else
539 delete tmp;
540 }
541 d_ptr = cspriv;
542 Q_ASSERT(isValid());
543}
544
550 : d_ptr(new QColorSpacePrivate(primaries, transferFunction, gamma))
551{
552}
553
559 : d_ptr(new QColorSpacePrivate(primaries, TransferFunction::Gamma, gamma))
560{
561}
562
573 : d_ptr(new QColorSpacePrivate(gamut, transferFunctionTable))
574{
575}
576
581QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
582 const QPointF &greenPoint, const QPointF &bluePoint,
583 QColorSpace::TransferFunction transferFunction, float gamma)
584{
585 QColorSpacePrimaries primaries(whitePoint, redPoint, greenPoint, bluePoint);
586 if (!primaries.areValid()) {
587 qWarning() << "QColorSpace attempted constructed from invalid primaries:" << whitePoint << redPoint << greenPoint << bluePoint;
588 return;
589 }
591}
592
600QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
601 const QPointF &greenPoint, const QPointF &bluePoint,
602 const QList<uint16_t> &transferFunctionTable)
603 : d_ptr(new QColorSpacePrivate({whitePoint, redPoint, greenPoint, bluePoint}, transferFunctionTable))
604{
605}
606
614QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
615 const QPointF &greenPoint, const QPointF &bluePoint,
616 const QList<uint16_t> &redTransferFunctionTable,
617 const QList<uint16_t> &greenTransferFunctionTable,
618 const QList<uint16_t> &blueTransferFunctionTable)
619 : d_ptr(new QColorSpacePrivate({whitePoint, redPoint, greenPoint, bluePoint},
620 redTransferFunctionTable,
621 greenTransferFunctionTable,
622 blueTransferFunctionTable))
623{
624}
625
626QColorSpace::~QColorSpace() = default;
627
629
630QColorSpace::QColorSpace(const QColorSpace &colorSpace) noexcept = default;
631
643{
644 if (Q_UNLIKELY(!d_ptr))
646 return d_ptr->primaries;
647}
648
656{
657 if (Q_UNLIKELY(!d_ptr))
659 return d_ptr->transferFunction;
660}
661
669float QColorSpace::gamma() const noexcept
670{
671 if (Q_UNLIKELY(!d_ptr))
672 return 0.0f;
673 return d_ptr->gamma;
674}
675
682{
684 return;
685 if (!d_ptr) {
687 return;
688 }
689 if (d_ptr->transferFunction == transferFunction && d_ptr->gamma == gamma)
690 return;
691 detach();
692 d_ptr->description.clear();
694 d_ptr->gamma = gamma;
695 d_ptr->identifyColorSpace();
696 d_ptr->setTransferFunction();
697}
698
705void QColorSpace::setTransferFunction(const QList<uint16_t> &transferFunctionTable)
706{
707 if (!d_ptr) {
708 d_ptr = new QColorSpacePrivate(Primaries::Custom, transferFunctionTable);
709 d_ptr->ref.ref();
710 return;
711 }
712 detach();
713 d_ptr->description.clear();
714 d_ptr->setTransferFunctionTable(transferFunctionTable);
715 d_ptr->gamma = 0;
716 d_ptr->identifyColorSpace();
717 d_ptr->setTransferFunction();
718}
719
727void QColorSpace::setTransferFunctions(const QList<uint16_t> &redTransferFunctionTable,
728 const QList<uint16_t> &greenTransferFunctionTable,
729 const QList<uint16_t> &blueTransferFunctionTable)
730{
731 if (!d_ptr) {
732 d_ptr = new QColorSpacePrivate();
733 d_ptr->setTransferFunctionTables(redTransferFunctionTable,
734 greenTransferFunctionTable,
735 blueTransferFunctionTable);
736 d_ptr->ref.ref();
737 return;
738 }
739 detach();
740 d_ptr->description.clear();
741 d_ptr->setTransferFunctionTables(redTransferFunctionTable,
742 greenTransferFunctionTable,
743 blueTransferFunctionTable);
744 d_ptr->gamma = 0;
745 d_ptr->identifyColorSpace();
746}
747
755{
757 return *this;
758 if (d_ptr->transferFunction == transferFunction && d_ptr->gamma == gamma)
759 return *this;
760 QColorSpace out(*this);
761 out.setTransferFunction(transferFunction, gamma);
762 return out;
763}
764
773{
774 if (!isValid())
775 return *this;
776 QColorSpace out(*this);
777 out.setTransferFunction(transferFunctionTable);
778 return out;
779}
780
790 const QList<uint16_t> &greenTransferFunctionTable,
791 const QList<uint16_t> &blueTransferFunctionTable) const
792{
793 if (!isValid())
794 return *this;
795 QColorSpace out(*this);
796 out.setTransferFunctions(redTransferFunctionTable, greenTransferFunctionTable, blueTransferFunctionTable);
797 return out;
798}
799
806{
807 if (primariesId == Primaries::Custom)
808 return;
809 if (!d_ptr) {
810 d_ptr = new QColorSpacePrivate(primariesId, TransferFunction::Custom, 0.0f);
811 return;
812 }
813 if (d_ptr->primaries == primariesId)
814 return;
815 detach();
816 d_ptr->description.clear();
817 d_ptr->primaries = primariesId;
818 d_ptr->identifyColorSpace();
819 d_ptr->setToXyzMatrix();
820}
821
828void QColorSpace::setPrimaries(const QPointF &whitePoint, const QPointF &redPoint,
829 const QPointF &greenPoint, const QPointF &bluePoint)
830{
831 QColorSpacePrimaries primaries(whitePoint, redPoint, greenPoint, bluePoint);
832 if (!primaries.areValid())
833 return;
834 if (!d_ptr) {
836 return;
837 }
838 QColorMatrix toXyz = primaries.toXyzMatrix();
839 if (QColorVector(primaries.whitePoint) == d_ptr->whitePoint && toXyz == d_ptr->toXyz)
840 return;
841 detach();
842 d_ptr->description.clear();
844 d_ptr->toXyz = toXyz;
845 d_ptr->whitePoint = QColorVector(primaries.whitePoint);
846 d_ptr->identifyColorSpace();
847}
848
853{
854 if (d_ptr)
855 d_ptr.detach();
856 else
857 d_ptr = new QColorSpacePrivate;
858}
859
873{
874 if (Q_UNLIKELY(!d_ptr))
875 return QByteArray();
876 if (!d_ptr->iccProfile.isEmpty())
877 return d_ptr->iccProfile;
878 if (!isValid())
879 return QByteArray();
880 return QIcc::toIccProfile(*this);
881}
882
895{
896 QColorSpace colorSpace;
897 if (QIcc::fromIccProfile(iccProfile, &colorSpace))
898 return colorSpace;
899 colorSpace.detach();
900 colorSpace.d_ptr->iccProfile = iccProfile;
901 return colorSpace;
902}
903
907bool QColorSpace::isValid() const noexcept
908{
909 return d_ptr
910 && d_ptr->toXyz.isValid()
911 && d_ptr->trc[0].isValid() && d_ptr->trc[1].isValid() && d_ptr->trc[2].isValid();
912}
913
931bool QColorSpace::equals(const QColorSpace &other) const
932{
933 if (d_ptr == other.d_ptr)
934 return true;
935 if (!d_ptr || !other.d_ptr)
936 return false;
937
938 if (d_ptr->namedColorSpace && other.d_ptr->namedColorSpace)
939 return d_ptr->namedColorSpace == other.d_ptr->namedColorSpace;
940
941 const bool valid1 = isValid();
942 const bool valid2 = other.isValid();
943 if (valid1 != valid2)
944 return false;
945 if (!valid1 && !valid2) {
946 if (!d_ptr->iccProfile.isEmpty() || !other.d_ptr->iccProfile.isEmpty())
947 return d_ptr->iccProfile == other.d_ptr->iccProfile;
948 }
949
950 // At this point one or both color spaces are unknown, and must be compared in detail instead
951
953 if (primaries() != other.primaries())
954 return false;
955 } else {
956 if (d_ptr->toXyz != other.d_ptr->toXyz)
957 return false;
958 }
959
961 other.transferFunction() != QColorSpace::TransferFunction::Custom) {
962 if (transferFunction() != other.transferFunction())
963 return false;
965 return (qAbs(gamma() - other.gamma()) <= (1.0f / 512.0f));
966 return true;
967 }
968
969 if (d_ptr->trc[0] != other.d_ptr->trc[0] ||
970 d_ptr->trc[1] != other.d_ptr->trc[1] ||
971 d_ptr->trc[2] != other.d_ptr->trc[2])
972 return false;
973
974 return true;
975}
976
982{
983 if (!isValid() || !colorspace.isValid())
984 return QColorTransform();
985
986 if (*this == colorspace)
987 return QColorTransform();
988
989 return d_ptr->transformationToColorSpace(colorspace.d_ptr.get());
990}
991
996QColorSpace::operator QVariant() const
997{
998 return QVariant::fromValue(*this);
999}
1000
1010{
1011 if (d_ptr)
1012 return d_ptr->userDescription.isEmpty() ? d_ptr->description : d_ptr->userDescription;
1013 return QString();
1014}
1015
1024void QColorSpace::setDescription(const QString &description)
1025{
1026 detach();
1028}
1029
1030/*****************************************************************************
1031 QColorSpace stream functions
1032 *****************************************************************************/
1033#if !defined(QT_NO_DATASTREAM)
1044{
1045 s << image.iccProfile();
1046 return s;
1047}
1048
1060{
1061 QByteArray iccProfile;
1062 s >> iccProfile;
1063 colorSpace = QColorSpace::fromIccProfile(iccProfile);
1064 return s;
1065}
1066#endif // QT_NO_DATASTREAM
1067
1068#ifndef QT_NO_DEBUG_STREAM
1069QDebug operator<<(QDebug dbg, const QColorSpace &colorSpace)
1070{
1071 QDebugStateSaver saver(dbg);
1072 dbg.nospace();
1073 dbg << "QColorSpace(";
1074 if (colorSpace.d_ptr) {
1075 if (colorSpace.d_ptr->namedColorSpace)
1076 dbg << colorSpace.d_ptr->namedColorSpace << ", ";
1077 dbg << colorSpace.primaries() << ", " << colorSpace.transferFunction();
1078 dbg << ", gamma=" << colorSpace.gamma();
1079 }
1080 dbg << ')';
1081 return dbg;
1082}
1083#endif
1084
1086
1087#include "moc_qcolorspace.cpp"
\macro Q_ATOMIC_INTnn_IS_SUPPORTED
Definition qatomic.h:123
bool ref() noexcept
bool deref() noexcept
void storeRelease(T newValue) noexcept
\inmodule QtCore
Definition qbytearray.h:57
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
QColorMatrix inverted() const
bool isValid() const
static QColorMatrix fromScale(QColorVector v)
QColorVector r
QColorVector map(const QColorVector &c) const
QColorMatrix toXyzMatrix() const
bool areValid() const
void setTransferFunctionTables(const QList< uint16_t > &redTransferFunctionTable, const QList< uint16_t > &greenTransferFunctionTable, const QList< uint16_t > &blueTransferFunctionTable)
QColorVector whitePoint
QColorTransform transformationToColorSpace(const QColorSpacePrivate *out) const
QColorSpace::NamedColorSpace namedColorSpace
void setTransferFunctionTable(const QList< uint16_t > &transferFunctionTable)
QColorTransform transformationToXYZ() const
static Q_CONSTINIT QBasicMutex s_lutWriteLock
struct QColorSpacePrivate::LUT lut
QColorSpace::Primaries primaries
QColorSpace::TransferFunction transferFunction
static constexpr QColorSpace::NamedColorSpace Unknown
The QColorSpace class provides a color space abstraction.
Definition qcolorspace.h:21
Primaries primaries() const noexcept
Returns the predefined primaries of the color space or primaries::Custom if it doesn't match any of t...
friend class QColorSpacePrivate
Primaries
Predefined sets of primary colors.
Definition qcolorspace.h:32
QColorTransform transformationToColorSpace(const QColorSpace &colorspace) const
Generates and returns a color space transformation from this color space to colorspace.
bool isValid() const noexcept
Returns true if the color space is valid.
QColorSpace withTransferFunctions(const QList< uint16_t > &redTransferFunctionTable, const QList< uint16_t > &greenTransferFunctionTable, const QList< uint16_t > &blueTransferFunctionTable) const
Returns a copy of this color space, except using the transfer functions described by redTransferFunct...
void setTransferFunction(TransferFunction transferFunction, float gamma=0.0f)
Sets the transfer function to transferFunction and gamma.
float gamma() const noexcept
Returns the gamma value of color spaces with TransferFunction::Gamma, an approximate gamma value for ...
static QColorSpace fromIccProfile(const QByteArray &iccProfile)
Creates a QColorSpace from ICC profile iccProfile.
TransferFunction transferFunction() const noexcept
Returns the predefined transfer function of the color space or TransferFunction::Custom if it doesn't...
NamedColorSpace
Predefined color spaces.
Definition qcolorspace.h:24
void setTransferFunctions(const QList< uint16_t > &redTransferFunctionTable, const QList< uint16_t > &greenTransferFunctionTable, const QList< uint16_t > &blueTransferFunctionTable)
Sets the transfer functions to redTransferFunctionTable, greenTransferFunctionTable and blueTransferF...
void setPrimaries(Primaries primariesId)
Sets the primaries to those of the primariesId set.
void setDescription(const QString &description)
Sets the name or short description of the color space to description.
TransferFunction
Predefined transfer functions or gamma curves.
Definition qcolorspace.h:40
QColorSpace() noexcept=default
Creates a new colorspace object that represents an undefined and invalid colorspace.
QColorSpace withTransferFunction(TransferFunction transferFunction, float gamma=0.0f) const
Returns a copy of this color space, except using the transfer function transferFunction and gamma.
QString description() const noexcept
Returns the name or short description.
QByteArray iccProfile() const
Returns an ICC profile representing the color space.
static QColorTransferFunction fromGamma(float gamma)
static QColorTransferFunction fromProPhotoRgb()
static QColorTransferFunction fromSRgb()
bool asColorTransferFunction(QColorTransferFunction *transferFn)
The QColorTransform class is a transformation between color spaces.
QColorTransferFunction m_fun
Definition qcolortrc_p.h:91
bool isValid() const
Definition qcolortrc_p.h:46
Type m_type
Definition qcolortrc_p.h:90
QColorTransferTable m_table
Definition qcolortrc_p.h:92
static constexpr QColorVector D50()
static constexpr QPointF D65Chromaticity()
static bool isValidChromaticity(const QPointF &chr)
static constexpr QPointF D50Chromaticity()
\inmodule QtCore\reentrant
Definition qdatastream.h:30
\inmodule QtCore
\inmodule QtCore
void detach()
If the shared data object's reference count is greater than 1, this function creates a deep copy of t...
T * get() const noexcept
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
\inmodule QtCore
Definition qmutex.h:285
\inmodule QtCore\reentrant
Definition qpoint.h:214
QAtomicInt ref
Definition qshareddata.h:21
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1107
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
\inmodule QtCore
Definition qvariant.h:64
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:531
bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
Definition qicc.cpp:604
QByteArray toIccProfile(const QColorSpace &space)
Definition qicc.cpp:280
Combined button and popup list for selecting options.
Definition image.cpp:4
static void cleanupPredefinedColorspaces()
QDataStream & operator>>(QDataStream &s, QColorSpace &colorSpace)
QDataStream & operator<<(QDataStream &s, const QColorSpace &image)
static Q_CONSTINIT QAtomicPointer< QColorSpacePrivate > s_predefinedColorspacePrivates[QColorSpace::ProPhotoRgb]
#define Q_UNLIKELY(x)
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:303
#define qWarning
Definition qlogging.h:162
static ControlElement< T > * ptr(QWidget *widget)
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLuint GLenum GLenum transform
GLdouble s
[6]
Definition qopenglext.h:235
GLenum GLenum GLsizei void * table
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QT_DEFINE_QESDP_SPECIALIZATION_DTOR(Class)
#define QStringLiteral(str)
QTextStream out(stdout)
[7]
QSharedPointer< T > other(t)
[5]