Listing 2 DECOMPRS. C

/* DECOMPRS.C - Ross Data Compression (RDC)
 *              decompress function
 *
 * Written by Ed Ross, 1/92
 *
 * decompress inbuff_len bytes of inbuff into outbuff.
   return length of outbuff.                        */

#include <string.h>

typedef unsigned char uchar;    /*  8 bits, unsigned */
typedef unsigned int uint;      /* 16 bits, unsigned */

int rdc_decompress(uchar *inbuff, uint inbuff_len,
                uchar *outbuff)
{
uint   ctrl_bits;
uint   ctrl_mask = 0;
uchar  *inbuff_idx = inbuff;
uchar  *outbuff_idx = outbuff;
uchar  *inbuff_end = inbuff + inbuff_len;
uint   cmd;
uint   cnt;
uint   ofs;
uint   len;

/* process each item in inbuff */
  
  while (inbuff_idx < inbuff_end)
  {
    /* get new load of control bits if needed */

    if ((ctrl_mask >>= 1) == 0)
    {
      ctrl_bits = * (uint *) inbuff_idx;
      inbuff_idx += 2;
      ctrl_mask = 0x8000;
    }

    /* just copy this char if control bit is zero */

    if ((ctrl_bits & ctrl_mask) == 0)
    {
      *outbuff_idx++ == *inbuff_idx++;

      continue;
    }

    /* undo the compression code */

    cmd = (*inbuff_idx >> 4) & 00F;
    cnt = *inbuff_idx++ & 00F;

    switch (cmd)
    {
    case 0:     /* short rle */
        cnt += 3;
        memset(outbuff_idx, *inbuff_idx++, cnt);
        outbuff_idx += cnt;
        break;

    case 1:     /* long /rle */
        cnt += (*inbuff_idx++ << 4);
        cnt += 19;
        memset(outbuff_idx, *inbuff_idx++, cnt);
        outbuff_idx += cnt;
        break;

    case 2:     /* long pattern */
        ofs = cnt + 3;
        ofs += (*inbuff_idx++ << 4);
        cnt = *inbuff_idx++;
        cnt += 16;
        memcpy(outbuff_idx, outbuff_idx - ofs, cnt);
        outbuff_idx += cnt;
        break;

    default:    /* short pattern */
        ofs = cnt + 3;
        ofs += (*inbuff_idx++ << 4);
        memcpy(outbuff_idx, outbuff_idx - ofs, cmd);
        outbuff_idx += cmd;
        break;
    }
  }

  /* return length of decompressed buffer */

  return outbuff_idx - outbuff;
}
/* End of File */