From 18f7bf5f572dee728181576a9d0b8db639803e5b Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Sat, 17 May 2025 22:30:43 +0200 Subject: [PATCH 1/5] patterns: Add json support for glb files This makes it possible to separate display the different buffer views, accessors and images (even visualizing them). Unfortunately the data within the JSON gets sometimes corrupted and this is the reason, why it parses the JSON multiple times at some places. --- patterns/gltf.hexpat | 201 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 196 insertions(+), 5 deletions(-) diff --git a/patterns/gltf.hexpat b/patterns/gltf.hexpat index 85d94b8f..aa27faeb 100644 --- a/patterns/gltf.hexpat +++ b/patterns/gltf.hexpat @@ -22,13 +22,16 @@ * SOFTWARE. */ -#pragma author H. Utku Maden +#pragma author H. Utku Maden, xZise #pragma description GL Transmission Format binary 3D model (.glb) #pragma MIME model/gltf-binary +#pragma magic [67 6C 54 46] @ 0x00 import std.mem; import std.io; import type.magic; +import hex.type.json; +import std.core; /** * @brief The glTF magic section. @@ -53,7 +56,10 @@ enum gltf_chunk_type_t : u32 { struct gltf_chunk_t { u32 length; /**< Length of this chunk. */ gltf_chunk_type_t type [[format("gltf_format")]]; /**< Type of the chunk. JSON or BIN expected. */ - u8 string[length]; /**< The chunk data. */ + match (type) { + (gltf_chunk_type_t::JSON): hex::type::Json json; + (gltf_chunk_type_t::BIN): u8 data[length]; + } /**< The chunk data. */ }; fn gltf_format(gltf_chunk_type_t x) @@ -64,7 +70,192 @@ fn gltf_format(gltf_chunk_type_t x) return ""; }; -gltf_magic_t magic @ 0x00; -gltf_chunk_t chunks[while(!std::mem::eof())] @ $; +u64 json_offset = 0; +u64 json_length = 0; -std::assert_warn(std::mem::size() == magic.length, "file size mismatch"); +struct StrideType { + InnerType value [[inline]]; + if (Stride > 0) { + padding[Stride - sizeof(value)]; + } +}; + +struct Scalar { + ComponentType scalar; +} [[static, sealed]]; + +struct Vec2 { + ComponentType x; + ComponentType y; +} [[static]]; + +struct Vec3 { + ComponentType x; + ComponentType y; + ComponentType z; +} [[static]]; + +struct Vec4 { + ComponentType x; + ComponentType y; + ComponentType z; + ComponentType w; +} [[static]]; + +struct Mat2 { + ComponentType a11; + ComponentType a21; + ComponentType a12; + ComponentType a22; +} [[static]]; + +struct Mat3 { + ComponentType a11; + ComponentType a21; + ComponentType a31; + ComponentType a12; + ComponentType a22; + ComponentType a32; + ComponentType a13; + ComponentType a23; + ComponentType a33; +} [[static]]; + +struct Mat4 { + ComponentType a11; + ComponentType a21; + ComponentType a31; + ComponentType a41; + ComponentType a12; + ComponentType a22; + ComponentType a32; + ComponentType a42; + ComponentType a13; + ComponentType a23; + ComponentType a33; + ComponentType a43; + ComponentType a14; + ComponentType a24; + ComponentType a34; + ComponentType a44; +} [[static]]; + +enum ComponentType : u64 { + BYTE = 5120, + UNSIGNED_BYTE = 5121, + SHORT = 5122, + UNSIGNED_SHORT = 5123, + UNSIGNED_INT = 5125, + FLOAT = 5126, +}; + +struct Accessor { + hex::type::Json Json @ json_offset; + hex::type::Json Json2 @ json_offset; + hex::type::Json Json3 @ json_offset; + u64 accessor_index = std::core::array_index(); + u64 view_index = Json.accessors[accessor_index].bufferView [[export]]; + u64 view_offset = Json.bufferViews[view_index].byteOffset [[export]]; + if (std::core::has_member(Json2.bufferViews[view_index], "byteStride")) { + u64 byte_stride = Json.bufferViews[view_index].byteStride [[export]]; + } else { + u64 byte_stride = 0 [[export]]; + } + if (std::core::has_member(Json3.accessors[accessor_index], "byteOffset")) { + u64 accessor_offset = Json.accessors[accessor_index].byteOffset [[export]]; + } else { + u64 accessor_offset = 0 [[export]]; + } + view_offset = view_offset + accessor_offset; + u64 count_elements = Json.accessors[accessor_index].count; + ComponentType component_type = Json.accessors[accessor_index].componentType [[export]]; + + match (Json.accessors[accessor_index].type, component_type) { + ("SCALAR", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + } +}; + +fn mem_cnt(auto value) { + return std::core::member_count(value); +}; + +struct ImageBuffer { + hex::type::Json Json @ json_offset; + u64 image_index = std::core::array_index(); + u64 buffer_view_index = Json.images[image_index].bufferView; + u64 byte_offset = Json.bufferViews[buffer_view_index].byteOffset; + u64 byte_length = Json.bufferViews[buffer_view_index].byteLength; + u8 image[byte_length] @ Offset + byte_offset; +} [[hex::visualize("image", image)]]; + +struct BufferView { + hex::type::Json Json @ json_offset; + u64 buffer_view_index = std::core::array_index(); + u64 byte_offset = Json.bufferViews[buffer_view_index].byteOffset; + u64 byte_length = Json.bufferViews[buffer_view_index].byteLength; + u8 data[byte_length] @ Offset + byte_offset; +}; + +struct Glb { + gltf_magic_t magic; + gltf_chunk_t json_chunk; + gltf_chunk_t chunks[while(!std::mem::eof())]; + + json_offset = addressof(json_chunk.json); + json_length = json_chunk.length; + + std::assert_warn(std::mem::size() == magic.length, "file size mismatch"); + + if (std::core::member_count(chunks) == 1) { + u128 bin_chunk = addressof(chunks[0].data); + hex::type::Json Json @ json_offset; + if (std::core::has_member(Json, "images")) { + ImageBuffer images[mem_cnt(json_chunk.json.images)]; + } + BufferView buffer_views[mem_cnt(json_chunk.json.bufferViews)]; + Accessor accessors[mem_cnt(json_chunk.json.accessors)]; + } +}; + +Glb glb @ 0x00; \ No newline at end of file From ae4e11644ece3e7a7139ef149e22f8eadfc7b831 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Sun, 22 Jun 2025 23:22:28 +0200 Subject: [PATCH 2/5] Use original style and only single json variable --- patterns/gltf.hexpat | 186 +++++++++++++++++------------------ patterns/png.hexpat | 11 ++- patterns/png2.hexpat | 224 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 319 insertions(+), 102 deletions(-) create mode 100644 patterns/png2.hexpat diff --git a/patterns/gltf.hexpat b/patterns/gltf.hexpat index aa27faeb..c421b695 100644 --- a/patterns/gltf.hexpat +++ b/patterns/gltf.hexpat @@ -56,10 +56,15 @@ enum gltf_chunk_type_t : u32 { struct gltf_chunk_t { u32 length; /**< Length of this chunk. */ gltf_chunk_type_t type [[format("gltf_format")]]; /**< Type of the chunk. JSON or BIN expected. */ +#ifndef __IMHEX__ + u8 data[length]; /**< The chunk data. */ +#endif +#ifdef __IMHEX__ match (type) { (gltf_chunk_type_t::JSON): hex::type::Json json; (gltf_chunk_type_t::BIN): u8 data[length]; } /**< The chunk data. */ +#endif }; fn gltf_format(gltf_chunk_type_t x) @@ -73,74 +78,54 @@ fn gltf_format(gltf_chunk_type_t x) u64 json_offset = 0; u64 json_length = 0; -struct StrideType { +struct stride_type_t { InnerType value [[inline]]; if (Stride > 0) { padding[Stride - sizeof(value)]; } }; -struct Scalar { +struct scalar_t { ComponentType scalar; } [[static, sealed]]; -struct Vec2 { +struct vec2_t { ComponentType x; ComponentType y; } [[static]]; -struct Vec3 { +struct vec3_t { ComponentType x; ComponentType y; ComponentType z; } [[static]]; -struct Vec4 { +struct vec4_t { ComponentType x; ComponentType y; ComponentType z; ComponentType w; } [[static]]; -struct Mat2 { - ComponentType a11; - ComponentType a21; - ComponentType a12; - ComponentType a22; +struct mat2_t { + ComponentType a11, a21; + ComponentType a12, a22; } [[static]]; -struct Mat3 { - ComponentType a11; - ComponentType a21; - ComponentType a31; - ComponentType a12; - ComponentType a22; - ComponentType a32; - ComponentType a13; - ComponentType a23; - ComponentType a33; +struct mat3_t { + ComponentType a11, a21, a31; + ComponentType a12, a22, a32; + ComponentType a13, a23, a33; } [[static]]; -struct Mat4 { - ComponentType a11; - ComponentType a21; - ComponentType a31; - ComponentType a41; - ComponentType a12; - ComponentType a22; - ComponentType a32; - ComponentType a42; - ComponentType a13; - ComponentType a23; - ComponentType a33; - ComponentType a43; - ComponentType a14; - ComponentType a24; - ComponentType a34; - ComponentType a44; +struct mat4_t { + ComponentType a11, a21, a31, a41; + ComponentType a12, a22, a32, a42; + ComponentType a13, a23, a33, a43; + ComponentType a14, a24, a34, a44; } [[static]]; -enum ComponentType : u64 { +enum component_types_t : u64 { BYTE = 5120, UNSIGNED_BYTE = 5121, SHORT = 5122, @@ -149,78 +134,80 @@ enum ComponentType : u64 { FLOAT = 5126, }; -struct Accessor { +fn mem_cnt(auto value) { + return std::core::member_count(value); +}; + +fn has_mem(auto value, str member) { + return std::core::has_member(value, member); +}; + +struct accessor_t { hex::type::Json Json @ json_offset; - hex::type::Json Json2 @ json_offset; - hex::type::Json Json3 @ json_offset; u64 accessor_index = std::core::array_index(); u64 view_index = Json.accessors[accessor_index].bufferView [[export]]; u64 view_offset = Json.bufferViews[view_index].byteOffset [[export]]; - if (std::core::has_member(Json2.bufferViews[view_index], "byteStride")) { + if (has_mem(Json.bufferViews[view_index], "byteStride")) { u64 byte_stride = Json.bufferViews[view_index].byteStride [[export]]; } else { u64 byte_stride = 0 [[export]]; } - if (std::core::has_member(Json3.accessors[accessor_index], "byteOffset")) { + if (has_mem(Json.accessors[accessor_index], "byteOffset")) { u64 accessor_offset = Json.accessors[accessor_index].byteOffset [[export]]; } else { u64 accessor_offset = 0 [[export]]; } view_offset = view_offset + accessor_offset; u64 count_elements = Json.accessors[accessor_index].count; - ComponentType component_type = Json.accessors[accessor_index].componentType [[export]]; + component_types_t component_type = Json.accessors[accessor_index].componentType [[export]]; match (Json.accessors[accessor_index].type, component_type) { - ("SCALAR", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("SCALAR", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("SCALAR", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("SCALAR", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("SCALAR", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("SCALAR", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", ComponentType::FLOAT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", ComponentType::UNSIGNED_INT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", ComponentType::UNSIGNED_SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", ComponentType::SHORT): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", ComponentType::UNSIGNED_BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", ComponentType::BYTE): StrideType, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("SCALAR", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC2", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC3", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("VEC4", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT2", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT3", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + ("MAT4", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; } }; -fn mem_cnt(auto value) { - return std::core::member_count(value); -}; - -struct ImageBuffer { +struct image_buffer_t { hex::type::Json Json @ json_offset; u64 image_index = std::core::array_index(); u64 buffer_view_index = Json.images[image_index].bufferView; @@ -229,7 +216,7 @@ struct ImageBuffer { u8 image[byte_length] @ Offset + byte_offset; } [[hex::visualize("image", image)]]; -struct BufferView { +struct buffer_view_t { hex::type::Json Json @ json_offset; u64 buffer_view_index = std::core::array_index(); u64 byte_offset = Json.bufferViews[buffer_view_index].byteOffset; @@ -237,7 +224,7 @@ struct BufferView { u8 data[byte_length] @ Offset + byte_offset; }; -struct Glb { +struct glb_file_t { gltf_magic_t magic; gltf_chunk_t json_chunk; gltf_chunk_t chunks[while(!std::mem::eof())]; @@ -247,15 +234,16 @@ struct Glb { std::assert_warn(std::mem::size() == magic.length, "file size mismatch"); +#ifdef __IMHEX__ if (std::core::member_count(chunks) == 1) { u128 bin_chunk = addressof(chunks[0].data); - hex::type::Json Json @ json_offset; - if (std::core::has_member(Json, "images")) { - ImageBuffer images[mem_cnt(json_chunk.json.images)]; + if (has_mem(json_chunk.json, "images")) { + image_buffer_t images[mem_cnt(json_chunk.json.images)]; } - BufferView buffer_views[mem_cnt(json_chunk.json.bufferViews)]; - Accessor accessors[mem_cnt(json_chunk.json.accessors)]; + buffer_view_t buffer_views[mem_cnt(json_chunk.json.bufferViews)]; + accessor_t accessors[mem_cnt(json_chunk.json.accessors)]; } +#endif }; -Glb glb @ 0x00; \ No newline at end of file +glb_file_t glb @ 0x00; \ No newline at end of file diff --git a/patterns/png.hexpat b/patterns/png.hexpat index ebd7122e..787d058f 100644 --- a/patterns/png.hexpat +++ b/patterns/png.hexpat @@ -214,6 +214,11 @@ struct Chunks { chunk_t iend_chunk [[comment("Image End Chunk")]]; }; -u8 visualizer[std::mem::size()] @ 0x00 [[sealed, hex::visualize("image", this)]]; -header_t header @ 0x00 [[comment("PNG file signature"), name("Signature")]]; -Chunks chunks @ 0x08 [[name("Chunks")]]; \ No newline at end of file +struct Png { + header_t header [[comment("PNG file signature"), name("Signature")]]; + Chunks chunks [[name("Chunks")]]; + u128 length = $ - addressof(this); + u8 visualizer[length] @ addressof(this) [[sealed, hex::visualize("image", this), no_unique_address]]; +}; + +Png png @ 0x00; \ No newline at end of file diff --git a/patterns/png2.hexpat b/patterns/png2.hexpat new file mode 100644 index 00000000..787d058f --- /dev/null +++ b/patterns/png2.hexpat @@ -0,0 +1,224 @@ +#pragma description PNG image + +#pragma MIME image/png +#pragma endian big + +import std.mem; + +struct header_t { + u8 highBitByte; + char signature[3]; + char dosLineEnding[2]; + char dosEOF; + char unixLineEnding; +}; + +struct actl_t { + u32 frames [[comment("Total № of frames in animation")]]; + u32 plays [[comment("№ of times animation will loop")]]; +} [[comment("Animation control chunk"), name("acTL")]]; + +enum ColorType: u8 { + Grayscale = 0x0, + RGBTriple = 0x2, + Palette, + GrayscaleAlpha, + RGBA = 0x6 +}; + +enum Interlacing: u8 { + None, + Adam7 +}; + +struct ihdr_t { + u32 width [[comment("Image width")]]; + u32 height [[comment("Image height")]]; + u8 bit_depth; + ColorType color_type [[comment("PNG Image Type")]]; + u8 compression_method [[comment("Only 0x0 = zlib supported by most")]]; + u8 filter_method [[comment("Only 0x0 = adaptive supported by most")]]; + Interlacing interlacing; +}; + +enum sRGB: u8 { + Perceptual = 0x0, + RelativeColorimetric, + Saturation, + AbsoluteColorimetric +}; + +enum Unit: u8 { + Unknown, + Meter +}; + +struct phys_t { + u32 ppu_x [[comment("Pixels per unit, X axis")]]; + u32 ppu_y [[comment("Pixels per unit, Y axis")]]; + Unit unit; +}; + +enum BlendOp: u8 { + Source = 0x0, + Over +}; + +enum DisposeOp: u8 { + None = 0x0, + Background, + Previous +}; + +struct fctl_t { + u32 sequence_no [[comment("Sequence №")]]; + u32 width [[comment("Frame width")]]; + u32 height; + u32 xoff; + u32 yoff; + u16 delay_num; + u16 delay_den; + DisposeOp dispose_op; + BlendOp blend_op; +}; + +struct fdat_t { + u32 sequence_no; +}; + +fn text_len() { + u64 len = parent.parent.length - ($ - addressof(parent.keyword)); + return len; +}; + +struct itxt_t { + char keyword[]; + u8 compression_flag; + u8 compression_method; + char language_tag[]; + char translated_keyword[]; + char text[text_len()]; +}; + +struct ztxt_t { + char keyword[]; + u8 compression_method; + char text[text_len()]; +}; + +struct text_t { + char keyword[]; + char text[text_len()]; +}; + +struct iccp_t { + char keyword[]; + u8 compression_method; + u8 compressed_profile[text_len()]; +}; + +struct palette_entry_t { + u24 color; +} [[inline]]; + +struct chrm_t { + u32 white_point_x; + u32 white_point_y; + u32 red_x; + u32 red_y; + u32 green_x; + u32 green_y; + u32 blue_x; + u32 blue_y; +}; + +struct time_t { + u16 year; + u8 month; + u8 day; + u8 hour; + u8 minute; + u8 second; +}; + +struct chunk_t { + u32 length [[color("17BECF")]]; + char name[4]; + + #define IHDR_k "IHDR" + #define PLTE_k "PLTE" + #define sRGB_k "sRGB" + #define pHYs_k "pHYs" + #define iTXt_k "iTXt" + #define tEXt_k "tEXt" + #define zTXt_k "zTXt" + #define IDAT_k "IDAT" + #define IEND_k "IEND" + #define gAMA_k "gAMA" + #define iCCP_k "iCCP" + #define acTL_k "acTL" + #define fdAT_k "fdAT" + #define fcTL_k "fcTL" + #define cHRM_k "cHRM" + #define tIME_k "tIME" + + if (name == IHDR_k) { + ihdr_t ihdr [[comment("Image Header chunk"), name("IHDR")]]; + } else if (name == PLTE_k) { + palette_entry_t entries[length / 3]; + } else if (name == sRGB_k) { + sRGB srgb; + } else if (name == pHYs_k) { + phys_t phys; + } else if (name == acTL_k) { + actl_t actl [[comment("Animation control chunk")]]; + } else if (name == fcTL_k) { + fctl_t fctl [[comment("Frame control chunk")]]; + } else if (name == iTXt_k) { + itxt_t text; + } else if (name == gAMA_k) { + u32 gamma [[name("image gamma"), comment("4 byte unsigned integer representing gamma times 100000")]]; + } else if (name == iCCP_k) { + iccp_t iccp; + } else if (name == tEXt_k) { + text_t text; + } else if (name == zTXt_k) { + ztxt_t text; + } else if (name == iCCP_k) { + iccp_t iccp; + } else if (name == fdAT_k) { + fdat_t fdat [[comment("Frame data chunk")]]; + u8 data[length-sizeof(u32)]; + } else if (name == cHRM_k) { + chrm_t chrm; + } else if (name == tIME_k) { + time_t time; + } else { + u8 data[length]; + } + + u32 crc; +} [[name(chunkValueName(this))]]; + +fn chunkValueName(ref chunk_t chunk) { + return chunk.name; +}; + +struct chunk_set { + chunk_t chunks[while(builtin::std::mem::read_string($ + 4, 4) != "IEND")] [[inline]]; +} [[inline]]; + +struct Chunks { + chunk_t ihdr_chunk [[comment("PNG Header chunk")]]; + chunk_set set [[comment("PNG Chunks"), name("Chunks"), inline]]; + chunk_t iend_chunk [[comment("Image End Chunk")]]; +}; + +struct Png { + header_t header [[comment("PNG file signature"), name("Signature")]]; + Chunks chunks [[name("Chunks")]]; + u128 length = $ - addressof(this); + u8 visualizer[length] @ addressof(this) [[sealed, hex::visualize("image", this), no_unique_address]]; +}; + +Png png @ 0x00; \ No newline at end of file From efd3752debaebd0441e0cbecb4b684332db95592 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Mon, 23 Jun 2025 23:13:55 +0200 Subject: [PATCH 3/5] patterns: Reuse json from global variable in gltf --- patterns/gltf.hexpat | 158 +++++++++++++++++++++---------------------- 1 file changed, 78 insertions(+), 80 deletions(-) diff --git a/patterns/gltf.hexpat b/patterns/gltf.hexpat index c421b695..599ed032 100644 --- a/patterns/gltf.hexpat +++ b/patterns/gltf.hexpat @@ -30,8 +30,10 @@ import std.mem; import std.io; import type.magic; -import hex.type.json; import std.core; +#ifdef __IMHEX__ +import hex.type.json; +#endif /** * @brief The glTF magic section. @@ -75,9 +77,6 @@ fn gltf_format(gltf_chunk_type_t x) return ""; }; -u64 json_offset = 0; -u64 json_length = 0; - struct stride_type_t { InnerType value [[inline]]; if (Stride > 0) { @@ -142,86 +141,84 @@ fn has_mem(auto value, str member) { return std::core::has_member(value, member); }; -struct accessor_t { - hex::type::Json Json @ json_offset; +struct accessor_t { u64 accessor_index = std::core::array_index(); - u64 view_index = Json.accessors[accessor_index].bufferView [[export]]; - u64 view_offset = Json.bufferViews[view_index].byteOffset [[export]]; - if (has_mem(Json.bufferViews[view_index], "byteStride")) { - u64 byte_stride = Json.bufferViews[view_index].byteStride [[export]]; + u64 view_index = glb.json_chunk.json.accessors[accessor_index].bufferView [[export]]; + u64 view_offset = glb.json_chunk.json.bufferViews[view_index].byteOffset [[export]]; + if (has_mem(glb.json_chunk.json.bufferViews[view_index], "byteStride")) { + u64 byte_stride = glb.json_chunk.json.bufferViews[view_index].byteStride [[export]]; } else { u64 byte_stride = 0 [[export]]; } - if (has_mem(Json.accessors[accessor_index], "byteOffset")) { - u64 accessor_offset = Json.accessors[accessor_index].byteOffset [[export]]; + if (has_mem(glb.json_chunk.json.accessors[accessor_index], "byteOffset")) { + u64 accessor_offset = glb.json_chunk.json.accessors[accessor_index].byteOffset [[export]]; } else { u64 accessor_offset = 0 [[export]]; } view_offset = view_offset + accessor_offset; - u64 count_elements = Json.accessors[accessor_index].count; - component_types_t component_type = Json.accessors[accessor_index].componentType [[export]]; - - match (Json.accessors[accessor_index].type, component_type) { - ("SCALAR", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("SCALAR", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("SCALAR", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("SCALAR", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("SCALAR", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("SCALAR", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC2", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC3", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("VEC4", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT2", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT3", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; - ("MAT4", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + Offset; + u64 count_elements = glb.json_chunk.json.accessors[accessor_index].count; + component_types_t component_type = glb.json_chunk.json.accessors[accessor_index].componentType [[export]]; + str element_type = glb.json_chunk.json.accessors[accessor_index].type [[export]]; + + match (element_type, component_type) { + ("SCALAR", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("SCALAR", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("SCALAR", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("SCALAR", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("SCALAR", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("SCALAR", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC2", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC2", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC2", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC2", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC2", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC2", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC3", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC3", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC3", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC3", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC3", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC3", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC4", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC4", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC4", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC4", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC4", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC4", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT2", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT2", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT2", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT2", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT2", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT2", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT3", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT3", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT3", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT3", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT3", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT3", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT4", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT4", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT4", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT4", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT4", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT4", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); } }; -struct image_buffer_t { - hex::type::Json Json @ json_offset; +struct image_buffer_t { u64 image_index = std::core::array_index(); - u64 buffer_view_index = Json.images[image_index].bufferView; - u64 byte_offset = Json.bufferViews[buffer_view_index].byteOffset; - u64 byte_length = Json.bufferViews[buffer_view_index].byteLength; - u8 image[byte_length] @ Offset + byte_offset; + u64 buffer_view_index = glb.json_chunk.json.images[image_index].bufferView; + u64 byte_offset = glb.json_chunk.json.bufferViews[buffer_view_index].byteOffset; + u64 byte_length = glb.json_chunk.json.bufferViews[buffer_view_index].byteLength; + u8 image[byte_length] @ addressof(glb.chunks[0]) + byte_offset; } [[hex::visualize("image", image)]]; -struct buffer_view_t { - hex::type::Json Json @ json_offset; +struct buffer_view_t { u64 buffer_view_index = std::core::array_index(); - u64 byte_offset = Json.bufferViews[buffer_view_index].byteOffset; - u64 byte_length = Json.bufferViews[buffer_view_index].byteLength; - u8 data[byte_length] @ Offset + byte_offset; + u64 byte_offset = glb.json_chunk.json.bufferViews[buffer_view_index].byteOffset; + u64 byte_length = glb.json_chunk.json.bufferViews[buffer_view_index].byteLength; + u8 data[byte_length] @ addressof(glb.chunks[0]) + byte_offset; }; struct glb_file_t { @@ -229,21 +226,22 @@ struct glb_file_t { gltf_chunk_t json_chunk; gltf_chunk_t chunks[while(!std::mem::eof())]; - json_offset = addressof(json_chunk.json); - json_length = json_chunk.length; - std::assert_warn(std::mem::size() == magic.length, "file size mismatch"); +}; + +glb_file_t glb @ 0x00; #ifdef __IMHEX__ - if (std::core::member_count(chunks) == 1) { - u128 bin_chunk = addressof(chunks[0].data); - if (has_mem(json_chunk.json, "images")) { - image_buffer_t images[mem_cnt(json_chunk.json.images)]; +struct glb_objects_t { + if (std::core::member_count(glb.chunks) == 1) { + u128 bin_chunk = addressof(glb.chunks[0].data); + if (has_mem(glb.json_chunk.json, "images")) { + image_buffer_t images[mem_cnt(glb.json_chunk.json.images)]; } - buffer_view_t buffer_views[mem_cnt(json_chunk.json.bufferViews)]; - accessor_t accessors[mem_cnt(json_chunk.json.accessors)]; + buffer_view_t buffer_views[mem_cnt(glb.json_chunk.json.bufferViews)]; + accessor_t accessors[mem_cnt(glb.json_chunk.json.accessors)]; } -#endif }; -glb_file_t glb @ 0x00; \ No newline at end of file +glb_objects_t objects @ 0x00; +#endif \ No newline at end of file From 5dcdf8d9e8d52c7302fad178962c25c79cadbd3b Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Tue, 24 Jun 2025 19:30:53 +0200 Subject: [PATCH 4/5] patterns: Check component type in gltf only once --- patterns/gltf.hexpat | 141 +++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 72 deletions(-) diff --git a/patterns/gltf.hexpat b/patterns/gltf.hexpat index 599ed032..77887940 100644 --- a/patterns/gltf.hexpat +++ b/patterns/gltf.hexpat @@ -77,51 +77,84 @@ fn gltf_format(gltf_chunk_type_t x) return ""; }; -struct stride_type_t { +struct stride_type_t { + auto component_type = component_type_; InnerType value [[inline]]; if (Stride > 0) { padding[Stride - sizeof(value)]; } }; -struct scalar_t { - ComponentType scalar; -} [[static, sealed]]; +enum component_types_t : u64 { + BYTE = 5120, + UNSIGNED_BYTE = 5121, + SHORT = 5122, + UNSIGNED_SHORT = 5123, + UNSIGNED_INT = 5125, + FLOAT = 5126, +}; + +fn component_type_format(component_types_t component_type) +{ + if (component_type == component_types_t::BYTE) return "s8"; +else if (component_type == component_types_t::UNSIGNED_BYTE) return "u8"; +else if (component_type == component_types_t::SHORT) return "s16"; +else if (component_type == component_types_t::UNSIGNED_SHORT) return "u16"; +else if (component_type == component_types_t::UNSIGNED_INT) return "u32"; +else if (component_type == component_types_t::FLOAT) return "float"; + + return std::format("{}", component_type); +}; + +struct component_type_t { + match (component_type) { + (component_types_t::BYTE): s8 value; + (component_types_t::UNSIGNED_BYTE): u8 value; + (component_types_t::SHORT): s16 value; + (component_types_t::UNSIGNED_SHORT): u16 value; + (component_types_t::UNSIGNED_INT): u32 value; + (component_types_t::FLOAT): float value; + } +}; + +struct scalar_t { + component_type_t scalar [[inline]]; +} [[static]]; -struct vec2_t { - ComponentType x; - ComponentType y; +struct vec2_t { + component_type_t x; + component_type_t y; } [[static]]; -struct vec3_t { - ComponentType x; - ComponentType y; - ComponentType z; +struct vec3_t { + component_type_t x; + component_type_t y; + component_type_t z; } [[static]]; -struct vec4_t { - ComponentType x; - ComponentType y; - ComponentType z; - ComponentType w; +struct vec4_t { + component_type_t x; + component_type_t y; + component_type_t z; + component_type_t w; } [[static]]; -struct mat2_t { - ComponentType a11, a21; - ComponentType a12, a22; +struct mat2_t { + component_type_t a11, a21; + component_type_t a12, a22; } [[static]]; -struct mat3_t { - ComponentType a11, a21, a31; - ComponentType a12, a22, a32; - ComponentType a13, a23, a33; +struct mat3_t { + component_type_t a11, a21, a31; + component_type_t a12, a22, a32; + component_type_t a13, a23, a33; } [[static]]; -struct mat4_t { - ComponentType a11, a21, a31, a41; - ComponentType a12, a22, a32, a42; - ComponentType a13, a23, a33, a43; - ComponentType a14, a24, a34, a44; +struct mat4_t { + component_type_t a11, a21, a31, a41; + component_type_t a12, a22, a32, a42; + component_type_t a13, a23, a33, a43; + component_type_t a14, a24, a34, a44; } [[static]]; enum component_types_t : u64 { @@ -160,49 +193,14 @@ struct accessor_t { component_types_t component_type = glb.json_chunk.json.accessors[accessor_index].componentType [[export]]; str element_type = glb.json_chunk.json.accessors[accessor_index].type [[export]]; - match (element_type, component_type) { - ("SCALAR", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("SCALAR", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("SCALAR", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("SCALAR", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("SCALAR", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("SCALAR", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC2", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC2", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC2", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC2", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC2", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC2", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC3", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC3", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC3", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC3", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC3", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC3", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC4", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC4", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC4", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC4", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC4", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC4", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT2", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT2", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT2", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT2", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT2", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT2", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT3", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT3", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT3", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT3", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT3", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT3", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT4", component_types_t::FLOAT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT4", component_types_t::UNSIGNED_INT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT4", component_types_t::UNSIGNED_SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT4", component_types_t::SHORT): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT4", component_types_t::UNSIGNED_BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT4", component_types_t::BYTE): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + match (element_type) { + ("SCALAR"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC2"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC3"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("VEC4"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT2"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT3"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("MAT4"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); } }; @@ -234,7 +232,6 @@ glb_file_t glb @ 0x00; #ifdef __IMHEX__ struct glb_objects_t { if (std::core::member_count(glb.chunks) == 1) { - u128 bin_chunk = addressof(glb.chunks[0].data); if (has_mem(glb.json_chunk.json, "images")) { image_buffer_t images[mem_cnt(glb.json_chunk.json.images)]; } From 9209f661fdec13743726078c4e614dc593680137 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Mon, 23 Jun 2025 23:14:08 +0200 Subject: [PATCH 5/5] patterns: Fix gltf pattern and add formatting Removes the duplicate definition of `component_type_t` and also removes the need to pass the `component_type` to `stride_type_t`. --- patterns/gltf.hexpat | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/patterns/gltf.hexpat b/patterns/gltf.hexpat index 77887940..a208b965 100644 --- a/patterns/gltf.hexpat +++ b/patterns/gltf.hexpat @@ -77,8 +77,7 @@ fn gltf_format(gltf_chunk_type_t x) return ""; }; -struct stride_type_t { - auto component_type = component_type_; +struct stride_type_t { InnerType value [[inline]]; if (Stride > 0) { padding[Stride - sizeof(value)]; @@ -157,15 +156,6 @@ struct mat4_t { component_type_t a14, a24, a34, a44; } [[static]]; -enum component_types_t : u64 { - BYTE = 5120, - UNSIGNED_BYTE = 5121, - SHORT = 5122, - UNSIGNED_SHORT = 5123, - UNSIGNED_INT = 5125, - FLOAT = 5126, -}; - fn mem_cnt(auto value) { return std::core::member_count(value); }; @@ -194,14 +184,18 @@ struct accessor_t { str element_type = glb.json_chunk.json.accessors[accessor_index].type [[export]]; match (element_type) { - ("SCALAR"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC2"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC3"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("VEC4"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT2"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT3"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); - ("MAT4"): stride_type_t, component_type, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0]); + ("SCALAR"): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0].data); + ("VEC2"): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0].data); + ("VEC3"): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0].data); + ("VEC4"): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0].data); + ("MAT2"): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0].data); + ("MAT3"): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0].data); + ("MAT4"): stride_type_t, byte_stride> content[count_elements] @ view_offset + addressof(glb.chunks[0].data); } +} [[format("accessor_format")]]; + +fn accessor_format(accessor_t accessor) { + return std::format("{}<{}>[{}]", accessor.element_type, accessor.component_type, accessor.count_elements); }; struct image_buffer_t { @@ -209,14 +203,14 @@ struct image_buffer_t { u64 buffer_view_index = glb.json_chunk.json.images[image_index].bufferView; u64 byte_offset = glb.json_chunk.json.bufferViews[buffer_view_index].byteOffset; u64 byte_length = glb.json_chunk.json.bufferViews[buffer_view_index].byteLength; - u8 image[byte_length] @ addressof(glb.chunks[0]) + byte_offset; + u8 image[byte_length] @ addressof(glb.chunks[0].data) + byte_offset; } [[hex::visualize("image", image)]]; struct buffer_view_t { u64 buffer_view_index = std::core::array_index(); u64 byte_offset = glb.json_chunk.json.bufferViews[buffer_view_index].byteOffset; u64 byte_length = glb.json_chunk.json.bufferViews[buffer_view_index].byteLength; - u8 data[byte_length] @ addressof(glb.chunks[0]) + byte_offset; + u8 data[byte_length] @ addressof(glb.chunks[0].data) + byte_offset; }; struct glb_file_t {