Index PPI project layers
This commit is contained in:
@@ -57,6 +57,48 @@ void print_error(std::string_view command, std::string_view message)
|
||||
<< "\",\"error\":\"" << message << "\"}\n";
|
||||
}
|
||||
|
||||
std::string json_escape(std::string_view value)
|
||||
{
|
||||
constexpr char hex[] = "0123456789abcdef";
|
||||
std::string escaped;
|
||||
escaped.reserve(value.size());
|
||||
for (const unsigned char ch : value) {
|
||||
switch (ch) {
|
||||
case '"':
|
||||
escaped += "\\\"";
|
||||
break;
|
||||
case '\\':
|
||||
escaped += "\\\\";
|
||||
break;
|
||||
case '\b':
|
||||
escaped += "\\b";
|
||||
break;
|
||||
case '\f':
|
||||
escaped += "\\f";
|
||||
break;
|
||||
case '\n':
|
||||
escaped += "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
escaped += "\\r";
|
||||
break;
|
||||
case '\t':
|
||||
escaped += "\\t";
|
||||
break;
|
||||
default:
|
||||
if (ch < 0x20U) {
|
||||
escaped += "\\u00";
|
||||
escaped.push_back(hex[(ch >> 4U) & 0x0fU]);
|
||||
escaped.push_back(hex[ch & 0x0fU]);
|
||||
} else {
|
||||
escaped.push_back(static_cast<char>(ch));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
void print_help()
|
||||
{
|
||||
std::cout
|
||||
@@ -287,34 +329,78 @@ int inspect_project(int argc, char** argv)
|
||||
std::istreambuf_iterator<char>()
|
||||
};
|
||||
const auto* data = reinterpret_cast<const std::byte*>(chars.data());
|
||||
const auto summary = pp::assets::parse_ppi_project_summary(std::span<const std::byte>(data, chars.size()));
|
||||
if (!summary) {
|
||||
print_error("inspect-project", summary.status().message);
|
||||
const auto project = pp::assets::parse_ppi_project_index(std::span<const std::byte>(data, chars.size()));
|
||||
if (!project) {
|
||||
print_error("inspect-project", project.status().message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
std::cout << "{\"ok\":true,\"command\":\"inspect-project\""
|
||||
<< ",\"documentVersion\":\"" << summary.value().layout.header.document_version.major
|
||||
<< "." << summary.value().layout.header.document_version.minor << "\""
|
||||
<< ",\"softwareVersion\":\"" << summary.value().layout.header.software_version.major
|
||||
<< "." << summary.value().layout.header.software_version.minor
|
||||
<< "." << summary.value().layout.header.software_version.fix
|
||||
<< "." << summary.value().layout.header.software_version.build << "\""
|
||||
<< ",\"thumbnail\":{\"width\":" << summary.value().layout.header.thumbnail.width
|
||||
<< ",\"height\":" << summary.value().layout.header.thumbnail.height
|
||||
<< ",\"components\":" << summary.value().layout.header.thumbnail.components
|
||||
<< ",\"bytes\":" << summary.value().layout.thumbnail_bytes
|
||||
<< "},\"body\":{\"offset\":" << summary.value().layout.body_offset
|
||||
<< ",\"bytes\":" << summary.value().layout.body_bytes
|
||||
<< ",\"width\":" << summary.value().body.width
|
||||
<< ",\"height\":" << summary.value().body.height
|
||||
<< ",\"layers\":" << summary.value().body.layer_count
|
||||
<< ",\"frames\":" << summary.value().body.declared_frame_count
|
||||
<< ",\"dirtyFaces\":" << summary.value().body.dirty_face_count
|
||||
<< ",\"rgbaFacePayloads\":" << summary.value().body.rgba_face_payload_count
|
||||
<< ",\"compressedBytes\":" << summary.value().body.compressed_face_bytes
|
||||
<< ",\"infoBytes\":" << summary.value().body.info_bytes
|
||||
<< "}}\n";
|
||||
<< ",\"documentVersion\":\"" << project.value().layout.header.document_version.major
|
||||
<< "." << project.value().layout.header.document_version.minor << "\""
|
||||
<< ",\"softwareVersion\":\"" << project.value().layout.header.software_version.major
|
||||
<< "." << project.value().layout.header.software_version.minor
|
||||
<< "." << project.value().layout.header.software_version.fix
|
||||
<< "." << project.value().layout.header.software_version.build << "\""
|
||||
<< ",\"thumbnail\":{\"width\":" << project.value().layout.header.thumbnail.width
|
||||
<< ",\"height\":" << project.value().layout.header.thumbnail.height
|
||||
<< ",\"components\":" << project.value().layout.header.thumbnail.components
|
||||
<< ",\"bytes\":" << project.value().layout.thumbnail_bytes
|
||||
<< "},\"body\":{\"offset\":" << project.value().layout.body_offset
|
||||
<< ",\"bytes\":" << project.value().layout.body_bytes
|
||||
<< ",\"width\":" << project.value().body.summary.width
|
||||
<< ",\"height\":" << project.value().body.summary.height
|
||||
<< ",\"layers\":" << project.value().body.summary.layer_count
|
||||
<< ",\"frames\":" << project.value().body.summary.declared_frame_count
|
||||
<< ",\"dirtyFaces\":" << project.value().body.summary.dirty_face_count
|
||||
<< ",\"rgbaFacePayloads\":" << project.value().body.summary.rgba_face_payload_count
|
||||
<< ",\"compressedBytes\":" << project.value().body.summary.compressed_face_bytes
|
||||
<< ",\"infoBytes\":" << project.value().body.summary.info_bytes
|
||||
<< "},\"layers\":[";
|
||||
for (std::size_t layer_index = 0; layer_index < project.value().body.layers.size(); ++layer_index) {
|
||||
const auto& layer = project.value().body.layers[layer_index];
|
||||
if (layer_index != 0U) {
|
||||
std::cout << ",";
|
||||
}
|
||||
std::cout << "{\"index\":" << layer_index
|
||||
<< ",\"storedOrder\":" << layer.stored_order
|
||||
<< ",\"name\":\"" << json_escape(layer.name) << "\""
|
||||
<< ",\"opacity\":" << layer.opacity
|
||||
<< ",\"blendMode\":" << layer.blend_mode
|
||||
<< ",\"alphaLocked\":" << (layer.alpha_locked ? "true" : "false")
|
||||
<< ",\"visible\":" << (layer.visible ? "true" : "false")
|
||||
<< ",\"frames\":[";
|
||||
for (std::size_t frame_index = 0; frame_index < layer.frames.size(); ++frame_index) {
|
||||
const auto& frame = layer.frames[frame_index];
|
||||
if (frame_index != 0U) {
|
||||
std::cout << ",";
|
||||
}
|
||||
std::cout << "{\"index\":" << frame_index
|
||||
<< ",\"durationMs\":" << frame.duration_ms
|
||||
<< ",\"dirtyFaces\":[";
|
||||
bool first_face = true;
|
||||
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 (!first_face) {
|
||||
std::cout << ",";
|
||||
}
|
||||
first_face = false;
|
||||
std::cout << "{\"face\":" << face_index
|
||||
<< ",\"box\":[" << face.x0 << "," << face.y0 << "," << face.x1 << "," << face.y1 << "]"
|
||||
<< ",\"bodyPayloadOffset\":" << face.body_payload_offset
|
||||
<< ",\"bytes\":" << face.payload_bytes
|
||||
<< ",\"png\":{\"width\":" << face.png_width
|
||||
<< ",\"height\":" << face.png_height
|
||||
<< "}}";
|
||||
}
|
||||
std::cout << "]}";
|
||||
}
|
||||
std::cout << "]}";
|
||||
}
|
||||
std::cout << "]}\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user