diff --git a/README.md b/README.md index 6f589c7..44811a7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -#NX Specification [PKG4] +#4th NX Format Specification [PKG5] -This repository hosts the NX (PKG4) specification, which is currently under development. \ No newline at end of file +This repository hosts the 4th NX Format (PKG5) specification, which is currently under development. \ No newline at end of file diff --git a/index.html b/index.html index ddd36ae..0478f55 100644 --- a/index.html +++ b/index.html @@ -1,17 +1,21 @@
-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:
- +In the NX file format, the following must be followed:
These are the reference implementations of the NX format:
-Name | Type | Description |
---|---|---|
Magic | UInt8[4] | "PKG4" = {0x50, 0x4B, 0x47, 0x34} |
Magic | UInt8[4] | "PKG5" = {0x50, 0x4B, 0x47, 0x35} |
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. |
Node block offset | Node* | Offset to the start of the node block, which must 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 . |
Byte Array count | UInt32 | Total number of Byte Array entries in the file. |
Byte Array offset table offset | OffsetTable* | Offset to the byte array offset table, with the number of entries equal to the Byte Array count . This must be a multiple of 8. |
Metadata | UInt8[] | This field is ignored by parsers and can be used to store application-specific metadata. Note that this field can be of any length, by virtue of NX being offset-based. |
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).
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 must be in one contiguous block, which must be of size 20 * Number of nodes
. Node
s must be aligned to a 4-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 has an ID of 0, and should preferably be of 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 | UInt16 | 0 = None Parsers must ignore types they do not recognise. | ||
Data | Varies | This field is always 8 bytes. | ||
Type | Description | |||
0 | None | This field is ignored. | ||
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 . | ||
5 | Byte array | 32-bit unsigned byte array ID. Ignored if Byte Array 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 |
---|---|---|
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.
Each Byte Array
is assigned a zero-based unsigned 32-bit ID. Offsets to Byte Array
s are located in the byte array offset table. Byte arrays do not need to be in a contiguous block, though this is recommended. Byte Array
s must be aligned to an 8-byte boundary.
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. |
Length | UInt64 | Length, in bytes, of the Data field. |
Decoded length | UInt64 | Length, in bytes, of the byte array once decoded. |
Encoding | UInt16 | Encoding. 0 = None |
Metadata | UInt8[16] | This field is ignored by parsers and can be used to store application-specific metadata. |
Data | UInt8[] | Data, encoded using the method specified in Encoding . 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.
LZ4
algorithm can only compress up to 2,147,483,647 bytes. For larger sizes, LZ4 Frame
should be used.
+
+Offset tables are used to refer to String
s and byte arrays. String
offsets must be a multiple of 2. Byte Array
offsets must be a multiple of 8.
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 Array | UInt64[] | Sequential offset array; the first offset has ID 0, the second has ID 1, and so on. |
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.
This section recommends how Bitmaps and Audio files from WZs should be stored. This is also how the reference converter, WZ2NX, will store Bitmaps and MP3s.
+ +In a NX file containing Bitmaps and Audio files from WZs that follows this recommendation, the first 2 bytes of the Metadata
field of the Header
must have bits 15
, 10
, 6
and 0
set to 1
, that is, ORed with 0b1000010001000001 = {0x84, 0x41}
.
The 16-byte Metadata
field of the byte array containing a WZ bitmap must have the following format.
Name | Type | Description |
---|---|---|
Offset Array | UInt64[] | Sequential offset array; the first offset has ID 0, the second has ID 1, and so on. |
Magic | UInt8[4] | "WZBM" = {0x57, 0x5A, 0x42, 0x4D} |
Format | UInt32 | Format of the image. 0 = 32 bpp ARGB |
Width | UInt32 | Width of the image. |
Height | UInt32 | Height of the image. |
Acknowledgements:
+Note that since NX is a little-endian format, e.g. ARGB
is actually stored as BGRA
— it is treated as a 32-bit field, and not four octets.
If bitmap data is omitted in an NX file, the Node
s containing a bitmap must point to an empty byte array. Otherwise, the structure of the data within the byte array is as follows.
Name | Type | Description |
---|---|---|
Data | UInt8[] | Bitmap data. This byte array is Length bytes long. Length is specified in the Byte Array structure. |
The 16-byte Metadata
field of the byte array containing audio must have the following format.
Name | Type | Description |
---|---|---|
Magic | UInt8[4] | "WZAU" = {0x57, 0x5A, 0x41, 0x55} |
Duration | UInt32 | Audio duration, in milliseconds. |
Null | UInt8[8] | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} |
If audio data is omitted in an NX file, the Node
s containing audio must point to an empty byte array. Otherwise, the structure of the data within the byte array is as follows.
Name | Type | Description |
---|---|---|
Header length | UInt16 | Length of the header. |
Header | WAVEFORMATEX | Format header. This structure is Header length bytes long. |
Audio data | UInt8[] | Audio data. This byte array is Length − Header length − 2 bytes long. Length is specified in the Byte Array structure. |
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.
+
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.