CLeaning the read case

This commit is contained in:
sam 2017-02-16 17:28:02 -08:00 committed by Brad Davis
parent 6771cc31e1
commit 0d2e764bfd
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_RGBA_32{ VEC4, NUINT8, RGBA };
const Element Element::COLOR_SRGBA_32{ VEC4, NUINT8, SRGBA }; 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::COLOR_R11G11B10{ SCALAR, FLOAT, R11G11B10 };
const Element Element::VEC4F_COLOR_RGBA{ VEC4, FLOAT, RGBA }; const Element Element::VEC4F_COLOR_RGBA{ VEC4, FLOAT, RGBA };
const Element Element::VEC2F_UV{ VEC2, FLOAT, UV }; 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_RGBA_32;
static const Element COLOR_SRGBA_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 COLOR_R11G11B10;
static const Element VEC4F_COLOR_RGBA; static const Element VEC4F_COLOR_RGBA;
static const Element VEC2F_UV; static const Element VEC2F_UV;

View file

@ -24,7 +24,7 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
header.numberOfMipmapLevels = texture.mipLevels(); header.numberOfMipmapLevels = texture.mipLevels();
ktx::Images images; 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); auto mip = texture.accessStoredMipFace(level);
if (mip) { if (mip) {
images.emplace_back(ktx::Image(mip->getSize(), 0, mip->readData())); 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(); 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()); auto tex = Texture::create2D(pixelFormat, header.getPixelWidth(), header.getPixelHeight());
uint16_t level = 0; uint16_t level = 0;
for (auto& image : srcData->_images) { for (auto& image : srcData->_images) {
tex->assignStoredMip(level, pixelFormat, image._imageSize, image._bytes); tex->assignStoredMip(level, mipFormat, image._imageSize, image._bytes);
level++; level++;
} }

View file

@ -445,10 +445,10 @@ namespace ktx {
static Images writeImages(Byte* destBytes, size_t destByteSize, const Images& images); static Images writeImages(Byte* destBytes, size_t destByteSize, const Images& images);
// Parse a block of memory and create a KTX object from it // 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 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 // Access raw pointers to the main sections of the KTX
const Header* getHeader() const; const Header* getHeader() const;

View file

@ -38,12 +38,17 @@ namespace ktx {
} }
break; break;
default: default:
throw ReaderException("endianness field has invalid value");
return false; return false;
} }
} }
bool checkIdentifier(const Byte* identifier) { 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) { KeyValues getKeyValues(size_t length, const Byte* src) {
@ -81,53 +86,18 @@ namespace ktx {
return keyValues; return keyValues;
} }
Images getImagesTable(const Header& header, size_t mipsDataSize, const Byte* mipsData) { bool KTX::checkHeaderFromStorage(size_t srcSize, const Byte* srcBytes) {
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) {
try { try {
auto srcSize = src.size();
auto srcBytes = src.data();
// validation // validation
if (srcSize < sizeof(Header)) { if (srcSize < sizeof(Header)) {
throw ReaderException("length is too short for header"); throw ReaderException("length is too short for header");
} }
const Header* header = reinterpret_cast<const Header*>(srcBytes); const Header* header = reinterpret_cast<const Header*>(srcBytes);
if (!checkIdentifier(header->identifier)) { checkIdentifier(header->identifier);
throw ReaderException("identifier field invalid");
}
bool endianMatch { true }; bool endianMatch { true };
if (!checkEndianness(header->endianness, endianMatch)) { checkEndianness(header->endianness, endianMatch);
throw ReaderException("endianness field has invalid value");
}
// TODO: endian conversion if !endianMatch - for now, this is for local use and is unnecessary // 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) { Images KTX::parseImages(const Header& header, size_t srcSize, const Byte* srcBytes) {
auto srcCopy = std::make_unique<Storage>(src); 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) { std::unique_ptr<KTX> KTX::create(std::unique_ptr<Storage>& src) {
@ -162,25 +153,19 @@ namespace ktx {
return nullptr; return nullptr;
} }
try { if (!checkHeaderFromStorage(src->size(), src->data())) {
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());
return nullptr; 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;
} }
} }