Add PPI dirty-face payload save automation
This commit is contained in:
@@ -659,6 +659,54 @@ pp::foundation::Result<std::vector<std::byte>> create_minimal_ppi_project(PpiMin
|
||||
pp::foundation::Status::invalid_argument("PPI frame duration must be greater than zero"));
|
||||
}
|
||||
|
||||
bool seen_faces[6] {};
|
||||
std::uint64_t total_payload_bytes = 0;
|
||||
for (const auto& face : config.dirty_faces) {
|
||||
if (face.face_index >= 6U) {
|
||||
return pp::foundation::Result<std::vector<std::byte>>::failure(
|
||||
pp::foundation::Status::out_of_range("PPI dirty face index is outside the cube face list"));
|
||||
}
|
||||
|
||||
if (seen_faces[face.face_index]) {
|
||||
return pp::foundation::Result<std::vector<std::byte>>::failure(
|
||||
pp::foundation::Status::invalid_argument("PPI dirty face index is duplicated"));
|
||||
}
|
||||
seen_faces[face.face_index] = true;
|
||||
|
||||
if (face.width == 0 || face.height == 0) {
|
||||
return pp::foundation::Result<std::vector<std::byte>>::failure(
|
||||
pp::foundation::Status::invalid_argument("PPI dirty face dimensions must be greater than zero"));
|
||||
}
|
||||
|
||||
if (face.x > config.width || face.width > config.width - face.x
|
||||
|| face.y > config.height || face.height > config.height - face.y) {
|
||||
return pp::foundation::Result<std::vector<std::byte>>::failure(
|
||||
pp::foundation::Status::out_of_range("PPI dirty face box is outside the canvas"));
|
||||
}
|
||||
|
||||
if (face.png_rgba8.empty()) {
|
||||
return pp::foundation::Result<std::vector<std::byte>>::failure(
|
||||
pp::foundation::Status::invalid_argument("PPI dirty face PNG payload must not be empty"));
|
||||
}
|
||||
|
||||
if (face.png_rgba8.size() > static_cast<std::size_t>(std::numeric_limits<std::uint32_t>::max())) {
|
||||
return pp::foundation::Result<std::vector<std::byte>>::failure(
|
||||
pp::foundation::Status::out_of_range("PPI dirty face PNG payload is too large"));
|
||||
}
|
||||
|
||||
const auto next_payload_bytes = total_payload_bytes + face.png_rgba8.size();
|
||||
if (next_payload_bytes > max_ppi_face_payload_bytes) {
|
||||
return pp::foundation::Result<std::vector<std::byte>>::failure(
|
||||
pp::foundation::Status::out_of_range("PPI dirty face PNG payloads exceed the configured limit"));
|
||||
}
|
||||
total_payload_bytes = next_payload_bytes;
|
||||
|
||||
const auto metadata = validate_face_png_payload(face.png_rgba8, face.width, face.height);
|
||||
if (!metadata) {
|
||||
return pp::foundation::Result<std::vector<std::byte>>::failure(metadata.status());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::byte> bytes {
|
||||
std::byte { 'P' },
|
||||
std::byte { 'P' },
|
||||
@@ -692,7 +740,26 @@ pp::foundation::Result<std::vector<std::byte>> create_minimal_ppi_project(PpiMin
|
||||
append_u32(bytes, 1);
|
||||
append_u32(bytes, config.frame_duration_ms);
|
||||
for (std::uint32_t face = 0; face < 6U; ++face) {
|
||||
append_u32(bytes, 0);
|
||||
const PpiDirtyFacePayloadConfig* dirty_face = nullptr;
|
||||
for (const auto& candidate : config.dirty_faces) {
|
||||
if (candidate.face_index == face) {
|
||||
dirty_face = &candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty_face == nullptr) {
|
||||
append_u32(bytes, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
append_u32(bytes, 1);
|
||||
append_u32(bytes, dirty_face->x);
|
||||
append_u32(bytes, dirty_face->y);
|
||||
append_u32(bytes, dirty_face->x + dirty_face->width);
|
||||
append_u32(bytes, dirty_face->y + dirty_face->height);
|
||||
append_u32(bytes, static_cast<std::uint32_t>(dirty_face->png_rgba8.size()));
|
||||
bytes.insert(bytes.end(), dirty_face->png_rgba8.begin(), dirty_face->png_rgba8.end());
|
||||
}
|
||||
append_u32(bytes, 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user