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