📄 cfs_tool.c
字号:
* DESCRIPTION
*
*
*
* INPUTS
*
* *input Pointer to BIT_FILE structure.
* This structure holds all the
* related to the input file to be
* compressed.
* *output Pointer to BIT_FILE structure.
* This structure holds all the
* related to the output file to be
* compressed.
*
* OUTPUTS
*
* None
*
************************************************************************/
static VOID CFS_Compress_File(WS_BIT_FILE *input, WS_BIT_FILE *output)
{
INT c;
WS_SYMBOL s;
CFS_Build_Model( input, output);
CFS_Init_Arithmetic_Encoder();
while ( ( c = CFS_Buf_Getc( input ) ) != EOF )
{
CFS_Convert_Int_To_Symbol( c, &s );
CFS_Encode_Symbol( output, &s );
}
CFS_Convert_Int_To_Symbol( CFS_END_OF_STREAM, &s );
CFS_Encode_Symbol( output, &s );
CFS_Flush_Arithmetic_Encoder( output );
CFS_Output_Bits( output, 0L, 16 );
}
/************************************************************************
*
* FUNCTION
*
* CFS_Expand_File
*
* DESCRIPTION
*
*
*
* INPUTS
*
* *input Pointer to BIT_FILE structure.
* This structure holds all the
* related to the input file to be
* compressed.
* *output Pointer to BIT_FILE structure.
* This structure holds all the
* related to the output file to be
* compressed.
*
* OUTPUTS
*
* None
*
************************************************************************/
static VOID CFS_Expand_File(WS_BIT_FILE *input, WS_BIT_FILE *output)
{
WS_SYMBOL s;
INT c;
INT count;
CFS_Input_Counts( input );
CFS_Init_Arithmetic_Decoder( input );
while(1)
{
CFS_Get_Symbol_Scale( &s );
count = CFS_Get_Current_Count( &s );
c = CFS_Convert_Symbol_To_Int( count, &s );
if ( c == CFS_END_OF_STREAM )
break;
CFS_Remove_Symbol_From_Stream( input, &s );
CFS_Buf_Putc((unsigned int)c, output );
}
}
/************************************************************************
*
* FUNCTION
*
* CFS_Build_Model
*
* DESCRIPTION
*
* This is the routine that is called to scan the input file,
* scale the counts, build the totals array, then outputs the
* scaled counts to the output file.
*
* INPUTS
*
* *input Pointer to BIT_FILE structure.
* This structure holds all the
* related to the input file to be
* compressed.
* *output Pointer to BIT_FILE structure.
* This structure holds all the
* related to the output file to be
* compressed.
*
* OUTPUTS
*
* None
*
************************************************************************/
static VOID CFS_Build_Model(WS_BIT_FILE *input, WS_BIT_FILE *output)
{
UINT32 counts[256];
UINT8 scaled_counts[256];
CFS_Count_Bytes(input, counts);
CFS_Scale_Counts(counts, scaled_counts);
CFS_Output_Counts(output, scaled_counts);
CFS_Build_Totals(scaled_counts);
}
/************************************************************************
*
* FUNCTION
*
* CFS_Count_Bytes
*
* DESCRIPTION
*
* This routine runs through the file and counts the appearances
* of each character.
*
* INPUTS
*
* *input Pointer to BIT_FILE structure.
* This structure holds all the
* related to the input file to be
* compressed.
* counts Number of bytes that are found
* in this segement of the file.
*
* OUTPUTS
*
* None
*
************************************************************************/
static VOID CFS_Count_Bytes(WS_BIT_FILE *input, UINT32 counts[])
{
INT i;
INT c;
for ( i = 0 ; i < 256 ; i++ )
counts[ i ] = 0;
while ( ( c = CFS_Buf_Getc( input )) != EOF )
counts[ c ]++;
input->cur_pos = input->fstart; /* "REWIND" input stream */
}
/************************************************************************
*
* FUNCTION
*
* CFS_Scale_Counts
*
* DESCRIPTION
*
* This routine is called to scale the counts down. There are
* two types of scaling that must be done. First, the counts
* need to be scaled down so that the individual counts fit
* into a single UINT8. Then, the counts need to be
* rescaled so that the total of all counts is less than 16384.
*
* INPUTS
*
* counts Number of bytes in file.
* scaled_counts Scaled Number of bytes in file.
*
* OUTPUTS
*
* None
*
************************************************************************/
static VOID CFS_Scale_Counts(UINT32 counts[], UINT8 scaled_counts[])
{
INT i;
UINT32 max_count;
unsigned int total;
UINT32 scale;
/*
* The first section of code makes sure each count fits into a single byte.
*/
max_count = 0;
for ( i = 0 ; i < 256 ; i++ )
if ( counts[ i ] > max_count )
max_count = counts[ i ];
scale = max_count / 256;
scale = scale + 1;
for ( i = 0 ; i < 256 ; i++ )
{
scaled_counts[ i ] = (UINT8 ) ( counts[ i ] / scale );
if ( scaled_counts[ i ] == 0 && counts[ i ] != 0 )
scaled_counts[ i ] = 1;
}
/*
* This next section makes sure the total is less than 16384. I initialize
* the total to 1 instead of 0 because there will be an additional 1 added
* in for the CFS_END_OF_STREAM symbol;
*/
total = 1;
for ( i = 0 ; i < 256 ; i++ )
total += scaled_counts[ i ];
if ( total > ( 32767 - 256 ) )
scale = 4;
else if ( total > 16383 )
scale = 2;
else
return;
for ( i = 0 ; i < 256 ; i++ )
scaled_counts[ i ] = (UINT8)(scaled_counts[ i ] / (UINT8)scale);
}
/************************************************************************
*
* FUNCTION
*
* CFS_Build_Totals
*
* DESCRIPTION
*
* This routine is used by both the encoder and decoder to
* build the table of cumulative totals. The counts for the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -