167 lines
4.4 KiB
C++
167 lines
4.4 KiB
C++
#pragma once
|
|
|
|
#include "assets/image_pixels.h"
|
|
#include "foundation/result.h"
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <span>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace pp::assets {
|
|
|
|
constexpr std::size_t ppi_header_size = 40;
|
|
constexpr std::uint32_t max_ppi_canvas_dimension = 131072;
|
|
constexpr std::uint32_t max_ppi_layer_count = 1024;
|
|
constexpr std::uint32_t max_ppi_frame_count = 100000;
|
|
constexpr std::size_t max_ppi_layer_name_length = 128;
|
|
constexpr std::uint64_t max_ppi_face_payload_bytes = 1024ULL * 1024ULL * 1024ULL;
|
|
|
|
struct PpiVersion {
|
|
std::uint32_t major = 0;
|
|
std::uint32_t minor = 0;
|
|
};
|
|
|
|
struct PpiSoftwareVersion {
|
|
std::uint32_t major = 0;
|
|
std::uint32_t minor = 0;
|
|
std::uint32_t fix = 0;
|
|
std::uint32_t build = 0;
|
|
};
|
|
|
|
struct PpiThumbnailInfo {
|
|
std::uint32_t width = 0;
|
|
std::uint32_t height = 0;
|
|
std::uint32_t components = 0;
|
|
};
|
|
|
|
struct PpiHeaderInfo {
|
|
PpiVersion document_version;
|
|
PpiSoftwareVersion software_version;
|
|
PpiThumbnailInfo thumbnail;
|
|
};
|
|
|
|
struct PpiProjectLayout {
|
|
PpiHeaderInfo header;
|
|
std::size_t thumbnail_offset = 0;
|
|
std::size_t thumbnail_bytes = 0;
|
|
std::size_t body_offset = 0;
|
|
std::size_t body_bytes = 0;
|
|
};
|
|
|
|
struct PpiBodySummary {
|
|
std::uint32_t width = 0;
|
|
std::uint32_t height = 0;
|
|
std::uint32_t layer_count = 0;
|
|
std::uint32_t declared_frame_count = 0;
|
|
std::uint32_t total_layer_frames = 0;
|
|
std::uint32_t dirty_face_count = 0;
|
|
std::uint32_t rgba_face_payload_count = 0;
|
|
std::uint64_t compressed_face_bytes = 0;
|
|
std::uint32_t info_bytes = 0;
|
|
};
|
|
|
|
struct PpiProjectSummary {
|
|
PpiProjectLayout layout;
|
|
PpiBodySummary body;
|
|
};
|
|
|
|
struct PpiFacePayloadSummary {
|
|
bool has_data = false;
|
|
std::uint32_t x0 = 0;
|
|
std::uint32_t y0 = 0;
|
|
std::uint32_t x1 = 0;
|
|
std::uint32_t y1 = 0;
|
|
std::uint32_t body_payload_offset = 0;
|
|
std::uint32_t payload_bytes = 0;
|
|
std::uint32_t png_width = 0;
|
|
std::uint32_t png_height = 0;
|
|
};
|
|
|
|
struct PpiFrameSummary {
|
|
std::uint32_t duration_ms = 100;
|
|
std::array<PpiFacePayloadSummary, 6> faces;
|
|
};
|
|
|
|
struct PpiLayerSummary {
|
|
std::uint32_t stored_order = 0;
|
|
std::string name;
|
|
float opacity = 1.0F;
|
|
std::uint32_t blend_mode = 0;
|
|
bool alpha_locked = false;
|
|
bool visible = true;
|
|
std::vector<PpiFrameSummary> frames;
|
|
};
|
|
|
|
struct PpiBodyIndex {
|
|
PpiBodySummary summary;
|
|
std::vector<PpiLayerSummary> layers;
|
|
};
|
|
|
|
struct PpiProjectIndex {
|
|
PpiProjectLayout layout;
|
|
PpiBodyIndex body;
|
|
};
|
|
|
|
struct PpiDecodedFacePayload {
|
|
std::uint32_t layer_index = 0;
|
|
std::uint32_t frame_index = 0;
|
|
std::uint32_t face_index = 0;
|
|
PpiFacePayloadSummary descriptor;
|
|
Rgba8Image image;
|
|
};
|
|
|
|
struct PpiDecodedProjectImages {
|
|
PpiProjectIndex project;
|
|
std::vector<PpiDecodedFacePayload> faces;
|
|
};
|
|
|
|
struct PpiDirtyFacePayloadConfig {
|
|
std::uint32_t face_index = 0;
|
|
std::uint32_t x = 0;
|
|
std::uint32_t y = 0;
|
|
std::uint32_t width = 0;
|
|
std::uint32_t height = 0;
|
|
std::span<const std::byte> png_rgba8;
|
|
};
|
|
|
|
struct PpiMinimalProjectConfig {
|
|
std::uint32_t width = 0;
|
|
std::uint32_t height = 0;
|
|
std::string layer_name;
|
|
std::uint32_t frame_duration_ms = 100;
|
|
std::span<const PpiDirtyFacePayloadConfig> dirty_faces;
|
|
};
|
|
|
|
[[nodiscard]] pp::foundation::Result<PpiHeaderInfo> parse_ppi_header(
|
|
std::span<const std::byte> bytes) noexcept;
|
|
|
|
[[nodiscard]] pp::foundation::Result<std::size_t> ppi_thumbnail_byte_size(PpiThumbnailInfo thumbnail) noexcept;
|
|
|
|
[[nodiscard]] pp::foundation::Result<PpiProjectLayout> parse_ppi_project_layout(
|
|
std::span<const std::byte> bytes) noexcept;
|
|
|
|
[[nodiscard]] pp::foundation::Result<PpiBodySummary> parse_ppi_body_summary(
|
|
PpiHeaderInfo header,
|
|
std::span<const std::byte> body) noexcept;
|
|
|
|
[[nodiscard]] pp::foundation::Result<PpiBodyIndex> parse_ppi_body_index(
|
|
PpiHeaderInfo header,
|
|
std::span<const std::byte> body);
|
|
|
|
[[nodiscard]] pp::foundation::Result<PpiProjectSummary> parse_ppi_project_summary(
|
|
std::span<const std::byte> bytes) noexcept;
|
|
|
|
[[nodiscard]] pp::foundation::Result<PpiProjectIndex> parse_ppi_project_index(
|
|
std::span<const std::byte> bytes);
|
|
|
|
[[nodiscard]] pp::foundation::Result<PpiDecodedProjectImages> decode_ppi_project_images(
|
|
std::span<const std::byte> bytes);
|
|
|
|
[[nodiscard]] pp::foundation::Result<std::vector<std::byte>> create_minimal_ppi_project(
|
|
PpiMinimalProjectConfig config);
|
|
|
|
}
|