Team17 compression

From Worms Knowledge Base

Jump to: navigation, search

The majority of Team17's unique graphic file formats are stored with their image data compressed into 1 or more data streams. The exact compression algorithm used has not been made public knowledge.

History

It is presumed that Fudge Boy was the first one to reverse engineer Team17's compression algorithm. He used this knowledge to create two very popular and important programs, the WA directory editor and The Fiddler. However, he never released his information about Team17's compression to the public.

Many years passed before it was again reverse engineered, this time by acme_pjz. On June 12, 2008 he released his findings to the public. Very shortly thereafter, Pisto revised acme_pjz's decompression code and re-released the improvements to the public.

Decompression Routine

public static bool Decompress(BinaryReader b, ref byte[] dStream)
{
    int cmd;
    int output = 0;  //offset of next write
    while ((cmd = b.ReadByte()) != -1)
    {  //read a byte
        if ((cmd & 0x80) == 0) {  //command: 1 byte (color)
            dStream[output++] = (byte)cmd;
        } else {
            int arg1 = (cmd >> 3) & 0xF;  //arg1=bits 2-5
            int arg2 = b.ReadByte();
            if (arg2 == -1)
                return false;
            arg2 = ((cmd << 8) | arg2) & 0x7FF;  //arg2=bits 6-16
            if (arg1 == 0) {
                if (arg2 == 0)  //command: 0x80 0x00
                    return false;
                int arg3 = b.ReadByte();
                if (arg3 == -1)
                    return false;
                output = CopyData(output, arg2, arg3 + 18, ref dStream);  //command: 3 bytes
            } else {
                output = CopyData(output, arg2 + 1, arg1 + 2, ref dStream);  //command: 2 bytes
            }
        }
    }
    return true;
}

public static int CopyData(int dOffset, int cOffset, int Repeat, ref byte[] dStream)
{
    for (; Repeat > 0; Repeat--)
        dStream[dOffset] = dStream[dOffset++ - cOffset];
    return dOffset;
}
Personal tools