Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qssgexrcodecs.cpp
Go to the documentation of this file.
1
// Copyright (C) 2026 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
// Qt-Security score:critical reason:data-parser
4
5
#
include
<
QtQuick3DTextureHelpers
/
private
/
qssgexrcodecs_p
.
h
>
6
7
#
include
<
QtCore
/
qnumeric
.
h
>
8
9
#
include
<
zlib
.
h
>
10
11
#
include
<
cstring
>
12
13
QT_BEGIN_NAMESPACE
14
15
namespace
QSSGExr
{
16
17
bool
undoPredictorAndDeinterleave
(QSpan<
char
> out, QSpan<
char
> scratch, QString *error)
18
{
19
const
qsizetype n = out.size();
20
if
(scratch.size() < n) {
21
*error = QStringLiteral(
"predictor scratch is smaller than the chunk"
);
22
return
false
;
23
}
24
if
(n <= 0)
25
return
true
;
26
27
quint8 *t =
reinterpret_cast
<quint8 *>(scratch.data());
28
for
(qsizetype i = 1; i < n; ++i)
29
t[i] = quint8(quint32(t[i - 1]) + quint32(t[i]) - 128u);
30
31
const
qsizetype half = (n + 1) / 2;
32
const
quint8 *t1 = t;
33
const
quint8 *t2 = t + half;
34
quint8 *s =
reinterpret_cast
<quint8 *>(out.data());
35
for
(qsizetype i = 0; i < n; i += 2) {
36
s[i] = *t1++;
37
if
(i + 1 < n)
38
s[i + 1] = *t2++;
39
}
40
41
return
true
;
42
}
43
44
bool
inflateExact
(QByteArrayView in, QSpan<
char
> out, QString *error)
45
{
46
if
(in.isEmpty() || out.isEmpty()) {
47
*error = QStringLiteral(
"empty compressed chunk"
);
48
return
false
;
49
}
50
if
(quint64(in.size()) > std::numeric_limits<uInt>::max() || quint64(out.size()) > std::numeric_limits<uInt>::max()) {
51
*error = QStringLiteral(
"compressed chunk is too large"
);
52
return
false
;
53
}
54
55
z_stream zs = {};
56
if
(inflateInit(&zs) != Z_OK) {
57
*error = QStringLiteral(
"could not initialise zlib"
);
58
return
false
;
59
}
60
61
zs.next_in =
reinterpret_cast
<Bytef *>(
const_cast
<
char
*>(in.data()));
62
zs.avail_in = uInt(in.size());
63
zs.next_out =
reinterpret_cast
<Bytef *>(out.data());
64
zs.avail_out = uInt(out.size());
65
66
const
int
ret = inflate(&zs, Z_FINISH);
67
const
bool
complete = ret == Z_STREAM_END;
68
const
bool
exact = zs.avail_out == 0 && zs.avail_in == 0;
69
inflateEnd(&zs);
70
71
if
(!complete || !exact) {
72
*error = QStringLiteral(
"corrupt zlib stream in chunk"
);
73
return
false
;
74
}
75
return
true
;
76
}
77
78
bool
rleDecode
(QByteArrayView in, QSpan<
char
> out, QString *error)
79
{
80
const
qint8 *ip =
reinterpret_cast
<
const
qint8 *>(in.data());
81
const
qint8 *iend = ip + in.size();
82
char
*op = out.data();
83
qsizetype produced = 0;
84
85
while
(ip < iend) {
86
const
qint8 tag = *ip++;
87
if
(tag < 0) {
88
const
qsizetype count = -qsizetype(tag);
89
if
(count > iend - ip || count > out.size() - produced) {
90
*error = QStringLiteral(
"corrupt RLE stream in chunk"
);
91
return
false
;
92
}
93
memcpy(op + produced, ip, size_t(count));
94
ip += count;
95
produced += count;
96
}
else
{
97
const
qsizetype count = qsizetype(tag) + 1;
98
if
(ip >= iend || count > out.size() - produced) {
99
*error = QStringLiteral(
"corrupt RLE stream in chunk"
);
100
return
false
;
101
}
102
memset(op + produced, *
reinterpret_cast
<
const
char
*>(ip), size_t(count));
103
++ip;
104
produced += count;
105
}
106
}
107
108
if
(produced != out.size()) {
109
*error = QStringLiteral(
"RLE stream does not fill the chunk"
);
110
return
false
;
111
}
112
return
true
;
113
}
114
115
}
// namespace QSSGExr
116
117
QT_END_NAMESPACE
QSSGExr
Definition
qssgexrcodecs.cpp:15
QSSGExr::undoPredictorAndDeinterleave
bool undoPredictorAndDeinterleave(QSpan< char > out, QSpan< char > scratch, QString *error)
Definition
qssgexrcodecs.cpp:17
QSSGExr::inflateExact
bool inflateExact(QByteArrayView in, QSpan< char > out, QString *error)
Definition
qssgexrcodecs.cpp:44
QSSGExr::rleDecode
bool rleDecode(QByteArrayView in, QSpan< char > out, QString *error)
Definition
qssgexrcodecs.cpp:78
qtquick3d
src
texturehelpers
qssgexrcodecs.cpp
Generated on
for Qt by
1.18.0