mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 03:13:51 +02:00
Adding KeyValues read/write, work in progress
This commit is contained in:
parent
8782fe1d93
commit
c267b5cd09
4 changed files with 111 additions and 40 deletions
libraries/ktx/src/ktx
|
@ -71,6 +71,35 @@ size_t Header::evalImageSize(uint32_t level) const {
|
|||
}
|
||||
|
||||
|
||||
KeyValue::KeyValue(const std::string& key, uint32_t valueByteSize, const Byte* value) :
|
||||
_byteSize((uint32_t) key.size() + valueByteSize),
|
||||
_key(key),
|
||||
_value(valueByteSize)
|
||||
{
|
||||
if (_value.size() && value) {
|
||||
memcpy(_value.data(), value, valueByteSize);
|
||||
}
|
||||
}
|
||||
|
||||
KeyValue::KeyValue(const std::string& key, const std::string& value) :
|
||||
KeyValue(key, (uint32_t) value.size(), (const Byte*) value.data())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint32_t KeyValue::serializedByteSize() const {
|
||||
return (uint32_t) (sizeof(uint32_t) + _byteSize + Header::evalPadding(_byteSize));
|
||||
}
|
||||
|
||||
uint32_t KeyValue::serializedKeyValuesByteSize(const KeyValues& keyValues) {
|
||||
size_t keyValuesSize = 0;
|
||||
for (auto& keyval : keyValues) {
|
||||
keyValuesSize += keyval.serializedByteSize();
|
||||
}
|
||||
return (keyValuesSize + Header::evalPadding(keyValuesSize));
|
||||
}
|
||||
|
||||
|
||||
KTX::KTX() {
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include <shared/Storage.h>
|
||||
|
@ -385,9 +386,27 @@ namespace ktx {
|
|||
};
|
||||
|
||||
// Key Values
|
||||
using KeyValue = std::pair<std::string, std::string>;
|
||||
using KeyValues = std::list<KeyValue>;
|
||||
|
||||
struct KeyValue {
|
||||
uint32_t _byteSize { 0 };
|
||||
std::string _key;
|
||||
std::vector<Byte> _value;
|
||||
|
||||
|
||||
KeyValue(const std::string& key, uint32_t valueByteSize, const Byte* value);
|
||||
|
||||
KeyValue(const std::string& key, const std::string& value);
|
||||
|
||||
uint32_t serializedByteSize() const;
|
||||
|
||||
static KeyValue parseKeyAndValue(uint32_t keyAndValueByteSize, const Byte* bytes);
|
||||
static KeyValue parseSerializedKeyAndValue(uint32_t byteSizeAhead, const Byte* bytes);
|
||||
|
||||
using KeyValues = std::list<KeyValue>;
|
||||
static uint32_t serializedKeyValuesByteSize(const KeyValues& keyValues);
|
||||
|
||||
};
|
||||
using KeyValues = KeyValue::KeyValues;
|
||||
|
||||
|
||||
struct Image {
|
||||
using FaceBytes = std::vector<const Byte*>;
|
||||
|
@ -445,12 +464,14 @@ namespace ktx {
|
|||
// This is exactly what is done in the create function
|
||||
static size_t evalStorageSize(const Header& header, const Images& images, const KeyValues& keyValues = KeyValues());
|
||||
static size_t write(Byte* destBytes, size_t destByteSize, const Header& header, const Images& images, const KeyValues& keyValues = KeyValues());
|
||||
static size_t writeKeyValues(Byte* destBytes, size_t destByteSize, const KeyValues& keyValues);
|
||||
static Images writeImages(Byte* destBytes, size_t destByteSize, const Images& images);
|
||||
|
||||
// Parse a block of memory and create a KTX object from it
|
||||
static std::unique_ptr<KTX> create(const StoragePointer& src);
|
||||
|
||||
static bool checkHeaderFromStorage(size_t srcSize, const Byte* srcBytes);
|
||||
static KeyValues parseKeyValues(size_t srcSize, const Byte* srcBytes);
|
||||
static Images parseImages(const Header& header, size_t srcSize, const Byte* srcBytes);
|
||||
|
||||
// Access raw pointers to the main sections of the KTX
|
||||
|
|
|
@ -56,38 +56,52 @@ namespace ktx {
|
|||
return true;
|
||||
}
|
||||
|
||||
KeyValues getKeyValues(size_t length, const Byte* src) {
|
||||
KeyValues keyValues;
|
||||
size_t offset = 0;
|
||||
|
||||
while (offset < length) {
|
||||
// determine byte size
|
||||
uint32_t keyValueByteSize;
|
||||
memcpy(&keyValueByteSize, src, sizeof(uint32_t));
|
||||
if (keyValueByteSize > length - offset) {
|
||||
throw ReaderException("invalid key-value size");
|
||||
KeyValue KeyValue::parseKeyAndValue(uint32_t keyAndValueByteSize, const Byte* bytes) {
|
||||
// find the first null character \0
|
||||
uint32_t keyLength = 0;
|
||||
while (reinterpret_cast<const char*>(bytes[++keyLength]) != '\0') {
|
||||
if (keyLength == keyAndValueByteSize) {
|
||||
// key must be null-terminated, and there must be space for the value
|
||||
throw ReaderException("invalid key-value " + std::string(reinterpret_cast<const char*>(bytes), keyLength));
|
||||
}
|
||||
|
||||
// find the first null character \0
|
||||
uint32_t keyLength = 0;
|
||||
while (reinterpret_cast<const char*>(src[++keyLength]) != '\0') {
|
||||
if (keyLength == keyValueByteSize) {
|
||||
// key must be null-terminated, and there must be space for the value
|
||||
throw ReaderException("invalid key-value " + std::string(reinterpret_cast<const char*>(src), keyLength));
|
||||
}
|
||||
}
|
||||
|
||||
// populate the key-value
|
||||
keyValues.emplace_back(
|
||||
std::move(std::string(reinterpret_cast<const char*>(src), keyLength)),
|
||||
std::move(std::string(reinterpret_cast<const char*>(src + keyLength), keyValueByteSize - keyLength)));
|
||||
|
||||
// advance offset/src
|
||||
uint32_t keyValuePadding = 3 - ((keyValueByteSize + 3) % PACKING_SIZE);
|
||||
offset += keyValueByteSize + keyValuePadding;
|
||||
src += keyValueByteSize + keyValuePadding;
|
||||
}
|
||||
|
||||
return KeyValue(std::string(reinterpret_cast<const char*>(bytes), keyLength), keyAndValueByteSize - keyLength, bytes + keyLength);
|
||||
}
|
||||
|
||||
static KeyValue parseSerializedKeyAndValue(uint32_t byteSizeAhead, const Byte* bytes) {
|
||||
uint32_t keyValueByteSize;
|
||||
memcpy(&keyValueByteSize, bytes, sizeof(uint32_t));
|
||||
if (keyValueByteSize > byteSizeAhead) {
|
||||
throw ReaderException("invalid key-value size");
|
||||
}
|
||||
|
||||
auto keyValueBytes = bytes + sizeof(uint32_t);
|
||||
|
||||
// parse the key-value
|
||||
return KeyValue::parseKeyAndValue(keyValueByteSize, keyValueBytes);
|
||||
}
|
||||
|
||||
static KeyValues parseKeyValues(size_t srcSize, const Byte* srcBytes);
|
||||
|
||||
KeyValues KTX::parseKeyValues(size_t srcSize, const Byte* src) {
|
||||
KeyValues keyValues;
|
||||
try {
|
||||
uint32_t length = (uint32_t) srcSize;
|
||||
uint32_t offset = 0;
|
||||
while (offset < length) {
|
||||
auto keyValue = parseSerializedKeyAndValue(length - offset, src);
|
||||
keyValues.emplace_back(keyValue);
|
||||
|
||||
// advance offset/src
|
||||
offset += keyValue.serializedByteSize();
|
||||
src += keyValue.serializedByteSize();
|
||||
}
|
||||
}
|
||||
catch (const ReaderException& e) {
|
||||
qWarning() << e.what();
|
||||
}
|
||||
return keyValues;
|
||||
}
|
||||
|
||||
|
@ -176,7 +190,7 @@ namespace ktx {
|
|||
result->resetStorage(src);
|
||||
|
||||
// read metadata
|
||||
// result->_keyValues = getKeyValues(result->getHeader()->bytesOfKeyValueData, result->getKeyValueData());
|
||||
result->_keyValues = parseKeyValues(result->getHeader()->bytesOfKeyValueData, result->getKeyValueData());
|
||||
|
||||
// populate image table
|
||||
result->_images = parseImages(*result->getHeader(), result->getTexelsDataSize(), result->getTexelsData());
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace ktx {
|
|||
std::unique_ptr<KTX> KTX::create(const Header& header, const Images& images, const KeyValues& keyValues) {
|
||||
StoragePointer storagePointer;
|
||||
{
|
||||
auto storageSize = ktx::KTX::evalStorageSize(header, images);
|
||||
auto storageSize = ktx::KTX::evalStorageSize(header, images, keyValues);
|
||||
auto memoryStorage = new storage::MemoryStorage(storageSize);
|
||||
ktx::KTX::write(memoryStorage->data(), memoryStorage->size(), header, images);
|
||||
ktx::KTX::write(memoryStorage->data(), memoryStorage->size(), header, images, keyValues);
|
||||
storagePointer.reset(memoryStorage);
|
||||
}
|
||||
return create(storagePointer);
|
||||
|
@ -40,8 +40,9 @@ namespace ktx {
|
|||
size_t KTX::evalStorageSize(const Header& header, const Images& images, const KeyValues& keyValues) {
|
||||
size_t storageSize = sizeof(Header);
|
||||
|
||||
if (header.bytesOfKeyValueData && !keyValues.empty()) {
|
||||
|
||||
if (!keyValues.empty()) {
|
||||
size_t keyValuesSize = KeyValue::serializedKeyValuesByteSize(keyValues);
|
||||
storageSize += keyValuesSize;
|
||||
}
|
||||
|
||||
auto numMips = header.getNumberOfLevels();
|
||||
|
@ -68,11 +69,12 @@ namespace ktx {
|
|||
currentDestPtr += sizeof(Header);
|
||||
|
||||
// KeyValues
|
||||
// Skip for now
|
||||
if (header.bytesOfKeyValueData && !keyValues.empty()) {
|
||||
|
||||
if (!keyValues.empty()) {
|
||||
destHeader->bytesOfKeyValueData = writeKeyValues(currentDestPtr, destByteSize - sizeof(Header), keyValues);
|
||||
} else {
|
||||
// Make sure the header contains the right bytesOfKeyValueData size
|
||||
destHeader->bytesOfKeyValueData = 0;
|
||||
}
|
||||
destHeader->bytesOfKeyValueData = 0;
|
||||
currentDestPtr += destHeader->bytesOfKeyValueData;
|
||||
|
||||
// Images
|
||||
|
@ -82,6 +84,11 @@ namespace ktx {
|
|||
return destByteSize;
|
||||
}
|
||||
|
||||
static size_t writeKeyValues(Byte* destBytes, size_t destByteSize, const KeyValues& keyValues) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
Images KTX::writeImages(Byte* destBytes, size_t destByteSize, const Images& srcImages) {
|
||||
Images destImages;
|
||||
auto imagesDataPtr = destBytes;
|
||||
|
|
Loading…
Reference in a new issue