diff --git a/README.md b/README.md index 4674d18..62172db 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | 3DS | | [`patterns/3ds.hexpat`](patterns/3ds.hexpat) | Autodesk 3DS Max Model file | | 7Z | | [`patterns/7z.hexpat`](patterns/7z.hexpat) | 7z File Format | | AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log | +| ANI | `application/x-navi-animation` | [`patterns/ani.hexpat`](patterns/ani.hexpat) | Windows Animated Cursor file | | AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files | | ARIA2 | | [`patterns/aria2.hexpat`](patterns/aria2.hexpat) | ARIA2 Download Manager Control files | | ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout | diff --git a/patterns/ani.hexpat b/patterns/ani.hexpat new file mode 100644 index 0000000..f23ff75 --- /dev/null +++ b/patterns/ani.hexpat @@ -0,0 +1,66 @@ +#pragma description Windows animated cursor +#pragma MIME application/x-navi-animation +#pragma endian little + +import std.io; +import std.mem; + +bitfield HeaderFlags { + icon : 1; + sequence : 1; + padding: 30; +}; + +struct anih { + u32 struct_size; + u32 stored_frames; + u32 animation_steps; + u32 w; + u32 h; + u32 bits; + u32 planes; + u32 default_jiffies; + HeaderFlags flags; +}; + +struct rate { + u32 jiffies[parent.size / 4]; +}; + +struct seq { + u32 index[parent.size / 4]; +}; + +struct RiffChunk { + char signature[4]; + u32 size; + if (signature == "RIFF" || signature == "LIST") { + char type[4]; + RiffChunk chunks[while($ - addressof(type) < size)]; + } else if (signature[0] == 'I' && parent.type == "INFO") { + char info[size]; + } else if (signature == "anih") { + anih anih [[inline]]; + } else if (signature == "rate") { + rate rate [[inline]]; + } else if (signature == "seq ") { + seq seq [[inline]]; + } else { + std::mem::Bytes data; + } + padding[size % 2]; +} [[format_read("read_chunk")]]; + +fn read_chunk(RiffChunk chunk) { + if (chunk.signature == "RIFF" || chunk.signature == "LIST") { + return std::format("{}<{}> ({})", chunk.signature, chunk.type, chunk.size); + } else { + str ret = std::format("{} ({})", chunk.signature, chunk.size); + try { + ret += std::format(" \"{}\"", chunk.info); + } catch {} + return ret; + } +}; + +RiffChunk riff @ 0; diff --git a/tests/patterns/test_data/ani.hexpat.ani b/tests/patterns/test_data/ani.hexpat.ani new file mode 100644 index 0000000..1dc061b Binary files /dev/null and b/tests/patterns/test_data/ani.hexpat.ani differ