📄 cfs_tool.c
字号:
* None
*
*************************************************************************/
static VOID CFS_Flush_Arithmetic_Encoder(WS_BIT_FILE *stream)
{
CFS_Output_Bit( stream, (INT)(CFS_Low & 0x4000) );
CFS_Underflow_Bits++;
while ( CFS_Underflow_Bits-- > 0 )
CFS_Output_Bit( stream, (INT)(~CFS_Low & 0x4000) );
}
/************************************************************************
*
* FUNCTION
*
* CFS_Convert_Int_To_Symbol
*
* DESCRIPTION
*
* Finding the low count, high count, and scale for
* a symbol is really easy, because of the way the totals
* are stored. This is the one redeeming feature of the
* data structure used in this implementation.
*
* INPUTS
*
* c Integer to be converted.
* *s Pointer to the SYMBOL structure
* that contains the converted
* symbol information.
*
* OUTPUTS
*
* None
*
*************************************************************************/
static VOID CFS_Convert_Int_To_Symbol(INT c, WS_SYMBOL *s)
{
s->scale = CFS_Totals[ CFS_END_OF_STREAM + 1 ];
s->low_count = CFS_Totals[ c ];
s->high_count = CFS_Totals[ c + 1 ];
}
/************************************************************************
*
* FUNCTION
*
* CFS_Get_Symbol_Scale
*
* DESCRIPTION
*
* Getting the scale for the current context is easy.
*
* INPUTS
*
* *s Pointer to the SYMBOL structure
* that contains the converted
* symbol information.
*
* OUTPUTS
*
* None
*
*************************************************************************/
static VOID CFS_Get_Symbol_Scale(WS_SYMBOL *s)
{
s->scale = CFS_Totals[ CFS_END_OF_STREAM + 1 ];
}
/************************************************************************
*
* FUNCTION
*
* CFS_Convert_Symbol_To_Int
*
* DESCRIPTION
*
* During decompression, we have to search through the
* table until we find the symbol that straddles the
* "count" parameter. When it is found, it is returned.
* The reason for also setting the high count and low count
* is so that symbol can be properly removed from the
* arithmetic coded input.
*
* INPUTS
*
* count The current count.
* *s Pointer to the SYMBOL structure
* that contains the converted
* symbol information.
*
* OUTPUTS
*
* c Integer form of converted symbol.
*
*************************************************************************/
static INT CFS_Convert_Symbol_To_Int(INT count, WS_SYMBOL *s)
{
INT c;
for ( c = CFS_END_OF_STREAM ; count < CFS_Totals[ c ] ; c-- );
s->high_count = CFS_Totals[ c + 1 ];
s->low_count = CFS_Totals[ c ];
return( c );
}
/************************************************************************
*
* FUNCTION
*
* CFS_Encode_Symbol
*
* DESCRIPTION
*
* This routine is called to encode a symbol. The symbol
* is passed in the SYMBOL structure as a low count, a
* high count, and a range, instead of the more conventional
* probability ranges. The encoding process takes two steps.
* First, the values of high and low are updated to take
* into account the range restriction created by the new
* symbol. Then, as many bits as possible are shifted out to
* the output stream. Finally, high and low are stable again
* and the routine returns.
*
* INPUTS
*
* *stream Pointer to BIT_FILE structure.
* This structure holds all the
* related to the output file to be
* compressed.
* *s Pointer to the SYMBOL structure
* that contains the converted
* symbol information.
*
* OUTPUTS
*
* None
*
*************************************************************************/
static VOID CFS_Encode_Symbol(WS_BIT_FILE *stream, WS_SYMBOL *s)
{
INT32 range;
/*
* These three lines rescale high and low for the new symbol.
*/
range = (INT32) ( CFS_High - CFS_Low ) + 1;
CFS_High = (UINT16)(CFS_Low + (UINT16)((range * s->high_count) / s->scale - 1));
CFS_Low = (UINT16)(CFS_Low + (UINT16)((range * s->low_count) / s->scale));
/*
* This loop turns out new bits until high and low are far enough
* apart to have stabilized.
*/
while(1)
{
/*
* If this test passes, it means that the MSDigits match, and can
* be sent to the output stream.
*/
if ( ( CFS_High & 0x8000 ) == ( CFS_Low & 0x8000 ) )
{
CFS_Output_Bit( stream, (INT)(CFS_High & 0x8000) );
while ( CFS_Underflow_Bits > 0 )
{
CFS_Output_Bit( stream, (INT)(~CFS_High & 0x8000) );
CFS_Underflow_Bits--;
}
}
/*
* If this test passes, the numbers are in danger of underflow, because
* the MSDigits don't match, and the 2nd digits are just one apart.
*/
else if ( ( CFS_Low & 0x4000 ) && !( CFS_High & 0x4000 ))
{
CFS_Underflow_Bits += 1;
CFS_Low &= 0x3fff;
CFS_High |= 0x4000;
} else
return ;
CFS_Low <<= 1;
CFS_High <<= 1;
CFS_High |= 1;
}
}
/************************************************************************
*
* FUNCTION
*
* CFS_Get_Current_Count
*
* DESCRIPTION
*
* When decoding, this routine is called to figure out
* which symbol is presently waiting to be decoded. This
* routine expects to get the current model scale in the
* s->scale parameter, and it returns a count that
* corresponds to the present floating point code:
*
* code = count / s->scale
*
* INPUTS
*
* *s Pointer to the SYMBOL structure
* that contains the converted
* symbol information.
*
* OUTPUTS
*
* count Current Count.
*
*************************************************************************/
static INT16 CFS_Get_Current_Count(WS_SYMBOL *s)
{
INT32 range;
INT16 count;
range = (INT32) ( CFS_High - CFS_Low ) + 1;
count = (INT16)
((((INT32) ( CFS_Code - CFS_Low ) + 1 ) * s->scale - 1 ) / range );
return( count );
}
/************************************************************************
*
* FUNCTION
*
* CFS_Init_Arithmetic_Decoder
*
* DESCRIPTION
*
* This routine is called to initialize the state
* of the arithmetic decoder. This involves initializing
* the high and low registers to their conventional
* starting values, plus reading the first 16 bits from
* the input stream into the code value.
*
* INPUTS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -