Validate PPI face payload metadata

This commit is contained in:
2026-06-01 12:48:55 +02:00
parent f1ee1b28a1
commit 677d0b33a8
8 changed files with 161 additions and 16 deletions

View File

@@ -1,5 +1,6 @@
#include "assets/ppi_header.h"
#include "assets/image_metadata.h"
#include "foundation/binary_stream.h"
#include <bit>
@@ -77,6 +78,28 @@ namespace {
return pp::foundation::Status::success();
}
[[nodiscard]] pp::foundation::Status validate_face_png_payload(
std::span<const std::byte> payload,
std::uint32_t width,
std::uint32_t height) noexcept
{
const auto metadata = parse_png_metadata(payload);
if (!metadata) {
return metadata.status();
}
if (metadata.value().width != width || metadata.value().height != height) {
return pp::foundation::Status::invalid_argument("PPI face PNG dimensions do not match the dirty box");
}
if (metadata.value().bit_depth != 8U || metadata.value().components != 4U
|| metadata.value().color_type != ImageColorType::rgba) {
return pp::foundation::Status::invalid_argument("PPI face PNG payload must be 8-bit RGBA");
}
return pp::foundation::Status::success();
}
}
pp::foundation::Result<PpiHeaderInfo> parse_ppi_header(std::span<const std::byte> bytes) noexcept
@@ -356,15 +379,25 @@ pp::foundation::Result<PpiBodySummary> parse_ppi_body_summary(
pp::foundation::Status::invalid_argument("PPI compressed face payload must not be empty"));
}
const auto payload_status = add_payload_bytes(summary, data_size.value());
if (!payload_status.ok()) {
return pp::foundation::Result<PpiBodySummary>::failure(payload_status);
const auto byte_status = add_payload_bytes(summary, data_size.value());
if (!byte_status.ok()) {
return pp::foundation::Result<PpiBodySummary>::failure(byte_status);
}
const auto skip_status = skip_bytes(reader, data_size.value());
if (!skip_status.ok()) {
return pp::foundation::Result<PpiBodySummary>::failure(skip_status);
const auto payload = reader.read_bytes(data_size.value());
if (!payload) {
return pp::foundation::Result<PpiBodySummary>::failure(payload.status());
}
const auto png_status = validate_face_png_payload(
payload.value(),
x1.value() - x0.value(),
y1.value() - y0.value());
if (!png_status.ok()) {
return pp::foundation::Result<PpiBodySummary>::failure(png_status);
}
++summary.rgba_face_payload_count;
}
}
}