home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_10 / 1010116a < prev    next >
Text File  |  1992-08-13  |  2KB  |  97 lines

  1. /*
  2.  * Listing 2
  3.  *
  4.  * DECOMPRS.C - Ross Data Compression (RDC)
  5.  *              decompress function
  6.  *
  7.  * Written by Ed Ross, 1/92
  8.  *
  9.  * decompress inbuff_len bytes of inbuff into outbuff.
  10.  *
  11.  * return length of outbuff.
  12.  *
  13. */
  14.  
  15. #include <string.h>
  16.  
  17. typedef unsigned char uchar;    /*  8 bits, unsigned */
  18. typedef unsigned int  uint;     /* 16 bits, unsigned */
  19.  
  20. int rdc_decompress(uchar *inbuff, uint inbuff_len,
  21.                    uchar *outbuff)
  22. {
  23. uint    ctrl_bits;
  24. uint    ctrl_mask = 0;
  25. uchar   *inbuff_idx = inbuff;
  26. uchar   *outbuff_idx = outbuff;
  27. uchar   *inbuff_end = inbuff + inbuff_len;
  28. uint    cmd;
  29. uint    cnt;
  30. uint    ofs;
  31. uint    len;
  32.  
  33.   /* process each item in inbuff */
  34.  
  35.   while (inbuff_idx < inbuff_end)
  36.   {
  37.     /* get new load of control bits if needed */
  38.  
  39.     if ((ctrl_mask >>= 1) == 0)
  40.     {
  41.       ctrl_bits = * (uint *) inbuff_idx;
  42.       inbuff_idx += 2;
  43.       ctrl_mask = 0x8000;
  44.     }
  45.  
  46.     /* just copy this char if control bit is zero */
  47.  
  48.     if ((ctrl_bits & ctrl_mask) == 0)
  49.     {
  50.       *outbuff_idx++ = *inbuff_idx++;
  51.  
  52.       continue;
  53.     }
  54.  
  55.     /* undo the compression code */
  56.  
  57.     cmd = (*inbuff_idx >> 4) & 0x0F;
  58.     cnt = *inbuff_idx++ & 0x0F;
  59.  
  60.     switch (cmd)
  61.     {
  62.     case 0:     /* short rle */
  63.          cnt += 3;
  64.          memset(outbuff_idx, *inbuff_idx++, cnt);
  65.          outbuff_idx += cnt;
  66.          break;
  67.  
  68.     case 1:     /* long rle */
  69.          cnt += (*inbuff_idx++ << 4);
  70.          cnt += 19;
  71.          memset(outbuff_idx, *inbuff_idx++, cnt);
  72.          outbuff_idx += cnt;
  73.          break;
  74.  
  75.     case 2:     /* long pattern */
  76.          ofs = cnt + 3;
  77.          ofs += (*inbuff_idx++ << 4);
  78.          cnt = *inbuff_idx++;
  79.          cnt += 16;
  80.          memcpy(outbuff_idx, outbuff_idx - ofs, cnt);
  81.          outbuff_idx += cnt;
  82.          break;
  83.  
  84.     default:    /* short pattern */
  85.          ofs = cnt + 3;
  86.          ofs += (*inbuff_idx++ << 4);
  87.          memcpy(outbuff_idx, outbuff_idx - ofs, cmd);
  88.          outbuff_idx += cmd;
  89.          break;
  90.     }
  91.   }
  92.  
  93.   /* return length of decompressed buffer */
  94.  
  95.   return outbuff_idx - outbuff;
  96. }
  97.