Westwood XOR Delta

From ModdingWiki
Jump to: navigation, search
Westwood XOR Delta
Format typeCompression algorithm
TypeStream
I/O unit size1-bit
Games

The Westwood XOR Delta compression is a format used in Westwood Studios's WSA animation file format. It is commonly known as "Format 40" because it is usually indicated in file headers with byte value 0x40.

Explanation

The format is designed to be used when there are only minor differences between an image and a following one, and is often used for large animations. Animations in this format, as the name says, contain differences between frames to be xor-ed over each other.

Like Westwood LCW, the format is comparable to Code-type RLE, with byte commands containing manipulation instructions, but while RLE contains repeat and copy commands, the XOR Delta commands, which are applied to a second set of existing data, will either skip over a given number of bytes to leave them unmodified, or will apply an XOR operation on them, either using a single fixed value, or using a following range of bytes from the XOR commands buffer.

For the purpose of this explanation, the XOR data itself is in Source, and the image that the XOR needs to be applied to is already loaded in the Dest buffer. At the beginning of the operation, the pointers for both Source and Dest are set to the start of their respective buffers.

Command 1: Short skip

This command is 1 byte long.

              byte
 +---+---+---+---+---+---+---+---+
 | 1 |   |   |   |   |   |   |   |
 +---+---+---+---+---+---+---+---+
     \___________________________/
                  |
                Count

Skip Count bytes in Dest (move the pointer forward).

Command 2: Long skip

This command is 3 bytes long.

             byte                           word
 +---+---+---+---+---+---+---+---+  +---+-----+-------+
 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |  | 0 | ... |       |
 +---+---+---+---+---+---+---+---+  +---+-----+-------+
                                        \_____________/
                                               |
                                             Count

Skip Count bytes.

Command 3: Long XOR

This command is 3 bytes long.

               byte                              word
 +---+---+---+---+---+---+---+---+  +---+---+-----+-------+
 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |  | 1 | 0 | ... |       |
 +---+---+---+---+---+---+---+---+  +---+---+-----+-------+
                                            \_____________/
                                                  |
                                                Count

Xor next Count bytes. That means xor Count bytes from Source with bytes in Dest.

Command 4: XOR with Value

This command is 4 bytes long.

             byte                               word           byte
 +---+---+---+---+---+---+---+---+  +---+---+-----+-------+  +-------+
 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |  | 1 | 1 | ... |       |  |       |
 +---+---+---+---+---+---+---+---+  +---+---+-----+-------+  +-------+
                                            \_____________/    Value
                                                  |
                                                Count

Xor next Count bytes in Dest with Value.

Command 5: Short XOR

This command is 1 byte long.

              byte
 +---+---+---+---+---+---+---+---+
 | 0 |   |   |   |   |   |   |   |
 +---+---+---+---+---+---+---+---+
     \___________________________/
                  |
                Count

Xor next Count bytes from Source with Dest.

Command 6: Long XOR with Value

This command is 3 bytes long.

             byte                     byte       byte
 +---+---+---+---+---+---+---+---+  +-------+  +-------+
 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |  |       |  |       |
 +---+---+---+---+---+---+---+---+  +-------+  +-------+
                                      Count      Value

Xor next Count bytes with Value.

All images end with a 80h 00h 00h command.

I think these are all the commands, but there might be some other. If you find anything new, please add them.

Code

Here's some code:

DP = destination pointer
SP = source pointer
Source is buffer containing the XOR Delta data
Dest is the buffer containing the image over which the second has to be xor-ed

  SP:=0;
  DP:=0;
  repeat
    Com:=Source[SP];
    Inc(SP);
 
    if (Com and $80)<>0 then {if bit 7 set}
    begin
      if Com<>$80 then  {small skip command (1)}
      begin
        Count:=Com and $7F;
        Inc(DP,Count);
      end
      else  {Big commands}
      begin
        Count:=Word(Source[SP]);
        if Count=0 then break;
        Inc(SP,2);
 
        Tc:=(Count and $C000) shr 14;  {Tc=two topmost bits of count}
 
        case Tc of
          0,1 : begin  {Big skip (2)}
                  Inc(DP,Count);
                end;
          2 : begin {big xor (3)}
                Count:=Count and $3FFF;
                for i:=1 to Count do
                begin
                  Dest[DP]:=Dest[DP] xor Source[SP];
                  Inc(DP);
                  Inc(SP);
                end;
              end;
          3 : begin  {big repeated xor (4)}
                Count:=Count and $3FFF;
                b:=Source[SP];
                Inc(SP);
                for i:=1 to Count do
                begin
                  Dest[DP]:=Dest[DP] xor b;
                  Inc(DP);
                end;
              end;
        end;
      end;
    end else  {xor command}
    begin
      Count:=Com;
      if Count=0 then
      begin {repeated xor (6)}
        Count:=Source[SP];
        Inc(SP);
        b:=Source[SP];
        Inc(SP);
        for i:=1 to Count do
        begin
          Dest[DP]:=Dest[DP] xor b;
          Inc(DP);
        end;
      end else  {copy xor (5)}
        for i:=1 to Count do
        begin
          Dest[DP]:=Dest[DP] xor Source[SP];
          Inc(DP);
          Inc(SP);
        end;
    end;
  until false;