forked from WerWolv/ImHex-Patterns
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
patterns: Added BZip3 File Header Pattern (WerWolv#329)
* Added: BZip3 Compression * Fixed: Bound the SmallBlock data by parent's size * Improved: Now uses the name 'Chunk' for block wrappers, such that the name 'block' matches with what the BZ3 API does * Improved: Import rather than Include std::mem * Added: Missing 'description' field in pragma
- Loading branch information
1 parent
cae2969
commit ebb6341
Showing
3 changed files
with
65 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#pragma author Sewer56 | ||
#pragma description Parses BZip3 compression (file format) by Kamila Szewczyk | ||
#pragma MIME application/x-bzip3 | ||
#pragma endian little | ||
#pragma magic [42 5A 33 76 31] @ 0x00 | ||
import std.mem; | ||
|
||
// Helper function for bit counting | ||
fn popcount(u8 b) { | ||
u32 count = 0; | ||
while (b != 0) { | ||
count = count + (b & 1); | ||
b = b >> 1; | ||
} | ||
return count; | ||
}; | ||
|
||
// Frame header structure | ||
struct FrameHeader { | ||
char magic[5]; // "BZ3v1" | ||
u32 blockSize; // Maximum block size | ||
}; | ||
|
||
// Small block header (for blocks < 64 bytes) | ||
struct SmallBlock { | ||
u32 crc32; // CRC32 checksum | ||
u32 literal; // Always 0xFFFFFFFF for small blocks | ||
u8 data[parent.compressedSize - 8]; // Uncompressed data | ||
}; | ||
|
||
// Regular block (blocks > 64 bytes) | ||
struct Block { | ||
u32 crc32; // CRC32 checksum of uncompressed data | ||
u32 bwtIndex; // Burrows-Wheeler transform index | ||
u8 model; // Compression model flags | ||
|
||
if ((model & 0x02) != 0) | ||
u32 lzpSize; // Size after LZP compression | ||
if ((model & 0x04) != 0) | ||
u32 rleSize; // Size after RLE compression | ||
|
||
u8 data[parent.compressedSize - (popcount(model) * 4 + 9)]; | ||
}; | ||
|
||
// Main block structure | ||
struct Chunk { | ||
u32 compressedSize; // Size of compressed block | ||
u32 origSize; // Original uncompressed size | ||
|
||
if (compressedSize < 64) { | ||
SmallBlock block; | ||
} else { | ||
Block block; | ||
} | ||
}; | ||
|
||
// Main parsing structure | ||
struct BZip3File { | ||
FrameHeader header; | ||
// Read blocks until end of file | ||
Chunk chunks[while(!std::mem::eof())]; | ||
}; | ||
|
||
BZip3File file @ 0x0; |
Binary file not shown.