Skip to content

Commit

Permalink
patterns: Added new WebP and VGM patterns (#294)
Browse files Browse the repository at this point in the history
* README: fix square bracket

* patterns: add WebP pattern

* patterns/dds: add x-dds mimetype

* patterns: add vgm pattern

* patterns/vgm: remove old pointer

* patterns/protobuf: fix field number handling

* patterns/protobuf: add .pb file extension

* patterns/uf2: updating the family IDs again

* patterns/png: add cHRM and tIME chunks

* patterns/png: whoops, old description snuck back in

* new quantized-mesh pattern

* add quantized-mesh to README, implement oct16 decoding
  • Loading branch information
applecuckoo authored Nov 17, 2024
1 parent 6697fc2 commit bf94cb7
Show file tree
Hide file tree
Showing 9 changed files with 604 additions and 15 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|------|------|------|-------------|
| 3DS | | [`patterns/3ds.hexpat`](patterns/3ds.hexpat) | Autodesk 3DS Max Model file |
| 7Z | | [`patterns/7z.hexpat`](patterns/7z.hexpat) | 7z File Format |
| ADTS | | [`patterns/adts.hexpat`(patterns/adts.hexpat) | ADTS/AAC audio files |
| ADTS | | [`patterns/adts.hexpat`](patterns/adts.hexpat) | ADTS/AAC audio files |
| AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log |
| ANI | `application/x-navi-animation` | [`patterns/ani.hexpat`](patterns/ani.hexpat) | Windows Animated Cursor file |
| AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files |
Expand Down Expand Up @@ -115,6 +115,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
| PYC | | [`patterns/pyc.hexpat`](patterns/pyc.hexpat) | Python bytecode files |
| QBCL | | [`patterns/qbcl.hexpat`](patterns/qbcl.hexpat) | Qubicle voxel scene project file |
| QOI | `image/qoi` | [`patterns/qoi.hexpat`](patterns/qoi.hexpat) | QOI image files |
| quantized-mesh | | [`patterns/quantized-mesh.hexpat`](patterns/quantized-mesh.hexpat) | Cesium quantized-mesh terrain |
| RAS | `image/x-sun-raster` | [`patterns/ras.hexpat`](patterns/ras.hexpat) | RAS image files |
| ReFS | | [`patterns/refs.hexpat`](patterns/refs.hexpat) | Microsoft Resilient File System |
| RGBDS | | [`patterns/rgbds.hexpat`](patterns/rgbds.hexpat) | [RGBDS](https://rgbds.gbdev.io) object file format |
Expand All @@ -136,10 +137,12 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
| UF2 | | [`patterns/uf2.hexpat`](patterns/uf2.hexpat) | [USB Flashing Format](https://github.com/microsoft/uf2) |
| VBMeta | | [`patterns/vbmeta.hexpat`](patterns/vbmeta.hexpat) | Android VBMeta image |
| VDF | | [`patterns/vdf.hexpat`](patterns/vdf.hexpat) | Binary Value Data Format (.vdf) files |
| VGM | | [`patterns/vgm.hexpat`](patterns/vgm.hexpat) | VGM (Video Game Music) sound log |
| VHDX | | [`patterns/vhdx.hexpat`](patterns/vhdx.hexpat) | Microsoft Hyper-V Virtual Hard Disk format |
| WAV | `audio/x-wav` | [`patterns/wav.hexpat`](patterns/wav.hexpat) | RIFF header, WAVE header, PCM header |
| WAS | | [`patterns\was_oskasoftware.hexpat`](patterns\was_oskasoftware.hexpat) | Oska Software DeskMates WAS/WA3 (WAVE/MP3 Set) file
| WAD | | [`patterns/wad.hexpat`](patterns/wad.hexpat) | DOOM WAD Archive |
| WebP | `image/webp` | [`patterns/webp.hexpat`](patterns/webp.hexpat) | Google WebP image |
| XBEH | `audio/x-xbox-executable` | [`patterns/xbeh.hexpat`](patterns/xbeh.hexpat) | Xbox executable |
| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cartridge ROM |
| XGT | | [`patterns/xgt.hexpat`](patterns/xgstexture.hexpat) | Exient XGS Engine Texture |
Expand Down
1 change: 1 addition & 0 deletions patterns/dds.hexpat
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma description DirectDraw Surface

#pragma MIME image/vnd-ms.dds
#pragma MIME image/x-dds
#pragma endian little

enum DXGI_FORMAT : u32 {
Expand Down
28 changes: 27 additions & 1 deletion patterns/png.hexpat
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma description PNG image
#pragma description PNG image

#pragma MIME image/png
#pragma endian big
Expand Down Expand Up @@ -121,6 +121,26 @@ struct palette_entry_t {
u24 color;
} [[inline]];

struct chrm_t {
u32 white_point_x;
u32 white_point_y;
u32 red_x;
u32 red_y;
u32 green_x;
u32 green_y;
u32 blue_x;
u32 blue_y;
};

struct time_t {
u16 year;
u8 month;
u8 day;
u8 hour;
u8 minute;
u8 second;
};

struct chunk_t {
u32 length [[color("17BECF")]];
char name[4];
Expand All @@ -139,6 +159,8 @@ struct chunk_t {
#define acTL_k "acTL"
#define fdAT_k "fdAT"
#define fcTL_k "fcTL"
#define cHRM_k "cHRM"
#define tIME_k "tIME"

if (name == IHDR_k) {
ihdr_t ihdr [[comment("Image Header chunk"), name("IHDR")]];
Expand Down Expand Up @@ -167,6 +189,10 @@ struct chunk_t {
} else if (name == fdAT_k) {
fdat_t fdat [[comment("Frame data chunk")]];
u8 data[length-sizeof(u32)];
} else if (name == cHRM_k) {
chrm_t chrm;
} else if (name == tIME_k) {
time_t time;
} else {
u8 data[length];
}
Expand Down
36 changes: 23 additions & 13 deletions patterns/protobuf.hexpat
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma author WerWolv
#pragma description Google Protobuf
#pragma description Google Protobuf wire encoding (.pb)

import std.core;
import std.io;
import std.mem;

import type.leb128;
Expand Down Expand Up @@ -31,10 +32,19 @@ enum WireType : u8 {
_32Bit = 5
};

bitfield Key {
field_number : 5;
wire_type : 3;
} [[bitfield_order(std::core::BitfieldOrder::MostToLeastSignificant, 8)]];
WireType wire_type;
u32 tag;
u32 field_number;

struct Key {
type::uLEB128 keyDec;
field_number = u32(keyDec) >> 3;
wire_type = u32(keyDec) & 7;
}[[sealed, format("format_key")]];

fn format_key(Key keyObject) {
return std::format("{} with field number {}", wire_type, field_number);
};

union _64Bit {
u64 fixed64;
Expand All @@ -49,22 +59,22 @@ union _32Bit {
};

struct LengthDelimited {
type::LEB128 length;
type::uLEB128 length;
char data[length];
};


struct Entry {
Key key;
Key key;

if (key.wire_type == WireType::Varint)
type::LEB128 value;
else if (key.wire_type == WireType::_64Bit)
if (wire_type == WireType::Varint)
type::uLEB128 value;
else if (wire_type == WireType::_64Bit)
_64Bit value;
else if (key.wire_type == WireType::LengthDelimited)
else if (wire_type == WireType::LengthDelimited)
LengthDelimited value;
else if (key.wire_type == WireType::_32Bit)
else if (wire_type == WireType::_32Bit)
_32Bit value;
};

Entry entries[while(!std::mem::eof())] @ 0x00;
Entry entries[while(!std::mem::eof())] @ 0x00;
169 changes: 169 additions & 0 deletions patterns/quantized-mesh.hexpat
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#pragma author applecuckoo
#pragma description Cesium quantized-mesh terrain
#pragma endian little

// based on https://github.com/CesiumGS/quantized-mesh
// potential improvements: figure out high water mark encoding for indices

import std.math;
import std.io;

u8 extensionCount;
extensionCount = 0; // NOTE: set this to the amount of extensions in your terrain.

// ZigZag decoder based on protobuf.hexpat by WerWolv

struct ZigZag16 {
u16 value;
} [[sealed, format("format_zigzag16")]];

fn format_zigzag16(ZigZag16 zigzag) {
return s16((s16(zigzag.value) << 1) ^ (s16(zigzag.value) >> 15));
};

struct QuantizedMeshHeader {
double CenterX;
double CenterY;
double CenterZ;

float MinimumHeight;
float MaximumHeight;

double BoundingSphereCenterX;
double BoundingSphereCenterY;
double BoundingSphereCenterZ;
double BoundingSphereRadius;

double HorizonOcclusionPointX;
double HorizonOcclusionPointY;
double HorizonOcclusionPointZ;
};

struct VertexData {
u32 vertexCount;
ZigZag16 u[vertexCount];
ZigZag16 v[vertexCount];
ZigZag16 height[vertexCount];
};

struct IndexData16 {
u32 triangleCount;
u16 indices[triangleCount * 3];
};

struct IndexData32 {
u32 triangleCount;
u32 indices[triangleCount * 3];
};

struct EdgeIndices16 {
u32 westVertexCount;
u16 westIndices[westVertexCount];

u32 southVertexCount;
u16 southIndices[southVertexCount];

u32 eastVertexCount;
u16 eastIndices[eastVertexCount];

u32 northVertexCount;
u16 northIndices[northVertexCount];
};

struct EdgeIndices32 {
u32 westVertexCount;
u32 westIndices[westVertexCount];

u32 southVertexCount;
u32 southIndices[southVertexCount];

u32 eastVertexCount;
u32 eastIndices[eastVertexCount];

u32 northVertexCount;
u32 northIndices[northVertexCount];
};

enum ExtensionTypes : u8 {
OctEncodedVertexNormals = 0x1,
WaterMask,
Metadata = 0x4,
};

// Oct16 decode based on https://github.com/loicgasser/quantized-mesh-tile/blob/master/quantized_mesh_tile/utils.py

fn signNotZero(float v) {
if (v < 0.0)
return -1.0;
else
return 1.0;
};

fn fromSnorm(u8 value) {
return float(std::math::clamp(value, 0.0, 255.0) / 255.0 * 2.0 - 1.0);
};

struct Oct16 {
u8 x;
u8 y;
}[[sealed, format("format_oct16")]];

fn format_oct16(Oct16 oct) {
float xOut;
float yOut;
float zOut;

xOut = fromSnorm(oct.x);
yOut = fromSnorm(oct.y);
zOut = 1.0 - (std::math::abs(xOut) + std::math::abs(yOut));

if (zOut < 0.0) {
float oldX;

oldX = xOut;
xOut = (1.0 - std::math::abs(yOut)) * signNotZero(oldX);
yOut = (1.0 - std::math::abs(oldX)) * signNotZero(yOut);
}

return std::format("{}, {}, {}", xOut, yOut, zOut);
};

struct OctEncodedVertexNormals {
Oct16 xy[parent.parent.vertdata.vertexCount];
};

struct WaterMask {
u8 mask[parent.extensionLength];
};

struct Metadata {
u32 jsonLength;
char json[jsonLength];
};

struct ExtensionHeader {
u8 extensionId;
u32 extensionLength;
match (extensionId) {
(ExtensionTypes::OctEncodedVertexNormals): OctEncodedVertexNormals octVertNormals;
(ExtensionTypes::WaterMask): WaterMask maskData;
(ExtensionTypes::Metadata): Metadata metadata;
}
};

struct QuantizedMesh {
QuantizedMeshHeader header;
VertexData vertdata;

if (vertdata.vertexCount > 65536) {
IndexData32 indexdata;
EdgeIndices32 edgeindices;
} else {
IndexData16 indexdata;
EdgeIndices16 edgeindices;
}

ExtensionHeader extensions[extensionCount];
};

QuantizedMesh mesh @ 0x00;
10 changes: 10 additions & 0 deletions patterns/uf2.hexpat
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ enum UF2_FamilyID : u32 {
NRF52832xxAB = 0x6f752678,
AT32F415 = 0xa0c97b8e,
CH32V = 0x699b62ec,
RA4M1 = 0x7be8976d,
RTL8710A = 0x9fffd543,
RTL8710B = 0x22e0d6fc,
RTL8720C = 0xe08f7564,
RTL8720D = 0x3379CFE2,
XR809 = 0x51e903a8,
BK7231U = 0x675a40b0,
BK7251 = 0x6a82cc42,
BK7231N = 0x7b3ef230,
BL602 = 0xde1270b7,
};

fn formatTagType(UF2_TagType type) {
Expand Down
Loading

0 comments on commit bf94cb7

Please sign in to comment.