Add PPI header recognition tests
This commit is contained in:
73
src/assets/ppi_header.cpp
Normal file
73
src/assets/ppi_header.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "assets/ppi_header.h"
|
||||
|
||||
#include "foundation/binary_stream.h"
|
||||
|
||||
namespace pp::assets {
|
||||
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] pp::foundation::Result<std::uint32_t> read_u32(pp::foundation::ByteReader& reader) noexcept
|
||||
{
|
||||
return reader.read_u32_le();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pp::foundation::Result<PpiHeaderInfo> parse_ppi_header(std::span<const std::byte> bytes) noexcept
|
||||
{
|
||||
if (bytes.size() < ppi_header_size) {
|
||||
return pp::foundation::Result<PpiHeaderInfo>::failure(
|
||||
pp::foundation::Status::out_of_range("PPI header is truncated"));
|
||||
}
|
||||
|
||||
pp::foundation::ByteReader reader(bytes.subspan(0, ppi_header_size));
|
||||
const auto magic = reader.read_bytes(4);
|
||||
if (!magic || magic.value()[0] != std::byte { 'P' } || magic.value()[1] != std::byte { 'P' }
|
||||
|| magic.value()[2] != std::byte { 'I' } || magic.value()[3] != std::byte { 0 }) {
|
||||
return pp::foundation::Result<PpiHeaderInfo>::failure(
|
||||
pp::foundation::Status::invalid_argument("PPI header magic is invalid"));
|
||||
}
|
||||
|
||||
PpiHeaderInfo info;
|
||||
const auto doc_major = read_u32(reader);
|
||||
const auto doc_minor = read_u32(reader);
|
||||
const auto soft_major = read_u32(reader);
|
||||
const auto soft_minor = read_u32(reader);
|
||||
const auto soft_fix = read_u32(reader);
|
||||
const auto soft_build = read_u32(reader);
|
||||
const auto thumb_width = read_u32(reader);
|
||||
const auto thumb_height = read_u32(reader);
|
||||
const auto thumb_components = read_u32(reader);
|
||||
if (!doc_major || !doc_minor || !soft_major || !soft_minor || !soft_fix || !soft_build
|
||||
|| !thumb_width || !thumb_height || !thumb_components) {
|
||||
return pp::foundation::Result<PpiHeaderInfo>::failure(
|
||||
pp::foundation::Status::out_of_range("PPI header is truncated"));
|
||||
}
|
||||
|
||||
info.document_version = { doc_major.value(), doc_minor.value() };
|
||||
info.software_version = {
|
||||
soft_major.value(),
|
||||
soft_minor.value(),
|
||||
soft_fix.value(),
|
||||
soft_build.value(),
|
||||
};
|
||||
info.thumbnail = {
|
||||
thumb_width.value(),
|
||||
thumb_height.value(),
|
||||
thumb_components.value(),
|
||||
};
|
||||
|
||||
if (info.document_version.major != 0 || info.document_version.minor < 1) {
|
||||
return pp::foundation::Result<PpiHeaderInfo>::failure(
|
||||
pp::foundation::Status::invalid_argument("PPI document version is unsupported"));
|
||||
}
|
||||
|
||||
if (info.thumbnail.width != 128 || info.thumbnail.height != 128 || info.thumbnail.components != 4) {
|
||||
return pp::foundation::Result<PpiHeaderInfo>::failure(
|
||||
pp::foundation::Status::invalid_argument("PPI thumbnail descriptor is invalid"));
|
||||
}
|
||||
|
||||
return pp::foundation::Result<PpiHeaderInfo>::success(info);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user