Westwood Compression Method 3

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

I called this method "compression 3", since there are 3 different commands to draw an image. Here I will explain that decompression method.

As I said before, we have 3 different commands; to find which command to execute, we have to read a byte from the file, and we must read it as a signed one:

Command 0: copy

1 signed byte [x|x|x|x|x|x|x|x] > 0

         count

command : Copy next _count_ pixels from source buffer to dest buffer.


Command 1: fill (1)

1 signed byte [0|0|0|0|0|0|0|0]


We have to read the next word (2 bytes) from src buffer (And swap bytes inside that word if we are working on a little endian machine (x86, for example)); that value will be "count". Then we read another byte, which is the "code". command: Fill _count_ pixels with _code_ color.

Command 2: fill (2)

1 signed byte [x|x|x|x|x|x|x|x] < 0

This byte, after we subtract it from 0, is "count". We then read another byte, which will be "code". command : Fill _count_ pixels with _code_ color.

Example decompression code

Notice that is actually uses Signed bytes for the command, the other code didn't and I think that was the main issue.

int cps_rle(unsigned char *src, unsigned char *dest, int len, bool swapWord)  // Source data, Dest Data, and source size.
{
 
  s8 com;   // s8 is a signed byte
  s16 count;// signed word or short.
  u8 col, debug;
  int DP, SP, i;
  DP=0;
  SP=0;
 
 
  while( SP< len)
  {
    com = src[SP];
    SP++;
    if (com > 0)  // Copy command
    {
        for(i=0;i<com; i++)
        {
            dest[DP] = src[SP];
            DP++; SP++;
        }
 
    }else
    {
        if(com < 0 ) //Command 2 < fill 2
        {
            count = -com;  // invert the count to make it a positive number.
 
        }else // Other wise, Command 1 Fill 1
        {
            // This fixes beholde1.cps for the amiga EOB1
            if( swapWord == true)
               count = (src[SP+1] * 256 )+ src[SP];
            else
               count = (src[SP] * 256 )+ src[SP+1];
 
            SP +=2;
 
        }
 
        col = src[SP];  // Grab the colour to fill with.
        SP++;
 
        for(i=0;i<count; i++)
        {
            dest[DP] = col;
            DP++;
        }
    }
 
  }
  return DP;  // This should be 64000.
}