diff --git a/README.md b/README.md index 87f6870..9a3cfb9 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,9 @@ Hex patterns, include patterns and magic files for the use with the ImHex Hex Ed | FDT | | [`patterns/fdt.hexpat`](patterns/fdt.hexpat) | Flat Linux Device Tree blob | | StuffItV5 | `application/x-stuffit` | [`patterns/sit5.hexpat`](patterns/sit5.hexpat) | StuffIt V5 archive | | NBT | | [`patterns/nbt.hexpat`](patterns/nbt.hexpat) | Minecraft NBT format | +| PCX | `application/x-pcx` | [`patterns/pcx.hexpat`](patterns/pcx.hexpat) | PCX Image format | +| GZIP | `application/gzip` | [`patterns/gzip.hexpat`](patterns/gzip.hexpat) | GZip compressed data format | +| PFS0 | | [`patterns/pfs0.hexpat`](patterns/pfs0.hexpat) | Nintendo Switch PFS0 archive (NSP files) | ### Scripts diff --git a/patterns/gzip.hexpat b/patterns/gzip.hexpat new file mode 100644 index 0000000..fc9fcf5 --- /dev/null +++ b/patterns/gzip.hexpat @@ -0,0 +1,77 @@ +#pragma MIME application/gzip + +#include +#include +#include + +bitfield Flags { + FTEXT : 1; + FHCRC : 1; + FEXTRA : 1; + FNAME : 1; + FCOMMENT : 1; + padding : 3; +} [[right_to_left]]; + +bitfield ExtraFlags { + padding : 1; + maximumCompression : 1; + fastestCompression : 1; + padding : 5; +}; + +enum CompressionMethod : u8 { + Reserved = 0 ... 7, + Deflate = 8 +}; + +enum OperatingSystemID : u8 { + FATFileSystem = 0x00, + Amiga = 0x01, + VMS = 0x02, + Unix = 0x03, + VM_CMS = 0x04, + AtariTOS = 0x05, + HPFSFileSystem = 0x06, + Macintosh = 0x07, + ZSystem = 0x08, + CP_M = 0x09, + TOPS_20 = 0x0A, + NTFSFileSystem = 0x0B, + QDOS = 0x0C, + AcordRISCOS = 0x0D, + Unknown = 0xFF +}; + +struct GZip { + u16 signature; + CompressionMethod compressionMethod; + Flags flags; + type::time32_t modificationTime; + ExtraFlags extraFlags; + OperatingSystemID operatingSystemId; + + if (flags.FEXTRA) { + u16 extraLength; + u8 extraField[extraLength]; + } + + if (flags.FNAME) { + char originalFileName[]; + } + + if (flags.FCOMMENT) { + char comment[]; + } + + if (flags.FHCRC) { + u16 crc16; + } + + u8 data[while($ < std::mem::size() - 8)] [[sealed]]; + + u32 crc32; + type::Size isize; +}; + +GZip gzip @ 0x00; \ No newline at end of file diff --git a/patterns/pcx.hexpat b/patterns/pcx.hexpat new file mode 100644 index 0000000..583ec3a --- /dev/null +++ b/patterns/pcx.hexpat @@ -0,0 +1,52 @@ +#pragma MIME application/x-pcx + +#include + +enum Encoding : u8 { + NoEncoding = 0x00, + RunLengthEncoding = 0x01 +}; + +enum PaletteType : u16 { + MonochromeOrColorInformation = 0x01, + GrayscaleInformation = 0x02 +}; + +enum Version : u8 { + V2_5 = 0x00, + V2_8WithPalette = 0x02, + V2_8_WithoutPalette = 0x03, + PaintbrushForWindows = 0x04, + V3_0 = 0x05 +}; + +struct Header { + u8 magic; + Version version; + Encoding encoding; + u8 bitsPerPixel; + u16 xMin, yMin; + u16 xMax, yMax; + u16 hdpi, vdpi; +}; + +struct RGB8 { + u8 r, g, b; +} [[sealed, color(std::format("{:02X}{:02X}{:02X}", this.r, this.g, this.b))]]; + +struct Palette { + RGB8 color[16]; +}; + +struct PCX { + Header header; + Palette palette; + padding[1]; + u8 numPlanes; + u16 bytesPerLine; + PaletteType paletteType; + u16 hres, vres; + padding[54]; +}; + +PCX pcx @ 0x00; \ No newline at end of file diff --git a/patterns/pfs0.hexpat b/patterns/pfs0.hexpat new file mode 100644 index 0000000..7646ee8 --- /dev/null +++ b/patterns/pfs0.hexpat @@ -0,0 +1,38 @@ +#include +#include + +#include + +struct FileEntry { + u64 dataOffset; + type::Size dataSize; + u32 nameOffset; + padding[4]; +}; + +struct String { + char value[]; +}; + +struct Header { + type::Magic<"PFS0"> magic; + u32 numFiles; + type::Size stringTableSize; + padding[4]; + + FileEntry fileEntryTable[numFiles]; + String strings[numFiles]; +}; + +struct File { + char name[] @ addressof(parent.header.strings) + parent.header.fileEntryTable[std::core::array_index()].nameOffset; + u8 data[parent.header.fileEntryTable[std::core::array_index()].dataSize] @ parent.header.fileEntryTable[std::core::array_index()].dataOffset [[sealed]]; +}; + +struct PFS0 { + Header header; + + File files[header.numFiles]; +}; + +PFS0 pfs0 @ 0x00; \ No newline at end of file diff --git a/tests/patterns/test_data/gzip.hexpat.gz b/tests/patterns/test_data/gzip.hexpat.gz new file mode 100644 index 0000000..ba0f89d Binary files /dev/null and b/tests/patterns/test_data/gzip.hexpat.gz differ diff --git a/tests/patterns/test_data/pcx.hexpat.pcx b/tests/patterns/test_data/pcx.hexpat.pcx new file mode 100644 index 0000000..c83d321 Binary files /dev/null and b/tests/patterns/test_data/pcx.hexpat.pcx differ