1/****************************************************************************
2**
3** Copyright (C) 2018 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#include "qtexturefiledata_p.h"
41#include <QMetaEnum>
42#include <QSize>
43#if QT_CONFIG(opengl)
44#include <QOpenGLTexture>
45#endif
46
47QT_BEGIN_NAMESPACE
48
49Q_LOGGING_CATEGORY(lcQtGuiTextureIO, "qt.gui.textureio");
50
51class QTextureFileDataPrivate : public QSharedData
52{
53public:
54 QTextureFileDataPrivate()
55 {
56 }
57
58 QTextureFileDataPrivate(const QTextureFileDataPrivate &other)
59 : QSharedData(other),
60 logName(other.logName),
61 data(other.data),
62 offsets(other.offsets),
63 lengths(other.lengths),
64 size(other.size),
65 format(other.format)
66 {
67 }
68
69 ~QTextureFileDataPrivate()
70 {
71 }
72
73 void ensureLevels(int num, bool force = false)
74 {
75 const int newSize = force ? num : qMax(a: offsets.size(), b: num);
76 offsets.resize(asize: newSize);
77 lengths.resize(asize: newSize);
78 }
79
80 QByteArray logName;
81 QByteArray data;
82 QVector<int> offsets;
83 QVector<int> lengths;
84 QSize size;
85 quint32 format = 0;
86 quint32 internalFormat = 0;
87 quint32 baseInternalFormat = 0;
88};
89
90
91
92QTextureFileData::QTextureFileData()
93{
94}
95
96QTextureFileData::QTextureFileData(const QTextureFileData &other)
97 : d(other.d)
98{
99}
100
101QTextureFileData &QTextureFileData::operator=(const QTextureFileData &other)
102{
103 d = other.d;
104 return *this;
105}
106
107QTextureFileData::~QTextureFileData()
108{
109}
110
111bool QTextureFileData::isNull() const
112{
113 return !d;
114}
115
116bool QTextureFileData::isValid() const
117{
118 if (!d)
119 return false;
120
121 if (d->data.isEmpty() || d->size.isEmpty() || (!d->format && !d->internalFormat))
122 return false;
123
124 const int numChunks = d->offsets.size();
125 if (numChunks == 0 || (d->lengths.size() != numChunks))
126 return false;
127
128 const qint64 sz = d->data.size();
129 for (int i = 0; i < numChunks; i++) {
130 qint64 offi = d->offsets.at(i);
131 qint64 leni = d->lengths.at(i);
132 if (offi < 0 || offi >= sz || leni <= 0 || (offi + leni > sz))
133 return false;
134 }
135 return true;
136}
137
138void QTextureFileData::clear()
139{
140 d = nullptr;
141}
142
143QByteArray QTextureFileData::data() const
144{
145 return d ? d->data : QByteArray();
146}
147
148void QTextureFileData::setData(const QByteArray &data)
149{
150 if (!d.constData()) //### uh think about this design, this is the only way to create; should be constructor instead at least
151 d = new QTextureFileDataPrivate;
152
153 d->data = data;
154}
155
156int QTextureFileData::dataOffset(int level) const
157{
158 return (d && d->offsets.size() > level) ? d->offsets.at(i: level) : 0;
159}
160
161void QTextureFileData::setDataOffset(int offset, int level)
162{
163 if (d.constData() && level >= 0) {
164 d->ensureLevels(num: level + 1);
165 d->offsets[level] = offset;
166 }
167}
168
169int QTextureFileData::dataLength(int level) const
170{
171 return (d && d->lengths.size() > level) ? d->lengths.at(i: level) : 0;
172}
173
174void QTextureFileData::setDataLength(int length, int level)
175{
176 if (d.constData() && level >= 0) {
177 d->ensureLevels(num: level + 1);
178 d->lengths[level] = length;
179 }
180}
181
182int QTextureFileData::numLevels() const
183{
184 return d ? d->offsets.size() : 0;
185}
186
187void QTextureFileData::setNumLevels(int num)
188{
189 if (d && num >= 0)
190 d->ensureLevels(num, force: true);
191}
192
193QSize QTextureFileData::size() const
194{
195 return d ? d->size : QSize();
196}
197
198void QTextureFileData::setSize(const QSize &size)
199{
200 if (d.constData())
201 d->size = size;
202}
203
204quint32 QTextureFileData::glFormat() const
205{
206 return d ? d->format : 0;
207}
208
209void QTextureFileData::setGLFormat(quint32 format)
210{
211 if (d.constData())
212 d->format = format;
213}
214
215quint32 QTextureFileData::glInternalFormat() const
216{
217 return d ? d->internalFormat : 0;
218}
219
220void QTextureFileData::setGLInternalFormat(quint32 format)
221{
222 if (d.constData())
223 d->internalFormat = format;
224}
225
226quint32 QTextureFileData::glBaseInternalFormat() const
227{
228 return d ? d->baseInternalFormat : 0;
229}
230
231void QTextureFileData::setGLBaseInternalFormat(quint32 format)
232{
233 if (d.constData())
234 d->baseInternalFormat = format;
235}
236
237QByteArray QTextureFileData::logName() const
238{
239 return d ? d->logName : QByteArray();
240}
241
242void QTextureFileData::setLogName(const QByteArray &name)
243{
244 if (d.constData())
245 d->logName = name;
246}
247
248static QByteArray glFormatName(quint32 fmt)
249{
250 const char *id = nullptr;
251#if QT_CONFIG(opengl)
252 id = QMetaEnum::fromType<QOpenGLTexture::TextureFormat>().valueToKey(value: fmt);
253#endif
254 QByteArray res(id ? id : "(?)");
255 res += " [0x" + QByteArray::number(fmt, base: 16).rightJustified(width: 4, fill: '0') + ']';
256 return res;
257}
258
259QDebug operator<<(QDebug dbg, const QTextureFileData &d)
260{
261 QDebugStateSaver saver(dbg);
262
263 dbg.nospace() << "QTextureFileData(";
264 if (!d.isNull()) {
265 dbg.space() << d.logName() << d.size();
266 dbg << "glFormat:" << glFormatName(fmt: d.glFormat());
267 dbg << "glInternalFormat:" << glFormatName(fmt: d.glInternalFormat());
268 dbg << "glBaseInternalFormat:" << glFormatName(fmt: d.glBaseInternalFormat());
269 dbg.nospace() << "Levels: " << d.numLevels();
270 if (!d.isValid())
271 dbg << " {Invalid}";
272 dbg << ")";
273 } else {
274 dbg << "null)";
275 }
276
277 return dbg;
278}
279
280QT_END_NAMESPACE
281

source code of qtbase/src/gui/util/qtexturefiledata.cpp