Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qpkmhandler.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 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// Qt-Security score:critical reason:data-parser
4
7
8#include <QFile>
9#include <QDebug>
10#include <QSize>
11#include <qendian.h>
12
13//#define ETC_DEBUG
14
16
17static const int qpkmh_headerSize = 16;
18
24
25static constexpr PkmType typeMap[5] = {
26 { 0x8D64, 8 }, // GL_ETC1_RGB8_OES
27 { 0x9274, 8 }, // GL_COMPRESSED_RGB8_ETC2
28 { 0, 0 }, // unused (obsolete)
29 { 0x9278, 16}, // GL_COMPRESSED_RGBA8_ETC2_EAC
30 { 0x9276, 8 } // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
31};
32
33QPkmHandler::~QPkmHandler() = default;
34
35bool QPkmHandler::canRead(const QByteArray &suffix, const QByteArray &block)
36{
37 Q_UNUSED(suffix);
38
39 return block.startsWith("PKM ");
40}
41
43{
44 QTextureFileData texData;
45
46 if (!device())
47 return texData;
48
49 QByteArray fileData = device()->readAll();
50 if (fileData.size() < qpkmh_headerSize || !canRead(QByteArray(), fileData)) {
51 qCDebug(lcQtGuiTextureIO, "Invalid PKM file %s", logName().constData());
52 return QTextureFileData();
53 }
54 texData.setData(fileData);
55
56 const char *rawData = fileData.constData();
57
58 // ignore version (rawData + 4 & 5)
59
60 // texture type
61 quint16 type = qFromBigEndian<quint16>(rawData + 6);
62 if (type >= sizeof(typeMap)/sizeof(typeMap[0])) {
63 qCDebug(lcQtGuiTextureIO, "Unknown compression format in PKM file %s", logName().constData());
64 return QTextureFileData();
65 }
66 texData.setGLFormat(0); // 0 for compressed textures
67 texData.setGLInternalFormat(typeMap[type].glFormat);
68 //### setBaseInternalFormat
69
70 // texture size
71 texData.setNumLevels(1);
72 texData.setNumFaces(1);
73 const int bpb = typeMap[type].bytesPerBlock;
74 QSize paddedSize(qFromBigEndian<quint16>(rawData + 8), qFromBigEndian<quint16>(rawData + 10));
75 texData.setDataLength((paddedSize.width() / 4) * (paddedSize.height() / 4) * bpb);
76 QSize texSize(qFromBigEndian<quint16>(rawData + 12), qFromBigEndian<quint16>(rawData + 14));
77 texData.setSize(texSize);
78
79 texData.setDataOffset(qpkmh_headerSize);
80
81 if (!texData.isValid()) {
82 qCDebug(lcQtGuiTextureIO, "Invalid values in header of PKM file %s", logName().constData());
83 return QTextureFileData();
84 }
85
86 texData.setLogName(logName());
87
88#ifdef ETC_DEBUG
89 qDebug() << "PKM file handler read" << texData;
90#endif
91 return texData;
92}
93
94QT_END_NAMESPACE
~QPkmHandler() override
QTextureFileData read() override
static QT_BEGIN_NAMESPACE const int qpkmh_headerSize
static constexpr PkmType typeMap[5]
quint32 bytesPerBlock
quint32 glFormat