Yaz0 Compression
From WADder Wiki
User Info
Yaz0 files are found in many places, including all .szs files and some .ash files (only ones that have been modified and compressed by end users. They can be decompressed with yaz0dec and compressed with yaz0enc Be warned, decompression is fast but compression can take hours, or at least a long time.
Technical Info
//header:
struct yaz0header {
u32 tag; //"Yaz0"
u32 size; //big endian, uncompressed data size
u8 zeroes [8];
}
//src points to the yaz0 source data (to the "real" source data, not at the header!)
//dst points to a buffer uncompressedSize bytes large (you get uncompressedSize from
//the second 4 bytes in the Yaz0 header).
void decode(u8* src, u8* dst, int uncompressedSize)
{
int srcPlace = 0, dstPlace = 0; //current read/write positions
u32 validBitCount = 0; //number of valid bits left in "code" byte
u8 currCodeByte;
while(dstPlace < uncompressedSize)
{
//read new "code" byte if the current one is used up
if(validBitCount == 0)
{
currCodeByte = src[srcPlace];
++srcPlace;
validBitCount = 8;
}
if((currCodeByte & 0x80) != 0)
{
//straight copy
dst[dstPlace] = src[srcPlace];
dstPlace++;
srcPlace++;
}
else
{
//RLE part
u8 byte1 = src[srcPlace];
u8 byte2 = src[srcPlace + 1];
srcPlace += 2;
u32 dist = ((byte1 & 0xF) << 8) | byte2;
u32 copySource = dstPlace - (dist + 1);
u32 numBytes = byte1 >> 4;
if(numBytes == 0)
{
numBytes = src[srcPlace] + 0x12;
srcPlace++;
}
else
numBytes += 2;
//copy run
for(int i = 0; i < numBytes; ++i)
{
dst[dstPlace] = dst[copySource];
copySource++;
dstPlace++;
}
}
//use next bit from "code" byte
currCodeByte <<= 1;
validBitCount-=1;
}
}
Code and info from: here.
