Yaz0 Compression

From WADder Wiki

Jump to: navigation, search

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.

Personal tools