The NX file format was designed with speediness and ease of reading in mind, to speed up loading times for anything that uses a node-tree-based data file format.
In the NX file format, the following should be followed:
These are the reference implementations of the NX format:
Name | Type | Description |
---|---|---|
Header | Header | File header |
Node data | Node[] | Node data, including all children. |
String offset table | UInt64[] | String offset table. Contiguous block. |
String data | String[] | String data. |
Bitmap offset table | UInt64[] | Bitmap offset table. Contiguous block. |
Bitmaps | Bitmap[] | Bitmap data. |
Audio offset table | UInt64[] | Audio offset table. Contiguous block. |
Audio data | Audio[] | Audio data. |
Name | Type | Description |
---|---|---|
Magic | UInt8[4] | "PKG4" = {0x50, 0x4B, 0x47, 0x34} |
Node count | UInt32 | Total number of nodes in the file. Cannot be zero. |
Node block offset | Node* | Offset to the start of the node block, which should be the base node: the parent of all other nodes in the file. This must be a multiple of 4. |
String count | UInt32 | Total number of String entries in the file. Cannot be zero. |
String offset table offset | OffsetTable* | Offset to the string offset table in the file, with the number of entries equal to the String count. This must be a multiple of 8. |
Bitmap count | UInt32 | Total number of Bitmap entries in the file. Zero indicates no bitmap data. |
Bitmap offset table offset | OffsetTable* | Offset to the bitmap offset table in the file, with the number of entries equal to Bitmap count . This must be a multiple of 8. Ignored if Bitmap count is 0 . |
Audio count | UInt32 | Total number of Audio entries in the file. Zero indicates no audio data. |
Audio offset table offset | OffsetTable* | Offset to the audio offset table in the file, with the number of entries equal to Audio count . This must be a multiple of 8. Ignored if Audio count is 0 . |
Each Node
is assigned a zero-based 32-bit unsigned ID in the order they appear in the node block; that is, the first Node
(the base node) has ID 0, the second node has ID 1, and so on. This ID is used to point to child nodes of Node
s.
All Node
s should be in one contiguous block, which should be of size 20 * Number of nodes
. Node
s must be aligned to an 8-byte boundary.
Children Node
s of each parent Node
must be consecutive in one contiguous block, and the ID of the first child in the block is specified in the First Child ID
field of the parent Node
. Children Node
s of each parent Node
must be sorted in ascending order according to the UTF-8 value of the node name of each child. Children Node
s of any given parent Node
must have unique node names.
The base node should have an ID of 0, and preferably have type 0 (None).
Name | Type | Description | ||
---|---|---|---|---|
Node name | UInt32 | String ID representing the name of this node | ||
First Child ID | UInt32 | Node ID of first child. Present but ignored if child count is zero (0). | ||
Children count | UInt16 | Zero means there are no children. | ||
Type | UInt16 | 0 = No data 1 = Int64 2 = Double 3 = String (UInt32 ID) 4 = Vector 5 = Bitmap (UInt32 ID, UInt16 Width, UInt16 Height) 6 = Audio (UInt32 ID, UInt32 Length) | ||
Data | Varies | This field is always 8 bytes. | ||
Type | Description | |||
0 | None | This field is ignored. | ||
1 | Int64 | 64-bit signed integer. | ||
2 | Double | 64-bit IEEE double-precision floating point. | ||
3 | String | 32-bit unsigned string ID. | ||
4 | Vector | Two 32-bit signed integers (Int32 ), for X and Y respectively. | ||
5 | Bitmap | 32-bit unsigned bitmap ID, followed by 16-bit unsigned width and height in that order. Ignored if Bitmap count in Header is 0 . | ||
6 | Audio | 32-bit unsigned audio ID, followed by 32-bit unsigned data length. Ignored if Audio count in Header is 0 . |
Each String
is assigned a zero-based unsigned 32-bit ID. Offsets to String
s are located in the String offset table. String
s do not need to be in a contiguous block, though this is recommended. String
s must be aligned to a 2-byte boundary.
Name | Type | Description |
---|---|---|
Length | UInt16 | Length, in bytes, of the following string data |
String data | UInt8[] | String data, encoded in UTF-8. This byte array is Length bytes long. |
Each Bitmap
is assigned a zero-based unsigned 32-bit ID. Offsets to Bitmap
s are located in the bitmap offset table. Bitmap
s do not need to be in a contiguous block, though this is recommended.
Name | Type | Description |
---|---|---|
Length | UInt32 | Length, in bytes, of the image data. Uncompressed length is Width * Height * 4 . Width and Height are specified in the Node 's Data field after the bitmap ID. |
Bitmap data | UInt8[] | Bitmap data, stored in BGRA8888 format, that is, 1 byte each for the blue, green, red and alpha components, in that order. This data is compressed with LZ4. This byte array is Length bytes long. |
Each Audio
is assigned a zero-based unsigned 32-bit ID. Offsets to Audio
s are located in the audio offset table. Audio
s do not need to be a contiguous block, though this is recommended.
Name | Type | Description |
---|---|---|
Audio data | UInt8[] | Audio data, including the 82-byte WZ header. This byte array is Length bytes long. Length is specified in the NX node's data field after the audio ID. |
Offset tables are used to refer to String
s, Bitmap
s and Audio
s. String offsets must be a multiple of 2. Bitmap and audio offsets must be a multiple of 8.
Name | Type | Description |
---|---|---|
Offset Array | UInt64[] | Sequential offset array; the first offset has ID 0, the second has ID 1, and so on. |
Acknowledgements:
Contributions to this specification are welcome. Please fork and then send a pull request to this repository.
This specification is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.