mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
patterns/zstd: Added ZSTD pattern (#68)
This commit is contained in:
115
patterns/zstd.hexpat
Normal file
115
patterns/zstd.hexpat
Normal file
@@ -0,0 +1,115 @@
|
||||
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md
|
||||
|
||||
#pragma MIME application/zstd
|
||||
|
||||
#include <std/io.pat>
|
||||
#include <std/mem.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
#define ZSTD_MAGIC_NUMBER 0xFD2FB528
|
||||
|
||||
bitfield frame_header_descriptor_t {
|
||||
frame_content_size_flag : 2;
|
||||
single_segment_flag : 1;
|
||||
unused_bit : 1;
|
||||
reserved_bit : 1;
|
||||
content_checksum_flag : 1;
|
||||
dictionary_id_flag : 2;
|
||||
} [[left_to_right]];
|
||||
|
||||
bitfield window_descriptor_t {
|
||||
exponent : 5;
|
||||
mantissa : 3;
|
||||
} [[left_to_right]];
|
||||
|
||||
fn window_size(window_descriptor_t window_descriptor) {
|
||||
u64 window_log = 10 + window_descriptor.exponent;
|
||||
u64 window_base = 1 << window_log;
|
||||
u64 window_add = (window_base / 8) * window_descriptor.mantissa;
|
||||
u64 window_size = window_base + window_add;
|
||||
return window_size;
|
||||
};
|
||||
|
||||
struct frame_header_t {
|
||||
frame_header_descriptor_t frame_header_descriptor;
|
||||
|
||||
if (!frame_header_descriptor.single_segment_flag){
|
||||
window_descriptor_t window_descriptor;
|
||||
}
|
||||
|
||||
if (frame_header_descriptor.dictionary_id_flag == 1) {
|
||||
le u8 dictionary_id;
|
||||
}
|
||||
else if (frame_header_descriptor.dictionary_id_flag == 2) {
|
||||
le u16 dictionary_id;
|
||||
}
|
||||
else if (frame_header_descriptor.dictionary_id_flag == 3) {
|
||||
le u32 dictionary_id;
|
||||
}
|
||||
|
||||
if (frame_header_descriptor.frame_content_size_flag == 0) { // 0
|
||||
if (frame_header_descriptor.single_segment_flag) {
|
||||
le u8 content_size;
|
||||
}
|
||||
}
|
||||
else if (frame_header_descriptor.frame_content_size_flag == 1) {
|
||||
le u16 content_size;
|
||||
}
|
||||
else if (frame_header_descriptor.frame_content_size_flag == 2) {
|
||||
le u32 content_size;
|
||||
}
|
||||
else {
|
||||
le u64 content_size;
|
||||
}
|
||||
};
|
||||
|
||||
bitfield block_header_t {
|
||||
block_size : 21;
|
||||
block_type : 2;
|
||||
last_block : 1;
|
||||
} [[left_to_right]];
|
||||
|
||||
enum block_type : u8 {
|
||||
raw_block = 0,
|
||||
rle_block = 1,
|
||||
compressed_block = 2,
|
||||
reserved = 3
|
||||
};
|
||||
|
||||
struct data_block_t {
|
||||
block_header_t block_header;
|
||||
|
||||
if (block_header.last_block) {
|
||||
last_block_flag = true;
|
||||
}
|
||||
|
||||
if (block_header.block_type == block_type::raw_block) {
|
||||
le u8 block_content[block_header.block_size];
|
||||
}
|
||||
else if (block_header.block_type == block_type::rle_block) {
|
||||
le u8 block_content[1];
|
||||
}
|
||||
else if (block_header.block_type == block_type::compressed_block) {
|
||||
le u8 block_content[block_header.block_size];
|
||||
}
|
||||
else {
|
||||
std::error("The data block seems to be corrupted!");
|
||||
}
|
||||
};
|
||||
|
||||
struct content_checksum_t {
|
||||
le u32 xxh64_hash;
|
||||
};
|
||||
|
||||
struct zstd_frame_t {
|
||||
le u32 magic_number;
|
||||
std::assert(magic_number == ZSTD_MAGIC_NUMBER, "Invalid magic number!");
|
||||
frame_header_t frame_header;
|
||||
data_block_t data_block[while(!last_block_flag)];
|
||||
if (frame_header.frame_header_descriptor.content_checksum_flag) {
|
||||
content_checksum_t content_checksum;
|
||||
}
|
||||
};
|
||||
|
||||
bool last_block_flag = false;
|
||||
zstd_frame_t zstd_frame @ 0x00;
|
||||
Reference in New Issue
Block a user