mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-28 07:47:02 -05:00
patterns: Add a pattern for zlib compression (#135)
Add a pattern for RFC 1950 zlib compression
This commit is contained in:
@@ -97,6 +97,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
||||
| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cardridge ROM |
|
||||
| Xilinx BIT | | [`patterns/xilinx_bit.hexpat`](patterns/xilinx_bit.hexpat) | Xilinx FPGA Bitstreams |
|
||||
| ZIP | `application/zip` | [`patterns/zip.hexpat`](patterns/zip.hexpat) | End of Central Directory Header, Central Directory File Headers |
|
||||
| ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format |
|
||||
| ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format |
|
||||
|
||||
### Scripts
|
||||
|
||||
88
patterns/zlib.hexpat
Normal file
88
patterns/zlib.hexpat
Normal file
@@ -0,0 +1,88 @@
|
||||
#pragma MIME application/zlib
|
||||
|
||||
#include <std/core.pat>
|
||||
#include <std/sys.pat>
|
||||
|
||||
#define HEADER_SIZE 2
|
||||
#define CSUM_SIZE 4
|
||||
|
||||
using BitfieldOrder = std::core::BitfieldOrder;
|
||||
|
||||
/// Entire stream minus header (2) and checksum (4)
|
||||
u64 data_len = std::mem::size();
|
||||
|
||||
if (data_len > (HEADER_SIZE + CSUM_SIZE)) {
|
||||
data_len -= (HEADER_SIZE + CSUM_SIZE);
|
||||
} else {
|
||||
data_len = 0;
|
||||
}
|
||||
|
||||
/// Compression method; only Deflate is used
|
||||
enum CM: u8 {
|
||||
Deflate = 8,
|
||||
Reserved = 15,
|
||||
};
|
||||
|
||||
/// Compression level
|
||||
enum Level: u8 {
|
||||
Fastest = 0,
|
||||
Fast = 1,
|
||||
Default = 2,
|
||||
Smallest = 3, // slowest
|
||||
};
|
||||
|
||||
// Compression method & flags
|
||||
bitfield Header {
|
||||
CM method : 4;
|
||||
info: 4;
|
||||
fcheck: 5;
|
||||
bool fdict: 1;
|
||||
Level flevel: 2;
|
||||
} [[bitfield_order(BitfieldOrder::LeastToMostSignificant, 16)]];
|
||||
|
||||
|
||||
/// Validate the header's checksum
|
||||
fn validate_hdr_checksum(Header hdr) {
|
||||
// Reassemble as a 2-byte big endian value
|
||||
u16 value = (
|
||||
(hdr.method << 8) +
|
||||
(hdr.info << 12) +
|
||||
(hdr.fcheck << 0) +
|
||||
(hdr.fdict << 5) +
|
||||
(hdr.flevel << 6)
|
||||
);
|
||||
|
||||
if (value % 31 == 0) {
|
||||
std::print("Zlib header checksum OK. Value: {}", value);
|
||||
} else {
|
||||
std::warning(std::format("Zlib header checksum failed! Value: {}", value));
|
||||
}
|
||||
};
|
||||
|
||||
/// Representation of a Zlib stream
|
||||
struct Zlib {
|
||||
/// Configuration
|
||||
Header header;
|
||||
|
||||
if (header.fdict) {
|
||||
/// Adler checksum of the optional dictionary
|
||||
u32 dict;
|
||||
}
|
||||
|
||||
/// Compressed data
|
||||
u8 data[data_len];
|
||||
/// Adler-32 checksum of uncompressed data
|
||||
u32 checksum;
|
||||
};
|
||||
|
||||
|
||||
// start parsing at the beginning of stream
|
||||
Zlib zlib @ 0x00;
|
||||
|
||||
// Only mode 8 (deflate) is recognized
|
||||
std::assert_warn(
|
||||
zlib.header.method == CM::Deflate,
|
||||
"Unrecognized compression method"
|
||||
);
|
||||
|
||||
validate_hdr_checksum(zlib.header);
|
||||
BIN
tests/patterns/test_data/zlib.hexpat.zlib
Normal file
BIN
tests/patterns/test_data/zlib.hexpat.zlib
Normal file
Binary file not shown.
Reference in New Issue
Block a user