Skip to content

Commit 1333c2a

Browse files
udakenClaude Opus 4.7 (1M context)paxcut
authored
patterns: Add LZ4 Frame Format pattern (#523)
* patterns: Add LZ4 Frame Format pattern Adds a pattern for the LZ4 Frame Format supporting standard, skippable, and legacy frames. Includes validation for version, block maximum size, and end mark. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: Add LZ4 to README pattern list Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: paxcut <53811119+paxcut@users.noreply.github.com>
1 parent 7f60dd9 commit 1333c2a

3 files changed

Lines changed: 124 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
146146
| Lua 5.3 | | [`patterns/lua53.hexpat`](patterns/lua53.hexpat) | Lua 5.3 bytecode |
147147
| Lua 5.4 | | [`patterns/lua54.hexpat`](patterns/lua54.hexpat) | Lua 5.4 bytecode |
148148
| LCE Savefile | | [`patterns/lcesave.hexpat`](patterns/lcesave.hexpat) | Minecraft Legacy Console Edition save file |
149+
| LZ4 | `application/x-lz4` | [`patterns/lz4.hexpat`](patterns/lz4.hexpat) | LZ4 Frame Format |
149150
| LZNT1 | | [`patterns/lznt1.hexpat`](patterns/lznt1.hexpat) | LZNT1 compressed data format |
150151
| Mach-O | `application/x-mach-binary` | [`patterns/macho.hexpat`](patterns/macho.hexpat) | Mach-O executable |
151152
| MIDI | `audio/midi` | [`patterns/midi.hexpat`](patterns/midi.hexpat) | MIDI header, event fields provided |

patterns/lz4.hexpat

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#pragma author Gemini
2+
#pragma description LZ4 Frame Format
3+
#pragma MIME application/x-lz4
4+
#pragma endian little
5+
6+
import std.io;
7+
import std.sys;
8+
import std.mem;
9+
import std.core;
10+
11+
enum MagicNumber : u32 {
12+
Standard = 0x184D2204,
13+
Legacy = 0x184C2102,
14+
15+
Skippable_0 = 0x184D2A50,
16+
Skippable_1 = 0x184D2A51,
17+
Skippable_2 = 0x184D2A52,
18+
Skippable_3 = 0x184D2A53,
19+
Skippable_4 = 0x184D2A54,
20+
Skippable_5 = 0x184D2A55,
21+
Skippable_6 = 0x184D2A56,
22+
Skippable_7 = 0x184D2A57,
23+
Skippable_8 = 0x184D2A58,
24+
Skippable_9 = 0x184D2A59,
25+
Skippable_A = 0x184D2A5A,
26+
Skippable_B = 0x184D2A5B,
27+
Skippable_C = 0x184D2A5C,
28+
Skippable_D = 0x184D2A5D,
29+
Skippable_E = 0x184D2A5E,
30+
Skippable_F = 0x184D2A5F
31+
};
32+
33+
bitfield FLG {
34+
dictionary_id_present : 1;
35+
reserved_1 : 1;
36+
content_checksum_present : 1;
37+
content_size_present : 1;
38+
block_checksum_present : 1;
39+
block_independence : 1;
40+
version : 2;
41+
};
42+
43+
bitfield BD {
44+
reserved_0 : 4;
45+
block_max_size : 3;
46+
reserved_7 : 1;
47+
};
48+
49+
struct FrameDescriptor {
50+
FLG flg;
51+
BD bd;
52+
53+
std::assert(flg.version == 1, "Invalid LZ4 frame version (must be 01)");
54+
std::assert(bd.block_max_size >= 4, "Invalid block maximum size");
55+
56+
if (flg.content_size_present) {
57+
u64 content_size;
58+
}
59+
if (flg.dictionary_id_present) {
60+
u32 dictionary_id;
61+
}
62+
63+
u8 header_checksum;
64+
};
65+
66+
bitfield BlockSize {
67+
size : 31;
68+
uncompressed : 1;
69+
};
70+
71+
struct DataBlock<auto block_checksum_present> {
72+
BlockSize size;
73+
74+
u8 data[size.size];
75+
if (block_checksum_present) {
76+
u32 block_checksum;
77+
}
78+
};
79+
80+
struct StandardFrame {
81+
FrameDescriptor descriptor;
82+
83+
DataBlock<descriptor.flg.block_checksum_present> blocks[while($ + 4 <= std::mem::size() && std::mem::read_unsigned($, 4) != 0)];
84+
85+
if ($ + 4 <= std::mem::size()) {
86+
u32 end_mark;
87+
std::assert(end_mark == 0x00000000, "Invalid EndMark");
88+
}
89+
90+
if (descriptor.flg.content_checksum_present && $ + 4 <= std::mem::size()) {
91+
u32 content_checksum;
92+
}
93+
};
94+
95+
struct SkippableFrame {
96+
u32 frame_size;
97+
u8 user_data[frame_size];
98+
};
99+
100+
struct LegacyBlock {
101+
u32 compressed_size;
102+
u8 data[compressed_size];
103+
};
104+
105+
struct LegacyFrame {
106+
LegacyBlock blocks[while($ + 4 <= std::mem::size() && std::mem::read_unsigned($, 4) != 0x184D2204 && std::mem::read_unsigned($, 4) != 0x184C2102 && (std::mem::read_unsigned($, 4) & 0xFFFFFFF0) != 0x184D2A50)];
107+
};
108+
109+
struct Frame {
110+
MagicNumber magic;
111+
112+
if (magic == MagicNumber::Standard) {
113+
StandardFrame frame;
114+
} else if (magic == MagicNumber::Legacy) {
115+
LegacyFrame frame;
116+
} else if ((u32(magic) & 0xFFFFFFF0) == 0x184D2A50) {
117+
SkippableFrame frame;
118+
} else {
119+
std::error("Unknown Magic Number");
120+
}
121+
};
122+
123+
Frame frames[while($ < std::mem::size())] @ 0x00;
24 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)