#pragma once #include "assets/image_pixels.h" #include "foundation/result.h" #include #include #include #include #include #include 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 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 frames; }; struct PpiBodyIndex { PpiBodySummary summary; std::vector 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 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 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 dirty_faces; }; [[nodiscard]] pp::foundation::Result parse_ppi_header( std::span bytes) noexcept; [[nodiscard]] pp::foundation::Result ppi_thumbnail_byte_size(PpiThumbnailInfo thumbnail) noexcept; [[nodiscard]] pp::foundation::Result parse_ppi_project_layout( std::span bytes) noexcept; [[nodiscard]] pp::foundation::Result parse_ppi_body_summary( PpiHeaderInfo header, std::span body) noexcept; [[nodiscard]] pp::foundation::Result parse_ppi_body_index( PpiHeaderInfo header, std::span body); [[nodiscard]] pp::foundation::Result parse_ppi_project_summary( std::span bytes) noexcept; [[nodiscard]] pp::foundation::Result parse_ppi_project_index( std::span bytes); [[nodiscard]] pp::foundation::Result decode_ppi_project_images( std::span bytes); [[nodiscard]] pp::foundation::Result> create_minimal_ppi_project( PpiMinimalProjectConfig config); }