CLeaning the read case

This commit is contained in:
sam 2017-02-16 17:28:02 -08:00
parent 8ee5defc60
commit 2ee3f05713
5 changed files with 57 additions and 65 deletions

View file

@ -12,6 +12,10 @@ using namespace gpu;
const Element Element::COLOR_RGBA_32{ VEC4, NUINT8, RGBA };
const Element Element::COLOR_SRGBA_32{ VEC4, NUINT8, SRGBA };
const Element Element::COLOR_BGRA_32{ VEC4, NUINT8, BGRA };
const Element Element::COLOR_SBGRA_32{ VEC4, NUINT8, SBGRA };
const Element Element::COLOR_R11G11B10{ SCALAR, FLOAT, R11G11B10 };
const Element Element::VEC4F_COLOR_RGBA{ VEC4, FLOAT, RGBA };
const Element Element::VEC2F_UV{ VEC2, FLOAT, UV };

View file

@ -229,6 +229,8 @@ public:
static const Element COLOR_RGBA_32;
static const Element COLOR_SRGBA_32;
static const Element COLOR_BGRA_32;
static const Element COLOR_SBGRA_32;
static const Element COLOR_R11G11B10;
static const Element VEC4F_COLOR_RGBA;
static const Element VEC2F_UV;

View file

@ -24,7 +24,7 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
header.numberOfMipmapLevels = texture.mipLevels();
ktx::Images images;
for (int level = 0; level < header.numberOfMipmapLevels; level++) {
for (uint32_t level = 0; level < header.numberOfMipmapLevels; level++) {
auto mip = texture.accessStoredMipFace(level);
if (mip) {
images.emplace_back(ktx::Image(mip->getSize(), 0, mip->readData()));
@ -41,12 +41,13 @@ Texture* Texture::unserialize(const ktx::KTXUniquePointer& srcData) {
const auto& header = *srcData->getHeader();
Format pixelFormat = Format::COLOR_RGBA_32;
Format mipFormat = Format::COLOR_SBGRA_32;
Format pixelFormat = Format::COLOR_SRGBA_32;
auto tex = Texture::create2D(pixelFormat, header.getPixelWidth(), header.getPixelHeight());
uint16_t level = 0;
for (auto& image : srcData->_images) {
tex->assignStoredMip(level, pixelFormat, image._imageSize, image._bytes);
tex->assignStoredMip(level, mipFormat, image._imageSize, image._bytes);
level++;
}

View file

@ -445,10 +445,10 @@ namespace ktx {
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 Storage& src);
static std::unique_ptr<KTX> create(std::unique_ptr<Storage>& src);
static bool checkHeaderFromStorage(const Storage& storage);
static bool checkHeaderFromStorage(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
const Header* getHeader() const;

View file

@ -38,12 +38,17 @@ namespace ktx {
}
break;
default:
throw ReaderException("endianness field has invalid value");
return false;
}
}
bool checkIdentifier(const Byte* identifier) {
return memcmp(identifier, Header::IDENTIFIER.data(), Header::IDENTIFIER_LENGTH);
if (!(0 == memcmp(identifier, Header::IDENTIFIER.data(), Header::IDENTIFIER_LENGTH))) {
throw ReaderException("identifier field invalid");
return false;
}
return true;
}
KeyValues getKeyValues(size_t length, const Byte* src) {
@ -81,53 +86,18 @@ namespace ktx {
return keyValues;
}
Images getImagesTable(const Header& header, size_t mipsDataSize, const Byte* mipsData) {
Images images;
auto currentPtr = mipsData;
auto numMips = header.getNumberOfLevels();
// 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
size_t 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 = Header::evalPadding(imageSize);
images.emplace_back(Image(imageSize, padding, currentPtr));
currentPtr += imageSize + padding;
} else {
break;
}
}
return images;
}
bool KTX::checkHeaderFromStorage(const Storage& src) {
bool KTX::checkHeaderFromStorage(size_t srcSize, const Byte* srcBytes) {
try {
auto srcSize = src.size();
auto srcBytes = src.data();
// validation
if (srcSize < sizeof(Header)) {
throw ReaderException("length is too short for header");
}
const Header* header = reinterpret_cast<const Header*>(srcBytes);
if (!checkIdentifier(header->identifier)) {
throw ReaderException("identifier field invalid");
}
checkIdentifier(header->identifier);
bool endianMatch { true };
if (!checkEndianness(header->endianness, endianMatch)) {
throw ReaderException("endianness field has invalid value");
}
checkEndianness(header->endianness, endianMatch);
// TODO: endian conversion if !endianMatch - for now, this is for local use and is unnecessary
@ -151,10 +121,31 @@ namespace ktx {
}
}
std::unique_ptr<KTX> KTX::create(const Storage& src) {
auto srcCopy = std::make_unique<Storage>(src);
Images KTX::parseImages(const Header& header, size_t srcSize, const Byte* srcBytes) {
Images images;
auto currentPtr = srcBytes;
auto numMips = header.getNumberOfLevels();
return create(srcCopy);
// Keep identifying new mip as long as we can at list query the next imageSize
while ((currentPtr - srcBytes) + sizeof(uint32_t) <= (srcSize)) {
// Grab the imageSize coming up
size_t imageSize = *reinterpret_cast<const uint32_t*>(currentPtr);
currentPtr += sizeof(uint32_t);
// If enough data ahead then capture the pointer
if ((currentPtr - srcBytes) + imageSize <= (srcSize)) {
auto padding = Header::evalPadding(imageSize);
images.emplace_back(Image(imageSize, padding, currentPtr));
currentPtr += imageSize + padding;
} else {
break;
}
}
return images;
}
std::unique_ptr<KTX> KTX::create(std::unique_ptr<Storage>& src) {
@ -162,25 +153,19 @@ namespace ktx {
return nullptr;
}
try {
if (!checkHeaderFromStorage(*src)) {
}
std::unique_ptr<KTX> result(new KTX());
result->resetStorage(src.release());
// read metadata
result->_keyValues = getKeyValues(result->getHeader()->bytesOfKeyValueData, result->getKeyValueData());
// populate image table
result->_images = getImagesTable(*result->getHeader(), result->getTexelsDataSize(), result->getTexelsData());
return result;
}
catch (ReaderException& e) {
qWarning(e.what());
if (!checkHeaderFromStorage(src->size(), src->data())) {
return nullptr;
}
std::unique_ptr<KTX> result(new KTX());
result->resetStorage(src.release());
// read metadata
// result->_keyValues = getKeyValues(result->getHeader()->bytesOfKeyValueData, result->getKeyValueData());
// populate image table
result->_images = parseImages(*result->getHeader(), result->getTexelsDataSize(), result->getTexelsData());
return result;
}
}