📄 coding.c
字号:
#include <stdio.h>
#include <stdlib.h>
#define MATRIX_INDEX 53/*length of probility matrix */
#define PACIFIER_COUNT 2047/*unsigned int totals[NO_WORDS+1]; */
/*
* These four variables define the current state of the arithmetic
* coder/decoder. They are assumed to be 16 bits long. Note that
* by declaring them as ints, they will actually be 16 bits
* on most 80X86 and 680X0 machines, as well as VAXen.
*/
static unsigned short int code; /* The present input code value */
static unsigned short int low; /* Start of the current code range */
static unsigned short int high; /* End of the current code range */
long underflow_bits; /* Number of underflow bits pending */
static unsigned short int prob_matrix[MATRIX_INDEX]; /*probility matrix*/
/* this is the header file for arith.c, with shorter integer precision */
typedef struct bit_file {
FILE *file;
unsigned char mask;
int rack;
int pacifier_counter;
} BIT_FILE;
/*
* The SYMBOL structure is what is used to define a symbol in
* arithmetic coding terms. A symbol is defined as a range between
* 0 and 1. Since we are using integer math, instead of using 0 and 1
* as our end points, we have an integer scale. The low_count and
* high_count define where the symbol falls in the range.
*/
typedef struct {
unsigned short int low_count;
unsigned short int high_count;
unsigned short int scale;
} SYMBOL;
unsigned long int prob_function(FILE *fp);
BIT_FILE *OpenOutputBitFile( char *name );
void OutputBit( BIT_FILE *bit_file, int bit );
void CloseOutputBitFile( BIT_FILE *bit_file );
void initialize_arithmetic_encoder( void );
int encode_symbol( BIT_FILE *stream, SYMBOL *s );
void flush_arithmetic_encoder( BIT_FILE *stream );
int convert_character_to_index( char character_in);
char convert_index_to_character( int index_in);
BIT_FILE *OpenInputBitFile( char *name );
void CloseInputBitFile( BIT_FILE *bit_file );
int InputBit( BIT_FILE *bit_file );
short int get_current_count( SYMBOL *s );
int convert_symbol_to_int(short int count, SYMBOL *s, short int *totals, int num_codeword);
int initialize_arithmetic_decoder( BIT_FILE *stream );
int remove_symbol_from_stream( BIT_FILE *stream, SYMBOL *s );
int arith_encode(BIT_FILE *OutBitp, unsigned short int *esti_prob, int num_codeword, int cur_index);
int arith_decode(BIT_FILE *InBitp, SYMBOL *cs, unsigned short int *esti_prob, int num_codeword, short int *totals);
int main()
{
/*the variable in the encoder program*/
int current_index, temp;
char current_character;
unsigned long int cnt_outbits = 0;
FILE *source_file;
BIT_FILE *compress_bitfile;
/*the variable in the decoder program*/
int decoder_index;
char decoder_character;
unsigned long int decompress_out_cnt;
unsigned long int tatals_of_characters;
short int *tatals_list;
FILE *decode_outfile;
BIT_FILE *decompress_bitfile;
SYMBOL *parameter_temp;
if( (parameter_temp = ( SYMBOL* )calloc( 1, sizeof( SYMBOL ))) == NULL){
printf("parameter_temp made error\n");
exit(1);
}
/*getting the probility table*/
if( (source_file = fopen("test.TXT", "rb")) == NULL){
printf("open file error\n");
exit(0);
}
tatals_of_characters = prob_function(source_file);
/*encoder program start*/
compress_bitfile = OpenOutputBitFile("compress.txt");
initialize_arithmetic_encoder();
fseek(source_file, 0, 0); //重定位流上的文件指针//
while(!feof(source_file)){
current_character = fgetc(source_file);
current_index = convert_character_to_index( current_character);
temp = arith_encode(compress_bitfile, prob_matrix, MATRIX_INDEX, current_index);
cnt_outbits += temp;
}
flush_arithmetic_encoder(compress_bitfile);//处理编码结束时的有效概率//
printf("The compressed file has %lu bits!\n", cnt_outbits);
CloseOutputBitFile(compress_bitfile);
fclose(source_file);
/*encoder program finish*/
/*Decoder program start*/
if( (decode_outfile = fopen( "decompress.txt", "wb" )) == NULL){
printf("open decompress_file for writing error\n");
exit(1);}
if( (tatals_list = ( short int * )calloc( 53, sizeof( short int ))) == NULL){
printf("tatal_list made error\n");
exit(1);
}
decompress_bitfile = OpenInputBitFile( "compress.txt" );
initialize_arithmetic_decoder( decompress_bitfile );
for( decompress_out_cnt = 0; decompress_out_cnt < tatals_of_characters; decompress_out_cnt++ )
{
decoder_index = arith_decode( decompress_bitfile, parameter_temp, prob_matrix, MATRIX_INDEX, tatals_list);
decoder_character = convert_index_to_character( decoder_index);
fputc(decoder_character, decode_outfile);
}
printf("The decompress file has %ld characters!\n", decompress_out_cnt);
CloseInputBitFile( decompress_bitfile);
parameter_temp=NULL;
tatals_list=NULL;
//free(tatals_list);
fclose(decode_outfile);
/*decoder program finish.*/
}
/*using the function to get the matrix of the source file*/
unsigned long int prob_function( FILE *fp)
{
int i;
unsigned long int temp_matrix[MATRIX_INDEX];
unsigned long int cnt = 0;
char s;
for(i = 0; i < MATRIX_INDEX; i++){
temp_matrix[i] = 0;
}
while(!feof(fp)){
s = fgetc(fp);
switch(s){
case'A': temp_matrix[0] += 1; break;
case'B': temp_matrix[1] += 1; break;
case'C': temp_matrix[2] += 1; break;
case'D': temp_matrix[3] += 1; break;
case'E': temp_matrix[4] += 1; break;
case'F': temp_matrix[5] += 1; break;
case'G': temp_matrix[6] += 1; break;
case'H': temp_matrix[7] += 1; break;
case'I': temp_matrix[8] += 1; break;
case'J': temp_matrix[9] += 1; break;
case'K': temp_matrix[10] += 1; break;
case'L': temp_matrix[11] += 1; break;
case'M': temp_matrix[12] += 1; break;
case'N': temp_matrix[13] += 1; break;
case'O': temp_matrix[14] += 1; break;
case'P': temp_matrix[15] += 1; break;
case'Q': temp_matrix[16] += 1; break;
case'R': temp_matrix[17] += 1; break;
case'S': temp_matrix[18] += 1; break;
case'T': temp_matrix[19] += 1; break;
case'U': temp_matrix[20] += 1; break;
case'V': temp_matrix[21] += 1; break;
case'W': temp_matrix[22] += 1; break;
case'X': temp_matrix[23] += 1; break;
case'Y': temp_matrix[24] += 1; break;
case'Z': temp_matrix[25] += 1; break;
case' ': temp_matrix[26] += 1; break;
case'a': temp_matrix[27] += 1; break;
case'b': temp_matrix[28] += 1; break;
case'c': temp_matrix[29] += 1; break;
case'd': temp_matrix[30] += 1; break;
case'e': temp_matrix[31] += 1; break;
case'f': temp_matrix[32] += 1; break;
case'g': temp_matrix[33] += 1; break;
case'h': temp_matrix[34] += 1; break;
case'i': temp_matrix[35] += 1; break;
case'j': temp_matrix[36] += 1; break;
case'k': temp_matrix[37] += 1; break;
case'l': temp_matrix[38] += 1; break;
case'm': temp_matrix[39] += 1; break;
case'n': temp_matrix[40] += 1; break;
case'o': temp_matrix[41] += 1; break;
case'p': temp_matrix[42] += 1; break;
case'q': temp_matrix[43] += 1; break;
case'r': temp_matrix[44] += 1; break;
case's': temp_matrix[45] += 1; break;
case't': temp_matrix[46] += 1; break;
case'u': temp_matrix[47] += 1; break;
case'v': temp_matrix[48] += 1; break;
case'w': temp_matrix[49] += 1; break;
case'x': temp_matrix[50] += 1; break;
case'y': temp_matrix[51] += 1; break;
case'z': temp_matrix[52] += 1; break;
default: if(s!=EOF){
printf(" probility fuction error\n");
}
}
}
for(i = 0; i < MATRIX_INDEX; i++){
if( temp_matrix[i] >= 0xFFFFFFF0 ){
printf("FLOW%d,error\n",i);
}
cnt += temp_matrix[i];
prob_matrix[i] = temp_matrix[i]/100;
}
printf("the source file has %lu characters!\n",cnt);
return(cnt);
}
/*Using the fuction to convert the character from the source file to the index of the probility vector,*
*when the encoder program work*****************************/
int convert_character_to_index( char character_in)
{
int index;
switch(character_in){
case'A': index = 0;break;
case'B': index = 1; break;
case'C': index = 2; break;
case'D': index = 3; break;
case'E': index = 4; break;
case'F': index = 5; break;
case'G': index = 6; break;
case'H': index = 7; break;
case'I': index = 8; break;
case'J': index = 9; break;
case'K': index = 10; break;
case'L': index = 11; break;
case'M': index = 12; break;
case'N': index = 13; break;
case'O': index = 14; break;
case'P': index = 15; break;
case'Q': index = 16; break;
case'R': index = 17; break;
case'S': index = 18; break;
case'T': index = 19; break;
case'U': index = 20; break;
case'V': index = 21; break;
case'W': index = 22; break;
case'X': index = 23; break;
case'Y': index = 24; break;
case'Z': index = 25; break;
case' ': index = 26; break;
case'a': index = 27;break;
case'b': index = 28; break;
case'c': index = 29; break;
case'd': index = 30; break;
case'e': index = 31; break;
case'f': index = 32; break;
case'g': index = 33; break;
case'h': index = 34; break;
case'i': index = 35; break;
case'j': index = 36; break;
case'k': index = 37; break;
case'l': index = 38; break;
case'm': index = 39; break;
case'n': index = 40; break;
case'o': index = 41; break;
case'p': index = 42; break;
case'q': index = 43; break;
case'r': index = 44; break;
case's': index = 45; break;
case't': index = 46; break;
case'u': index = 47; break;
case'v': index = 48; break;
case'w': index = 49; break;
case'x': index = 50; break;
case'y': index = 51; break;
case'z': index = 52; break;
default: if(character_in != EOF){
printf("encode error\n");
exit(1);
}
}
return(index);
}
/*Using the function to convert the index to the character for outputing, when the decoder program work*/
char convert_index_to_character( int index_in)
{
char character;
switch(index_in){
case 0: character = 'A'; break;
case 1: character = 'B'; break;
case 2: character = 'C'; break;
case 3: character = 'D'; break;
case 4: character = 'E'; break;
case 5: character = 'F'; break;
case 6: character = 'G'; break;
case 7: character = 'H'; break;
case 8: character = 'I'; break;
case 9: character = 'J'; break;
case 10: character = 'K'; break;
case 11: character = 'L'; break;
case 12: character = 'M'; break;
case 13: character = 'N'; break;
case 14: character = 'O'; break;
case 15: character = 'P'; break;
case 16: character = 'Q'; break;
case 17: character = 'R'; break;
case 18: character = 'S'; break;
case 19: character = 'T'; break;
case 20: character = 'U'; break;
case 21: character = 'V'; break;
case 22: character = 'W'; break;
case 23: character = 'X'; break;
case 24: character = 'Y'; break;
case 25: character = 'Z'; break;
case 26: character = ' '; break;
case 27: character = 'a'; break;
case 28: character = 'b'; break;
case 29: character = 'c'; break;
case 30: character = 'd'; break;
case 31: character = 'e'; break;
case 32: character = 'f'; break;
case 33: character = 'g'; break;
case 34: character = 'h'; break;
case 35: character = 'i'; break;
case 36: character = 'j'; break;
case 37: character = 'k'; break;
case 38: character = 'l'; break;
case 39: character = 'm'; break;
case 40: character = 'n'; break;
case 41: character = 'o'; break;
case 42: character = 'p'; break;
case 43: character = 'q'; break;
case 44: character = 'r'; break;
case 45: character = 's'; break;
case 46: character = 't'; break;
case 47: character = 'u'; break;
case 48: character = 'v'; break;
case 49: character = 'w'; break;
case 50: character = 'x'; break;
case 51: character = 'y'; break;
case 52: character = 'z'; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -