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 */