home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_10_10
/
1010118a
< prev
next >
Wrap
Text File
|
1992-08-13
|
4KB
|
192 lines
/*
* Listing 3
*
* TESTRDC.C - Ross Data Compression (RDC)
* test driver program
*
* Written by Ed Ross, 1/92
*
* This program will compress or decompress a file
* using RDC data compression.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#define HASH_LEN 4096 /* # hash table entries */
#define BUFF_LEN 16384 /* size of disk io buffer */
typedef unsigned char uchar; /* 8 bits, unsigned */
typedef unsigned int uint; /* 16 bits, unsigned */
uchar *hash_tbl[HASH_LEN]; /* hash table */
uchar inbuff[BUFF_LEN]; /* io buffers */
uchar outbuff[BUFF_LEN];
FILE *infile, *outfile; /* FILE access */
char usage[] =
"\nUsage: TESTRDC <c | d> <infile> <outfile>\n"
" c = compress infile to outfile\n"
" d = decompress infile to outfile\n";
/* compression function prototypes */
int rdc_compress(uchar *inbuff, uint inbuff_len,
uchar *outbuff,
uchar *hash_tbl[], uint hash_len);
int rdc_decompress(uchar *inbuff, uint inbuff_len,
uchar *outbuff);
/*--- post error message and exit ---*/
void err_exit(char *fmt, ...)
{
va_list v;
va_start(v, fmt);
vfprintf(stderr, fmt, v);
va_end(v);
exit(1);
}
/*--- compress infile to outfile ---*/
void do_compress(void)
{
int bytes_read;
int compress_len;
/* read infile BUFF_LEN bytes at a time */
while ((bytes_read =
fread(inbuff, 1, BUFF_LEN, infile)) > 0)
{
/* compress this load of bytes */
compress_len = rdc_compress(inbuff, bytes_read,
outbuff, hash_tbl, HASH_LEN);
/* write length of compressed buffer */
if (fwrite(&compress_len, sizeof(int),
1, outfile) != 1)
err_exit("Error writing block length.\n");
/* check for negative length indicating the
buffer could not be compressed */
if (compress_len < 0)
compress_len = 0 - compress_len;
/* write the buffer */
if (fwrite(outbuff, compress_len, 1, outfile) != 1)
err_exit("Error writing compressed data.\n");
/* we're done if less than full buffer was read */
if (bytes_read != BUFF_LEN)
break;
}
/* add trailer to indicate end of file */
compress_len = 0;
if (fwrite(&compress_len, sizeof(int),
1, outfile) != 1)
err_exit("Error writing trailer.\n");
}
/*--- decompress infile to outfile ---*/
void do_decompress(void)
{
int block_len;
int decomp_len;
/* read infile BUFF_LEN bytes at a time */
for (;;)
{
if (fread(&block_len, sizeof(int), 1, infile) != 1)
err_exit("Can't read block length.\n");
/* check for end-of-file flag */
if (block_len == 0)
return;
if (block_len < 0) /* copy uncompressed chars */
{
decomp_len = 0 - block_len;
if (fread(outbuff, decomp_len, 1, infile) != 1)
err_exit("Can't read uncompressed block.\n");
}
else /* decompress this buffer */
{
if (fread(inbuff, block_len, 1, infile) != 1)
err_exit("Can't read compressed block.\n");
decomp_len = rdc_decompress(inbuff, block_len,
outbuff);
}
/* and write this buffer outfile */
if (fwrite(outbuff, decomp_len, 1, outfile) != 1)
err_exit("Error writing uncompressed data.\n");
}
}
/*--- main ---*/
void main(int argc, char *argv[])
{
/* check command line */
if (argc != 4)
err_exit(usage);
/* open the files */
if ((infile = fopen(argv[2], "rb")) == NULL)
err_exit("Can't open %s for input.\n", argv[2]);
if ((outfile = fopen(argv[3], "wb")) == NULL)
err_exit("Can't open %s for output.\n", argv[3]);
/* dispatch to requested function */
switch (argv[1][0])
{
case 'c':
case 'C':
do_compress();
break;
case 'd':
case 'D':
do_decompress();
break;
default:
err_exit(usage);
}
/* and close the files */
if (fclose(infile))
err_exit("Error closing input file.\n");
if (fclose(outfile))
err_exit("Error closing output file.\n");
}