diff --git a/README.md b/README.md index 3492223..c90c17d 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | CDA | | [`patterns/cda.hexpat`](patterns/cda.hexpat) | Compact Disc Audio track | | CHD | | [`patterns/chd.hexpat`](patterns/chd.hexpat) | MAME Compressed Hunks of Data file | | CHM | `application/vnd.ms-htmlhelp` | [`patterns/chm.hexpat`](patterns/chm.hexpat) | Windows HtmlHelp Data (ITSF / CHM) | +| Chromium Pak | | [`patterns/chromium_pak.hexpat`](patterns/chromium_pak.hexpat) | Chromium pak file | | COFF | `application/x-coff` | [`patterns/coff.hexpat`](patterns/coff.hexpat) | Common Object File Format (COFF) executable | | CPIO | `application/x-cpio` | [`patterns/cpio.hexpat`](patterns/cpio.hexpat) | Old Binary CPIO Format | | CrashLvl | | [`patterns/Crashlvl.hexpat`](patterns/Crashlvl.hexpat) | Crash Bandicoot - Back in Time (fan game) User created level format | diff --git a/patterns/chromium_pak.hexpat b/patterns/chromium_pak.hexpat new file mode 100644 index 0000000..d609b9e --- /dev/null +++ b/patterns/chromium_pak.hexpat @@ -0,0 +1,81 @@ +#pragma author East_Arctica +#pragma description Chromium Pak File + +import std.core; +import std.io; + +struct IndexEntry { + u16 id; + u32 offset; +}; + +struct AliasEntry { + u16 id; + u16 index; +}; + +struct ResourceView { + u32 i = std::core::array_index(); + + u16 id = parent.entries[i].id; + u32 start = parent.entries[i].offset; + u32 end = parent.entries[i + 1].offset; + u32 length = (end >= start) ? (end - start) : 0; + + u8 data[length] @ start; + + // pak_util.py implies that this may also be gzip with a header of 0x1f 0x8b + bool is_brotli = (length > 8 && data[0] == 0x1e && data[1] == 0x9b); + if (is_brotli) { + u8 magic[2] @ start; + u48 decompressed_size @ start + 2; + // TODO: If brotli decompression is added to ImHex, add it here. + } +}; + +struct AliasResourceView { + u32 i = std::core::array_index(); + + u16 id = parent.aliases[i].id; + u16 idx = parent.aliases[i].index; + + bool valid = (idx < parent.resource_count); + u32 start = valid ? parent.entries[idx].offset : 0; + u32 end = valid ? parent.entries[idx + 1].offset : 0; + u32 length = (valid && end >= start) ? (end - start) : 0; + + u8 data[length] @ start; + +}; + +enum PakEncoding : u8 { + binary = 0, + utf8 = 1, + utf16 = 2 +}; + +struct Pak { + u32 version; + if (version == 4) { + u32 resource_count; + PakEncoding encoding; + + IndexEntry entries[resource_count + 1]; + ResourceView resources[resource_count]; + } else if (version == 5) { + PakEncoding encoding; + padding[3]; + u16 resource_count; + u16 alias_count; + + IndexEntry entries[resource_count + 1]; + AliasEntry aliases[alias_count]; + ResourceView resources[resource_count]; + AliasResourceView alias_resources[alias_count]; + } else { + std::error("Unsupported pak version"); + } +}; + +// Some pack files are stored gzipped and need to be gunzipped first +Pak pak @ 0x00; diff --git a/tests/patterns/test_data/chromium_pak.hexpat/kEmptyPakContents.pak b/tests/patterns/test_data/chromium_pak.hexpat/kEmptyPakContents.pak new file mode 100644 index 0000000..85cf8b5 Binary files /dev/null and b/tests/patterns/test_data/chromium_pak.hexpat/kEmptyPakContents.pak differ diff --git a/tests/patterns/test_data/chromium_pak.hexpat/kSampleCompressPakContentsV5.pak b/tests/patterns/test_data/chromium_pak.hexpat/kSampleCompressPakContentsV5.pak new file mode 100644 index 0000000..ce5470b Binary files /dev/null and b/tests/patterns/test_data/chromium_pak.hexpat/kSampleCompressPakContentsV5.pak differ diff --git a/tests/patterns/test_data/chromium_pak.hexpat/kSampleCompressScaledPakContents.pak b/tests/patterns/test_data/chromium_pak.hexpat/kSampleCompressScaledPakContents.pak new file mode 100644 index 0000000..884b5f4 Binary files /dev/null and b/tests/patterns/test_data/chromium_pak.hexpat/kSampleCompressScaledPakContents.pak differ diff --git a/tests/patterns/test_data/chromium_pak.hexpat/kSamplePakContents2x.pak b/tests/patterns/test_data/chromium_pak.hexpat/kSamplePakContents2x.pak new file mode 100644 index 0000000..00669bf Binary files /dev/null and b/tests/patterns/test_data/chromium_pak.hexpat/kSamplePakContents2x.pak differ diff --git a/tests/patterns/test_data/chromium_pak.hexpat/kSamplePakContentsV4.pak b/tests/patterns/test_data/chromium_pak.hexpat/kSamplePakContentsV4.pak new file mode 100644 index 0000000..1996f57 Binary files /dev/null and b/tests/patterns/test_data/chromium_pak.hexpat/kSamplePakContentsV4.pak differ