DOne with the parsing side of things

This commit is contained in:
samcake 2017-02-15 16:24:06 -08:00 committed by Brad Davis
parent 115251542d
commit 894f1b8e66
3 changed files with 114 additions and 39 deletions

View file

@ -49,8 +49,8 @@ size_t Header::evalRowSize(uint32_t level) const {
auto pixelWidth = evalPixelWidth(level); auto pixelWidth = evalPixelWidth(level);
auto pixSize = evalPixelSize(); auto pixSize = evalPixelSize();
auto netSize = pixelWidth * pixSize; auto netSize = pixelWidth * pixSize;
auto packing = netSize % 4; auto packing = netSize % PACKING_SIZE;
return netSize + (packing ? 4 - packing : 0); return netSize + (packing ? PACKING_SIZE - packing : 0);
} }
size_t Header::evalFaceSize(uint32_t level) const { size_t Header::evalFaceSize(uint32_t level) const {
auto pixelHeight = evalPixelHeight(level); auto pixelHeight = evalPixelHeight(level);
@ -83,6 +83,23 @@ const Header* KTX::getHeader() const {
} }
} }
size_t KTX::getKeyValueDataSize() const {
if (_storage) {
return getHeader()->bytesOfKeyValueData;
} else {
return 0;
}
}
size_t KTX::getTexelsDataSize() const {
if (_storage) {
return _storage->size() - sizeof(Header) + getKeyValueDataSize();
} else {
return 0;
}
}
const Byte* KTX::getKeyValueData() const { const Byte* KTX::getKeyValueData() const {
if (_storage) { if (_storage) {
return (_storage->_bytes + sizeof(Header)); return (_storage->_bytes + sizeof(Header));
@ -90,3 +107,11 @@ const Byte* KTX::getKeyValueData() const {
return nullptr; return nullptr;
} }
} }
const Byte* KTX::getTexelsData() const {
if (_storage) {
return (_storage->_bytes + sizeof(Header) + getKeyValueDataSize());
} else {
return nullptr;
}
}

View file

@ -66,6 +66,7 @@ end
namespace ktx { namespace ktx {
const uint32_t PACKING_SIZE { sizeof(uint32_t) };
enum GLType : uint32_t { enum GLType : uint32_t {
COMPRESSED_TYPE = 0, COMPRESSED_TYPE = 0,
@ -317,6 +318,17 @@ namespace ktx {
{ {
if (_size && _bytes) { _bytes = bytes; } if (_size && _bytes) { _bytes = bytes; }
} }
Storage(size_t size, const Byte* bytes) :
Storage(size)
{
if (_size && _bytes && bytes) {
memcpy(_bytes, bytes, size);
}
}
Storage(const Storage& src) :
Storage(src.size(), src.data())
{}
}; };
// Header // Header
@ -364,8 +376,14 @@ namespace ktx {
struct Mip { struct Mip {
uint32_t imageSize; uint32_t _imageSize;
uint32_t _padding;
const Byte* _bytes; const Byte* _bytes;
Mip(uint32_t imageSize, uint32_t padding, const Byte* bytes) :
_imageSize(imageSize),
_padding(padding),
_bytes(bytes) {}
}; };
using Mips = std::vector<Mip>; using Mips = std::vector<Mip>;
@ -375,21 +393,26 @@ namespace ktx {
public: public:
KTX(); KTX();
~KTX();
bool read(const Storage* src); // parse a block of memory and create a KTX object from it
bool read(Storage* src); static std::unique_ptr<KTX> create(const Storage& src);
static std::unique_ptr<KTX> create(std::unique_ptr<Storage>& src);
std::unique_ptr<Storage> _storage;
const Header* getHeader() const;
const Byte* getKeyValueData() const;
KeyValues _keyValues;
Mips _mips;
static bool checkStorageHeader(const Storage& storage); static bool checkStorageHeader(const Storage& storage);
static KTX* create(const Storage* src);
// Access raw pointers to the main sections of the KTX
const Header* getHeader() const;
const Byte* getKeyValueData() const;
const Byte* getTexelsData() const;
size_t getKeyValueDataSize() const;
size_t getTexelsDataSize() const;
std::unique_ptr<Storage> _storage;
KeyValues _keyValues;
Mips _mips;
}; };
} }

View file

@ -73,7 +73,7 @@ namespace ktx {
std::move(std::string(reinterpret_cast<const char*>(src + keyLength), keyValueByteSize - keyLength))); std::move(std::string(reinterpret_cast<const char*>(src + keyLength), keyValueByteSize - keyLength)));
// advance offset/src // advance offset/src
uint32_t keyValuePadding = 3 - ((keyValueByteSize + 3) % 4); uint32_t keyValuePadding = 3 - ((keyValueByteSize + 3) % PACKING_SIZE);
offset += keyValueByteSize + keyValuePadding; offset += keyValueByteSize + keyValuePadding;
src += keyValueByteSize + keyValuePadding; src += keyValueByteSize + keyValuePadding;
} }
@ -81,16 +81,39 @@ namespace ktx {
return keyValues; return keyValues;
} }
bool KTX::read(Storage* src) { Mips getMipsTable(const Header& header, size_t mipsDataSize, const Byte* mipsData) {
resetStorage(src); Mips mips;
auto currentPtr = mipsData;
auto numMips = header.numberOfMipmapLevels + 1;
return true; // Keep identifying new mip as long as we can at list query the next imageSize
while ((currentPtr - mipsData) + sizeof(uint32_t) <= (mipsDataSize)) {
// Grab the imageSize coming up
auto imageSize = *reinterpret_cast<const uint32_t*>(currentPtr);
currentPtr += sizeof(uint32_t);
// If enough data ahead then capture the pointer
if ((currentPtr - mipsData) + imageSize <= (mipsDataSize)) {
auto padding = imageSize % PACKING_SIZE;
padding = (padding ? 4 - padding : 0);
mips.emplace_back(Mip(imageSize, padding, currentPtr));
currentPtr += imageSize + padding;
} else {
break;
}
}
return mips;
} }
bool KTX::checkStorageHeader(const Storage& src) { bool KTX::checkStorageHeader(const Storage& src) {
try { try {
size_t srcSize = src.size(); auto srcSize = src.size();
const uint8_t* srcBytes = src.data(); auto srcBytes = src.data();
// validation // validation
if (srcSize < sizeof(Header)) { if (srcSize < sizeof(Header)) {
@ -121,16 +144,6 @@ namespace ktx {
throw Exception("length is too short for data"); throw Exception("length is too short for data");
} }
// read metadata
KeyValues keyValues = getKeyValues(header->bytesOfKeyValueData, srcBytes + sizeof(Header));
// prepare gpu::Texture using header & key-values
// TODO
// read data
// TODO
return true; return true;
} catch (Exception& e) { } catch (Exception& e) {
qWarning(e.what()); qWarning(e.what());
@ -138,20 +151,34 @@ namespace ktx {
} }
} }
KTX* KTX::create(const Storage* data) { std::unique_ptr<KTX> KTX::create(const Storage& src) {
auto srcCopy = std::make_unique<Storage>(src);
return create(srcCopy);
}
std::unique_ptr<KTX> KTX::create(std::unique_ptr<Storage>& src) {
if (!src) {
return nullptr;
}
try { try {
if (!checkStorageHeader(*data)) { if (!checkStorageHeader(*src)) {
} }
auto result = new KTX(); std::unique_ptr<KTX> result(new KTX());
result->resetStorage(const_cast<Storage*>(data)); result->resetStorage(src.release());
// read metadata // read metadata
KeyValues keyValues = getKeyValues(result->getHeader()->bytesOfKeyValueData, result->getKeyValueData()); result->_keyValues = getKeyValues(result->getHeader()->bytesOfKeyValueData, result->getKeyValueData());
return nullptr; // populate mip table
} catch (Exception& e) { result->_mips = getMipsTable(*result->getHeader(), result->getTexelsDataSize(), result->getTexelsData());
return result;
}
catch (Exception& e) {
qWarning(e.what()); qWarning(e.what());
return nullptr; return nullptr;
} }