home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_10_02
/
1002069a
< prev
next >
Wrap
Text File
|
1991-12-12
|
11KB
|
437 lines
/******************************************************
*
* file d:\lsu\cujhuff4.c
*
*****************************************************/
#include "d:\lsu\cujhuff.h"
/*
decode_compressed_file(...
This is the main function of the decompression
portion of the program.
*/
decode_compressed_file(input_file_name, output_file_name,
item_array, file_header)
char input_file_name[], output_file_name[];
struct item_struct item_array[];
struct header_struct *file_header;
{
char r[80];
int in_file_desc,
out_file_desc;
open_files_for_decode(input_file_name, output_file_name,
&in_file_desc, &out_file_desc);
input_file_header(file_header, in_file_desc);
convert_short_to_long(item_array, file_header);
decode_file_and_write_output(item_array,
in_file_desc,
out_file_desc);
close_decode_files(in_file_desc, out_file_desc);
} /* ends decode_compressed_file */
/*
open_files_for_decode(...
Open the input and output file.
*/
open_files_for_decode(in_file_name, out_file_name,
in_file_desc, out_file_desc)
char in_file_name[], out_file_name[];
int *in_file_desc, *out_file_desc;
{
int a ,b;
*out_file_desc = open(out_file_name, O_RDWR | O_CREAT | O_BINARY,
S_IWRITE);
*in_file_desc = open(in_file_name, O_RDWR | O_CREAT | O_BINARY,
S_IWRITE);
} /* ends open_files_for_decode */
/*
input_file_header(file_header, in_file_desc)
This function reads in the short header from the
front of the input file.
*/
input_file_header(file_header, in_file_desc)
int in_file_desc;
struct header_struct *file_header;
{
int bytes_read,
i;
char in_buffer[(sizeof(struct header_struct))],
*charptr,
name[80];
long position;
position = lseek(in_file_desc, 0L, 0);
bytes_read = my_read(in_file_desc, in_buffer,
sizeof(struct header_struct));
/*printf("\n\n> Read %d bytes using file header", bytes_read);*/
charptr = (char *)file_header;
for(i=0; i<((sizeof(struct header_struct))); i++)
*charptr++ = in_buffer[i];
} /* ends input_item_array */
/*
decode_file_and_write_output(...
This function takes in the packed bits, decodes them,
and puts the decoded characters out to the output
file.
*/
decode_file_and_write_output(item_array, in_file_desc, out_file_desc)
int in_file_desc, out_file_desc;
struct item_struct item_array[];
{
char output_buffer[IB_LENGTH],
r[80],
stream_buffer[CODE_LENGTH],
stream_of_bits[OB_LENGTH];
int bytes_read,
counter,
i,
in_disp,
not_finished,
output_pointer,
stream_pointer;
counter = 0;
output_pointer = 0;
stream_pointer = 0;
bytes_read = 0;
not_finished = 1;
for(i=0; i<IB_LENGTH; i++)
output_buffer[i] = OTHER;
while(not_finished){
read_in_buffer(in_file_desc, in_disp,
stream_of_bits, &bytes_read);
/*printf("\n> read %d bytes into stream of bits", bytes_read);*/
stream_pointer = 0;
if(bytes_read < OB_LENGTH)
not_finished = 0;
/* work through the stream_of_bits
you're finished when the stream_pointer
equals bytes_read * 8 bits per byte. */
while(stream_pointer < bytes_read*8){
convert_bits_to_char(stream_of_bits, stream_pointer,
stream_buffer);
decode_bits(stream_buffer, item_array,
output_buffer, &output_pointer,
&stream_pointer);
/*printf("\n> stream pointer = %d", stream_pointer);*/
/* if output_buffer fills up write it to disk */
if(output_pointer >= IB_LENGTH-10){
counter++;
printf("\n> Writing to output file-%d", counter);
write_out_buffer(out_file_desc,
output_buffer,
output_pointer);
output_pointer = 0;
} /* ends if output_pointer is too big */
} /* ends while stream_pointer < bytes_read*8 */
} /* ends while not_finished */
if(output_pointer > 0){
printf("\n> Writing to output file");
write_out_buffer(out_file_desc, output_buffer, output_pointer);
}
} /* ends decode_file_and_write_output */
/*
read_in_buffer(...
This function reads the input file and puts the packed
bits into the stream_of_bits.
*/
read_in_buffer(in_file_desc, in_disp, stream_of_bits,
bytes_read)
int *bytes_read, in_file_desc, in_disp;
char stream_of_bits[];
{
int b;
for(b=0; b<OB_LENGTH; b++)
stream_of_bits[b] = 0x00;
*bytes_read = read(in_file_desc, stream_of_bits, OB_LENGTH);
} /* ends read_in_buffer */
/*
convert_bits_to_char(...
This function takes the next CODE_LENGTH # of bits
from the stream_of_bits and converts them to bytes
having the value ONE or ZERO. These bytes are placed
into the stream_buffer. This makes it easier for
the decode_bits function to compare coded with the
packed bits.
*/
convert_bits_to_char(stream_of_bits, stream_pointer, stream_buffer)
char stream_of_bits[], stream_buffer[];
int stream_pointer;
{
char temp;
int bit_in_byte,
byte_in_buffer,
i,
j;
for(i=0; i<CODE_LENGTH; i++)
stream_buffer[i] = OTHER;
j = -1;
for(i=stream_pointer; i<stream_pointer+CODE_LENGTH; i++){
j++;
bit_in_byte = i % 8;
byte_in_buffer = i/8;
/* Test the bit by shifting it to the left
by the number bit_in_byte and then ANDing
it with 1000 0000 (128).
For this routine bit zero is the left most
or most significant bit of temp */
temp = stream_of_bits[byte_in_buffer];
temp = temp << bit_in_byte;
if((temp & SET_BIT_ZERO) != 0)
stream_buffer[j] = ONE;
else
stream_buffer[j] = ZERO;
} /* ends loop over i */
} /* ends convert_bits_to_char */
/*
decode_bits(...
Look at the converted bits from the packed file
compare them to the item_array.coded (start looking
at the top of the item_array since those occur most
frequently) and put the original character in the
output buffer
*/
decode_bits(stream_buffer, item_array,
output_buffer, output_pointer,
stream_pointer)
char output_buffer[], stream_buffer[];
int *output_pointer, *stream_pointer;
struct item_struct item_array[];
{
int found,
i,
j,
length_of_code,
not_finished;
char compare_string[CODE_LENGTH], r[80];
found = 0;
not_finished = 1;
j = 0;
/* search through the item_array looking for a coded array that
matches the characters in the stream_buffer
If you find it, increase the stream_pointer by
adding length_of_code to it. */
while(not_finished){
extract_code(item_array[j].coded, compare_string, &length_of_code);
if(strncmp(compare_string,
stream_buffer,
length_of_code) == 0){
found = 1;
not_finished = 0;
*stream_pointer = *stream_pointer + length_of_code;
} /* ends if strncmp */
else{ /* did not find the code so keep looking */
j++;
if(j > LENGTH){
not_finished = 0;
printf("\n\n\t> FAILURE - did not find code\n\n");
}
} /* ends else */
} /* ends while not_finished */
/* now put the decoded character in to the output_buffer */
if(found == 1){
output_buffer[*output_pointer] = item_array[j].character;
*output_pointer = *output_pointer + 1;
} /* ends if found == 1 */
} /* ends decode_bits */
/*
extract_code(...
Pull the code out of item_array[x].coded,
put it into compare_string, and put the
length of the code into length.
*/
extract_code(coded, compare_string, length_of_code)
char coded[], compare_string[];
int *length_of_code;
{
int i, j, k, m, not_finished;
/* clear the compare_string */
for(k=0; k<CODE_LENGTH; k++)
compare_string[k] = OTHER;
not_finished = 1;
*length_of_code = 0;
i = CODE_LENGTH-1;
j = 0;
/* Start at the end of coded and search back until you
run out of code i.e. you hit a OTHER. */
while(not_finished){
if(coded[i] != OTHER){
i--;
j++;
}
else
not_finished = 0;
} /* ends while not_finished */
/* adjust value of i */
i++;
/* Copy the coded to the compare_string */
*length_of_code = j;
m = 0;
for(k=i; k<CODE_LENGTH; k++){
compare_string[m] = coded[k];
m++;
}
} /* ends extract_code */
/*
write_out_buffer(...
Write the output_buffer to file.
*/
write_out_buffer(out_file_desc, output_buffer, output_pointer)
char output_buffer[];
int out_file_desc, output_pointer;
{
int bytes_written;
bytes_written =
my_write(out_file_desc, output_buffer, output_pointer);
} /* ends write_out_buffer */
/*
close_decode_files(...
Close the files.
*/
close_decode_files(in_file_desc, out_file_desc)
int in_file_desc, out_file_desc;
{
close(in_file_desc);
close(out_file_desc);
} /* ends close_decode_files */
/* End of File */