Saturday at 10:54 AM2 days Supporter HiNeeded help to figure out the compression algorithmThe only thing I knew is the file always start with SNK0 string and there's uncompressed size field at offset 0x0cspeaker.snk.zip
9 hours ago9 hr Localization SNK0 is a cut-down deflate: LZ77 with a 32 KB window and one Huffman code per block. The literal/length alphabet and the length and distance tables are the same as deflate, but the block header is much simpler and distances aren't Huffman coded.not sure what the u32 at 0x04 is, but it doesn't seem needed for decompressionAttached a script to decompress the file into .bin formatUsagepython snk_decompress.py speaker.snk writes speaker.snk.bin python snk_decompress.py speaker.snk speaker.bin writes speaker.binFile layoutEverything is little endian. Nothing inside the bitstream is aligned: each block starts at the bit right after the previous block ends.header 0x10 bytes bitstream blocks, until the output reaches the decompressed size padding zero bits to the end of the byte, then zero bytesHeader0x00 char[4] magic "SNK0" 0x04 u32 unknown (see Notes) 0x08 u32 CRC32 of the decompressed data (standard zlib / PKZIP CRC32) 0x0C u32 decompressed size 0x10 bitstream starts hereDifferences from deflateNo zlib/gzip wrapper and no 3-bit block header. Every block works like a dynamic block.The code lengths are stored raw as nibbles, instead of HLIT/HDIST/HCLEN and the run-length coded code length alphabet.There's no distance tree. The distance code is always getbits(5).No final-block flag. The decompressed size in the header says when to stop.NotesThe sample has 10 blocks of about 14.5 KB compressed each (115k to 125k bits), apart from a short last one. The decoder doesn't care where blocks are split.Code lengths in the sample go up to 14 bits. The 4-bit field allows up to 15.the sample (speaker.snk) itself is a PS2 texture: a 0x80 byte header, a 256 colour RGBA palette at 0x80 (CSM1 order, alpha 0 to 0x7F) and 512x512 swizzled 8-bit pixels at 0x480. In the header, 0x00 = 0x80 (palette offset), 0x04 = 0x480 (pixel offset), 0x2C = 0x13 (PSMT8) and 0x2E / 0x30 = 512 / 512. snk_decompress.py
Create an account or sign in to comment