/* encode.c */ /* Program for Lempel-Ziv compression */ #include #include #include #include #include #include "lz.h" /* contains global constants and datastructures*/ #include "encode.h" /* defines the ADT for encoding */ #include "bits.h" #include "dict.h" /*-------------------------------------------------------------------*/ int main(int argc, char *argv[]) { FILE *f_in, *f_out; encode_data_type encode_data; double start_time, end_time; char input_file_name[100],output_file_name[100]; int BPC; /*bits per code*/ /* From the standard input, read the name of input and output file */ /* names. Encode the input file and store the compressed data into */ /* output file */ /* read the input and output file names */ printf("ENTER THE FILE NAME TO BE COMPRESSED "); scanf("%s",input_file_name); printf("\nENTER THE OUTPUT FILE NAME ",input_file_name); scanf("%s",output_file_name); printf("\nBITS PER CODE TO BE USED (SHOULD BE BETWEEN 8 and 31) "); scanf("%d",&BPC); printf("\n"); /* open the input file for reading */ f_in = fopen(input_file_name,"rb"); assert(f_in != NULL); /* if error in opening file, exit */ /* open the output file for writing */ f_out = fopen(output_file_name,"wb"); assert(f_out != NULL); /* start clock */ start_time = clock(); /* encode the data */ encode_data = LZencode(f_in, f_out,BPC); /* end clock */ end_time = clock(); printf("Input Size = %6d bytes\n", encode_data.input_size); printf("Output Size = %6d bytes\n", encode_data.output_size); printf("Compression Ratio = %f\n", (float) encode_data.input_size/encode_data.output_size); printf("Total time = %f secs\n",(end_time-start_time)/CLOCKS_PER_SEC); /* close the files*/ fclose(f_in); fclose(f_out); return(1); } /* end of main */ /*-----------------------------------------------------------------------*/ encode_data_type LZencode(FILE *in, FILE *out, int BPC) { /* encode the data */ /* return the statistics in a variable of type enc_data_type */ encode_data_type enc; /* in this record the statistics */ char matched_string[MAX_MATCH_LENGTH]; /* stores the string which is to be matched */ /* in the dictionary */ int bytes_read ; float output_size = 0.0; int finished; /* used for detecting EOF */ DICT_TYPE dict; /* initialize enc */ enc.input_size = enc.output_size = 0; /* initialize dictionary */ dict = init_dict(BPC); /* Now get the longest match from the input */ /* the get_longest_match function returns the */ /* longest match along with the next character */ /* in the matched_string variable. It returns 0 */ /* in the finished variable if it exhaisted the */ /* while trying to find the longest match */ while((bytes_read = get_longest_match(in,matched_string,&finished,dict)) > 0) { int length; /* increase the number of bytes read */ enc.input_size += bytes_read; /* add this string to the dictionary if we did not encounter */ /* the EOF. If we did encounter EOF, then this string is */ /* already in the dictionary */ if (!(finished)) { insert_dict(matched_string,dict); /* get the code of the matched string minus the last */ /* character */ length = strlen(matched_string); matched_string[length-1] = '\0'; } /* write its code in the output file */ putCode(dict_lookup(matched_string,dict),BPC,out); output_size += ((float) BPC)/8.0; } /* end while */ /* LAST_CODE is a code which is used to mark the end of file */ /* in the compresses file so that the decoding algorithm will*/ /* know when to end */ putCode(LAST_CODE,BPC,out); enc.output_size = (int) ceil(output_size); return enc; } /*-------------------------------------------------------------------*/