Yaz0 (Compression)

From Wexos's Wiki
Revision as of 18:11, 1 May 2024 by Wexos (talk | contribs) (Imported from avsys wiki)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Yaz0 is a RLE compression (run-length encoding). It has been used in lots of games and platforms since its introduction on the Nintendo 64 console. It has been used in games like Mario Kart Wii, Super Mario Odyssey and many more. Note that Yaz0-compressed files are not affected by the endianness of the CPU. All fields will always be stored as big endian.

Header

A Yaz0-compressed file starts with the following header:

Offset Type Description
0x00 String File magic. Always Yaz0 in ASCII.
0x04 UInt32 Size of the uncompressed data in bytes.
0x08 UInt32 Reserved for special use within a game. Super Mario Odyssey uses this field as the file alignment.
0x0C UInt32 Reserved for special use within a game. Only seen as 0.

Chunks

The data is then stored into different chunks. Each chunk starts with a chunk header, which consist of a Byte. It obviously contains 8 bits, and each bit specifies the mode for one copy command, meaning there will be 8 copy commands per chunk. The MSB bit is the first command, and the LSB bit corresponds to the last command. Chunks are read until the size of the output is the same as specified in the header.

Direct Copy

If a bit is 1, then one byte is copied directly from the input to the output data.

Run-length

If a bit is 0, then this group will contain run-length encoded data. In order for this to work, a UInt16 (B) has to be read from the input. The data is copied from the output, at a specific address, to the output. To calculate the address to copy the data from, perform this calculation:

CopyOffset = CurrentOffset - (A & 0xFFF) - 1

Then the number of bytes to copy needs to be calculated. The run-length command supports two different size mode, and first the following calculation is performed:

B = (A >> 12) & 0b1111

If B is zero, then another byte is read. The number of bytes to copy is then calculated by adding 0x12 to the read byte. If B is not zero, then the number of bytes to copy is by adding 2 to B.