Decode PPI face payloads

This commit is contained in:
2026-06-01 13:35:03 +02:00
parent 10e5d5b5ae
commit 88507df90e
13 changed files with 349 additions and 15 deletions

View File

@@ -561,4 +561,59 @@ pp::foundation::Result<PpiProjectIndex> parse_ppi_project_index(std::span<const
});
}
pp::foundation::Result<PpiDecodedProjectImages> decode_ppi_project_images(std::span<const std::byte> bytes)
{
auto project = parse_ppi_project_index(bytes);
if (!project) {
return pp::foundation::Result<PpiDecodedProjectImages>::failure(project.status());
}
PpiDecodedProjectImages decoded {
.project = project.value(),
.faces = {},
};
decoded.faces.reserve(decoded.project.body.summary.rgba_face_payload_count);
const auto body = bytes.subspan(decoded.project.layout.body_offset, decoded.project.layout.body_bytes);
for (std::size_t layer_index = 0; layer_index < decoded.project.body.layers.size(); ++layer_index) {
const auto& layer = decoded.project.body.layers[layer_index];
for (std::size_t frame_index = 0; frame_index < layer.frames.size(); ++frame_index) {
const auto& frame = layer.frames[frame_index];
for (std::size_t face_index = 0; face_index < frame.faces.size(); ++face_index) {
const auto& face = frame.faces[face_index];
if (!face.has_data) {
continue;
}
if (face.body_payload_offset > body.size()
|| face.payload_bytes > body.size() - face.body_payload_offset) {
return pp::foundation::Result<PpiDecodedProjectImages>::failure(
pp::foundation::Status::out_of_range("PPI face payload range is outside the body"));
}
const auto image = decode_png_rgba8(
body.subspan(face.body_payload_offset, face.payload_bytes));
if (!image) {
return pp::foundation::Result<PpiDecodedProjectImages>::failure(image.status());
}
if (image.value().width != face.png_width || image.value().height != face.png_height) {
return pp::foundation::Result<PpiDecodedProjectImages>::failure(
pp::foundation::Status::invalid_argument("decoded PPI face payload dimensions changed"));
}
decoded.faces.push_back(PpiDecodedFacePayload {
.layer_index = static_cast<std::uint32_t>(layer_index),
.frame_index = static_cast<std::uint32_t>(frame_index),
.face_index = static_cast<std::uint32_t>(face_index),
.descriptor = face,
.image = image.value(),
});
}
}
}
return pp::foundation::Result<PpiDecodedProjectImages>::success(std::move(decoded));
}
}