diff --git a/README.md b/README.md index 24473303..4f0a3dd3 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ISO | `application/x-iso9660-image` | [`patterns/iso.hexpat`](patterns/iso.hexpat) | ISO 9660 file system | | Java Class | `application/x-java-applet` | [`patterns/java_class.hexpat`](patterns/java_class.hexpat) | Java Class files | | JPEG | `image/jpeg` | [`patterns/jpeg.hexpat`](patterns/jpeg.hexpat) | JPEG Image Format | +| JPEG XL | `patterns/jxl.hexpat` | [`patterns/jxl.hexpat`](patterns/jxl.hexpat) | JPEG XL(JXL) image format | | LOC | | [`patterns/loc.hexpat`](patterns/loc.hexpat) | Minecraft Legacy Console Edition Language file | | Lua 5.1 | | [`patterns/lua51.hexpat`](patterns/lua51.hexpat) | Lua 5.1 bytecode | | Lua 5.2 | | [`patterns/lua52.hexpat`](patterns/lua52.hexpat) | Lua 5.2 bytecode | diff --git a/patterns/jxl.hexpat b/patterns/jxl.hexpat new file mode 100644 index 00000000..0cc7c60b --- /dev/null +++ b/patterns/jxl.hexpat @@ -0,0 +1,140 @@ +#pragma author dxan29a +#pragma description JPEG XL Container Format + +import std.io; +import std.mem; +#pragma endian big +#pragma MIME image/jxl + +enum Type : u32 { + SIGNATURE = 0x4A584C20, // JXL + FILETYPE = 0x66747970, // ftyp + LEVEL = 0x6A786C6C, // jxll + JUMBF = 0x6A756D62, // jumb + EXIF = 0x45786966, // Exif + XML = 0x786D6C20, // xml + BROTILCOMPRESSED = 0x62726F62, // brob + FRAMEIDX = 0x6A786C69, // jxlu + CODESTREAM = 0x6A786C63, // jxlc + PARTIALCODESTREAM = 0x6A786C70, // jxlp + BITSTREAMRECONSTRUCTION = 0x6A627264, // jbrd + GAINMAPIMAGE = 0x6872676D // hrgm +}; + +struct Header { + u32 LBox; + u64 lbox = LBox; + Type box_type; + if (LBox == 1) { + u64 XLBox; + u64xlbox = XLBox; + } else { + u64 xlbox = 0; + } +}; + +struct Signature { + u32 validation; +}; + +struct FileType { + u8 JXL_JXL[12]; +}; + +struct Level { + u8 Level; +}; + +struct Jumbf { + if (lbox == 1) { + u8 JumbfBoxes[xlbox - 16]; + } else { + u8 JumbfBoxes[lbox - 8]; + } +}; + +struct Exif { + u32 tiff_header_offset; + if (lbox == 1) { + u8 ExifPayload[xlbox - 16 - sizeof(tiff_header_offset)]; + } else { + u8 ExifPayload[lbox - 8 - sizeof(tiff_header_offset)]; + } +}; + +struct XML { + if (lbox == 1) { + u8 XMLdata[xlbox - 16 - sizeof(tiff_header_offset)]; + } else { + u8 XMLdata[lbox - 8 - sizeof(tiff_header_offset)]; + } +}; + +struct PartialCodeStream { + u32 Index; + if (lbox == 1) { + u8 CodeStream[xlbox - 16 - sizeof(Index)]; + } else { + u8 CodeStream[lbox - 8 - sizeof(Index)]; + } +}; + +struct BrotilCompressed { + u32 PayloadTypes; + if (lbox == 1) { + u8 RemainingBytes[xlbox - 16 - sizeof(PayloadTypes)]; + } else { + u8 RemainingBytes[lbox - 8 - sizeof(PayloadTypes)]; + } +}; + +struct FrameIndex { + if (lbox == 1) { + u8 RemainingBytes[xlbox - 16]; + } else { + u8 RemainingBytes[lbox - 8]; + } +}; + +struct BitStreamReconstruction { + if (lbox == 1) { + u8 RemainingBytes[xlbox - 16]; + } else { + u8 RemainingBytes[lbox - 8]; + } +}; + +struct GainMapImage { + if (lbox == 1) { + u8 GainMapImage[xlbox - 16]; + } else { + u8 GainMapImage[lbox - 8]; + } +}; + +struct UnknownBox { + if (lbox == 1) { + u8 remaining_bytes[xlbox - 16]; + } else { + u8 remaining_bytes[lbox - 8]; + } +}; + +struct Box { + Header header; + match (header.box_type) { + (Type::SIGNATURE): Signature signature; + (Type::FILETYPE): FileType filetype; + (Type::LEVEL): Level level; + (Type::JUMBF): Jumbf jumbf; + (Type::EXIF): Exif exif; + (Type::PARTIALCODESTREAM): PartialCodeStream partial_codestream; + (Type::FRAMEIDX): FrameIndex frame_index; + (Type::BROTILCOMPRESSED): BrotilCompressed brotil_compressed; + (Type::BITSTREAMRECONSTRUCTION): BitStreamReconstruction bitstream_reconstruction; + (Type::GAINMAPIMAGE): GainMapImage gain_map_image;; + (_): UnknownBox unknown_box; + } +}; + +Box boxes[while(!std::mem::eof())] @ 0x00; \ No newline at end of file diff --git a/tests/patterns/test_data/jxl.hexpat.jxl b/tests/patterns/test_data/jxl.hexpat.jxl new file mode 100644 index 00000000..65b69e1a Binary files /dev/null and b/tests/patterns/test_data/jxl.hexpat.jxl differ