89 return (
a << 24) | (
b << 16) | (
c << 8) |
d;
212 static int toFixedS1516(
float x)
214 return int(
x * 65536.0f + 0.5f);
217 static float fromFixedS1516(
int x)
219 return x * (1.0f / 65536.0f);
225 qCWarning(lcIcc,
"Failed ICC signature test");
231 qCWarning(lcIcc,
"Failed tag count sanity");
235 qCWarning(lcIcc,
"Failed basic size sanity");
251 if (
header.pcs != 0x58595a20 ) {
258 illuminant.
x = fromFixedS1516(
header.illuminantXyz[0]);
259 illuminant.
y = fromFixedS1516(
header.illuminantXyz[1]);
260 illuminant.
z = fromFixedS1516(
header.illuminantXyz[2]);
262 qCWarning(lcIcc,
"Invalid ICC illuminant");
321 constexpr
int tagCount = 9;
322 constexpr
uint profileDataOffset = 128 + 4 + 12 * tagCount;
323 constexpr
uint variableTagTableOffsets = 128 + 4 + 12 * 5;
324 uint currentOffset = 0;
325 uint rTrcOffset, gTrcOffset, bTrcOffset;
326 uint rTrcSize, gTrcSize, bTrcSize;
327 uint descOffset, descSize;
348 stream <<
IccTag(
'Q',
't', QT_VERSION_MAJOR, QT_VERSION_MINOR);
365 currentOffset = profileDataOffset;
389 rTrcOffset = currentOffset;
390 rTrcSize = writeColorTrc(
stream, spaceDPtr->
trc[0]);
391 currentOffset += rTrcSize;
392 if (spaceDPtr->
trc[0] == spaceDPtr->
trc[1]) {
393 gTrcOffset = rTrcOffset;
396 gTrcOffset = currentOffset;
397 gTrcSize = writeColorTrc(
stream, spaceDPtr->
trc[1]);
398 currentOffset += gTrcSize;
400 if (spaceDPtr->
trc[0] == spaceDPtr->
trc[2]) {
401 bTrcOffset = rTrcOffset;
404 bTrcOffset = currentOffset;
405 bTrcSize = writeColorTrc(
stream, spaceDPtr->
trc[2]);
406 currentOffset += bTrcSize;
409 descOffset = currentOffset;
418 descSize = 90 + description.
size() + 1;
419 currentOffset += descSize;
426 *(
quint32_be *)(iccProfile.
data() + variableTagTableOffsets + 4) = rTrcOffset;
427 *(
quint32_be *)(iccProfile.
data() + variableTagTableOffsets + 8) = rTrcSize;
428 *(
quint32_be *)(iccProfile.
data() + variableTagTableOffsets + 12 + 4) = gTrcOffset;
429 *(
quint32_be *)(iccProfile.
data() + variableTagTableOffsets + 12 + 8) = gTrcSize;
430 *(
quint32_be *)(iccProfile.
data() + variableTagTableOffsets + 2 * 12 + 4) = bTrcOffset;
431 *(
quint32_be *)(iccProfile.
data() + variableTagTableOffsets + 2 * 12 + 8) = bTrcSize;
432 *(
quint32_be *)(iccProfile.
data() + variableTagTableOffsets + 3 * 12 + 4) = descOffset;
433 *(
quint32_be *)(iccProfile.
data() + variableTagTableOffsets + 3 * 12 + 8) = descSize;
435 #if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS)
438 Q_ASSERT(isValidIccProfile(*iccHeader));
452 qCWarning(lcIcc) <<
"Undersized XYZ tag";
457 qCWarning(lcIcc) <<
"Bad XYZ content type";
460 const float x = fromFixedS1516(xyz.
fixedX);
461 const float y = fromFixedS1516(xyz.
fixedY);
462 const float z = fromFixedS1516(xyz.
fixedZ);
475 if (
curv.valueCount > (1 << 16))
477 if (tagEntry.
size - 12 < 2 *
curv.valueCount)
480 if (
curv.valueCount == 0) {
483 }
else if (
curv.valueCount == 1) {
484 const quint16 v = qFromBigEndian<quint16>(
data.constData() + valueOffset);
491 "GenericTagData has padding. The following code is a subject to UB.");
492 qFromBigEndian<quint16>(
data.constData() + valueOffset,
curv.valueCount, tabl.
data());
495 if (!
table.checkValidity()) {
496 qCWarning(lcIcc) <<
"Invalid curv table";
498 }
else if (!
table.asColorTransferFunction(&curve)) {
502 qCDebug(lcIcc) <<
"Detected curv table as function";
514 switch (
para.curveType) {
518 qFromBigEndian<quint32>(
data.constData() + parametersOffset, 1, parameters);
519 float g = fromFixedS1516(parameters[0]);
527 qFromBigEndian<quint32>(
data.constData() + parametersOffset, 3, parameters);
528 if (parameters[1] == 0)
530 float g = fromFixedS1516(parameters[0]);
531 float a = fromFixedS1516(parameters[1]);
532 float b = fromFixedS1516(parameters[2]);
541 qFromBigEndian<quint32>(
data.constData() + parametersOffset, 4, parameters);
542 if (parameters[1] == 0)
544 float g = fromFixedS1516(parameters[0]);
545 float a = fromFixedS1516(parameters[1]);
546 float b = fromFixedS1516(parameters[2]);
547 float c = fromFixedS1516(parameters[3]);
556 qFromBigEndian<quint32>(
data.constData() + parametersOffset, 5, parameters);
557 float g = fromFixedS1516(parameters[0]);
558 float a = fromFixedS1516(parameters[1]);
559 float b = fromFixedS1516(parameters[2]);
560 float c = fromFixedS1516(parameters[3]);
561 float d = fromFixedS1516(parameters[4]);
569 qFromBigEndian<quint32>(
data.constData() + parametersOffset, 7, parameters);
570 float g = fromFixedS1516(parameters[0]);
571 float a = fromFixedS1516(parameters[1]);
572 float b = fromFixedS1516(parameters[2]);
573 float c = fromFixedS1516(parameters[3]);
574 float d = fromFixedS1516(parameters[4]);
575 float e = fromFixedS1516(parameters[5]);
576 float f = fromFixedS1516(parameters[6]);
587 qCWarning(lcIcc) <<
"Invalid TRC data type";
605 if (asciiDescription[
len - 1] !=
'\0')
616 if (
mluc.recordCount < 1)
618 if (
mluc.recordSize < 12)
621 const quint32 stringOffset =
mluc.records[0].offset;
623 if (tagEntry.
size < stringOffset || tagEntry.
size - stringOffset < stringSize )
625 if ((stringSize | stringOffset) & 1)
627 quint32 stringLen = stringSize / 2;
629 qFromBigEndian<char16_t>(
data.constData() + tagEntry.
offset + stringOffset, stringLen,
630 utf16hostendian.
data());
632 if (stringLen > 1 && utf16hostendian[stringLen - 1] == 0)
641 qCWarning(lcIcc) <<
"fromIccProfile: failed size sanity 1";
645 if (!isValidIccProfile(
header))
648 qCWarning(lcIcc) <<
"fromIccProfile: failed size sanity 2";
654 if (offsetToData >
data.size()) {
655 qCWarning(lcIcc) <<
"fromIccProfile: failed index size sanity";
668 qCWarning(lcIcc) <<
"fromIccProfile: failed tag offset sanity 1";
673 qCWarning(lcIcc) <<
"fromIccProfile: failed tag offset sanity 2";
676 if (tagTable.
size < 12) {
677 qCWarning(lcIcc) <<
"fromIccProfile: failed minimal tag size sanity";
681 qCWarning(lcIcc) <<
"fromIccProfile: failed tag offset + size sanity";
684 if (tagTable.
offset & 0x03) {
685 qCWarning(lcIcc) <<
"fromIccProfile: invalid tag offset alignment";
699 qCInfo(lcIcc) <<
"fromIccProfile: Unsupported ICC profile - not three component matrix based";
705 qCWarning(lcIcc) <<
"fromIccProfile: Invalid ICC profile - not valid gray scale based";
726 qCDebug(lcIcc) <<
"fromIccProfile: sRGB primaries detected";
729 qCDebug(lcIcc) <<
"fromIccProfile: Adobe RGB primaries detected";
732 qCDebug(lcIcc) <<
"fromIccProfile: DCI-P3 D65 primaries detected";
736 qCDebug(lcIcc) <<
"fromIccProfile: ProPhoto RGB primaries detected";
745 if (!
qFuzzyCompare(whitePoint.
y, 1.0f) || (1.0f + whitePoint.
z + whitePoint.
x) == 0.0f) {
746 qCWarning(lcIcc) <<
"fromIccProfile: Invalid ICC profile - gray white-point not normalized";
754 float y = 1.0f / (1.0f + whitePoint.
z + whitePoint.
x);
755 float x = whitePoint.
x *
y;
759 qCWarning(lcIcc,
"fromIccProfile: Invalid ICC profile - invalid white-point(%f, %f)",
x,
y);
792 qCWarning(lcIcc) <<
"fromIccProfile: Invalid rTRC";
796 qCWarning(lcIcc) <<
"fromIccProfile: Invalid gTRC";
800 qCWarning(lcIcc) <<
"fromIccProfile: Invalid bTRC";
805 qCDebug(lcIcc) <<
"fromIccProfile: Linear gamma detected";
808 colorspaceDPtr->
gamma = 1.0f;
810 qCDebug(lcIcc) <<
"fromIccProfile: Simple gamma detected";
815 qCDebug(lcIcc) <<
"fromIccProfile: sRGB gamma detected";
819 colorspaceDPtr->
trc[0] = rCurve;
823 colorspaceDPtr->
trc[1] = colorspaceDPtr->
trc[0];
824 colorspaceDPtr->
trc[2] = colorspaceDPtr->
trc[0];
826 colorspaceDPtr->
trc[0] = rCurve;
827 colorspaceDPtr->
trc[1] = gCurve;
828 colorspaceDPtr->
trc[2] = bCurve;
834 qCWarning(lcIcc) <<
"fromIccProfile: Failed to parse description";
small capitals from c petite p scientific i
[1]
The QBuffer class provides a QIODevice interface for a QByteArray.
The QByteArray class provides an array of bytes.
qsizetype size() const noexcept
const char * constData() const noexcept
static QColorMatrix toXyzFromSRgb()
static QColorMatrix toXyzFromAdobeRgb()
static QColorMatrix toXyzFromDciP3D65()
static QColorMatrix toXyzFromProPhotoRgb()
The QColorSpace class provides a color space abstraction.
bool isValid() const noexcept
QString description() const noexcept
QColorMatrix toXyzMatrix() const
QColorSpace::NamedColorSpace namedColorSpace
void identifyColorSpace()
static const QColorSpacePrivate * get(const QColorSpace &colorSpace)
QColorSpace::Primaries primaries
QColorSpace::TransferFunction transferFunction
static QColorTransferFunction fromGamma(float gamma)
static QColorTransferFunction fromSRgb()
QList< uint8_t > m_table8
QList< uint16_t > m_table16
QColorTransferFunction m_fun
QColorTransferTable m_table
static constexpr QColorVector D50()
static constexpr QColorVector D65()
The QDataStream class provides serialization of binary data to a QIODevice.
template< typename Enum > size_t qHash(QFlags< Enum > flags, size_t seed=0) noexcept
The QHash class is a template class that provides a hash-table-based dictionary.
bool contains(const Key &key) const noexcept
iterator insert(const Key &key, const T &value)
bool isEmpty() const noexcept
void resize(qsizetype size)
The QPointF class defines a point in the plane using floating point precision.
The QString class provides a Unicode character string.
static QString fromLatin1(QByteArrayView ba)
static QString fromUtf16(const char16_t *, qsizetype size=-1)
QByteArray toUtf8() const &
bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
QByteArray toIccProfile(const QColorSpace &space)
bool parseTRC(const QByteArray &data, const TagEntry &tagEntry, QColorTrc &gamma)
bool parseXyzData(const QByteArray &data, const TagEntry &tagEntry, QColorVector &colorVector)
bool parseDesc(const QByteArray &data, const TagEntry &tagEntry, QString &descName)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
bool qFuzzyIsNull(qfloat16 f) noexcept
#define Q_STATIC_ASSERT(Condition)
QT_BEGIN_INCLUDE_NAMESPACE typedef unsigned char uchar
constexpr quint32 IccTag(uchar a, uchar b, uchar c, uchar d)
#define Q_LOGGING_CATEGORY(name,...)
#define qCInfo(category,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei void * table
QHttpRequestHeader header("GET", QUrl::toPercentEncoding("/index.html"))
[1]
quint32_be asciiDescriptionLength
XmlOutput::xml_output tag(const QString &name)