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