📄 arithmetic.c
字号:
{
QccErrorAddMessage("(QccENTArithmeticEncode): Invalid context");
return(1);
}
if ((symbol_stream[current_symbol] >=
model->num_symbols[model->current_context] - 1) ||
(symbol_stream[current_symbol] < 0))
{
QccErrorAddMessage("(QccENTArithmeticEncode): Invalid symbol in symbol stream");
return(1);
}
symbol_index =
model->translate_symbol_to_index
[model->current_context][symbol_stream[current_symbol]];
return_value =
QccENTArithmeticEncodeSymbol(symbol_index, model->current_context,
model, output_buffer);
if (return_value == 2)
return(2);
else
if (return_value == 1)
{
QccErrorAddMessage("(QccENTArithmeticEncode): Error calling QccENTArithmeticEncodeSymbol()");
return(1);
}
if (model->adaptive_model == QCCENT_ADAPTIVE)
if (QccENTArithmeticUpdateModel(model,
symbol_index,
model->current_context))
{
QccErrorAddMessage("(QccENTArithmeticEncode): Error calling QccENTArithmeticUpdateModel()");
return(1);
}
}
return(0);
}
static QccENTArithmeticModel
*QccENTArithmeticCreateModel(const int *num_symbols,
int num_contexts,
QccENTArithmeticGetContext context_function)
{
QccENTArithmeticModel *new_model = NULL;
int symbol, context;
if (num_symbols == NULL)
return(NULL);
if ((new_model =
(QccENTArithmeticModel *)malloc(sizeof(QccENTArithmeticModel))) == NULL)
{
QccErrorAddMessage("(QccENTArithmeticCreateModel): Error allocating memory");
goto QccENTError;
}
QccENTArithmeticModelInitialize(new_model);
if ((new_model->num_symbols =
(int *)malloc(sizeof(int)*num_contexts)) == NULL)
{
QccErrorAddMessage("(QccENTArithmeticCreateModel): Error allocating memory");
goto QccENTError;
}
/* Save space for EOF symbol */
for (context = 0; context < num_contexts; context++)
new_model->num_symbols[context] = num_symbols[context] + 1;
new_model->num_contexts = num_contexts;
if (QccENTArithmeticAllocModelArrays(new_model))
{
QccErrorAddMessage("(QccENTArithmeticCreateModel): Error calling QccENTArithmeticAllocModelArrays()");
goto QccENTError;
}
for (context = 0; context < new_model->num_contexts; context++)
{
for (symbol = 0; symbol < new_model->num_symbols[context]; symbol++)
{
new_model->translate_symbol_to_index[context][symbol] = symbol + 1;
new_model->translate_index_to_symbol[context][symbol + 1] =
symbol;
}
for (symbol = 0; symbol <= new_model->num_symbols[context]; symbol++)
{
new_model->frequencies[context][symbol] = 1;
new_model->cumulative_frequencies[context][symbol] =
new_model->num_symbols[context] - symbol;
}
new_model->frequencies[context][0] = 0;
}
new_model->low = 0;
new_model->high = QCCENT_TOPVALUE;
new_model->bits_to_follow = 0;
new_model->context_function = context_function;
new_model->current_context = 0;
return(new_model);
QccENTError:
if (new_model != NULL)
QccENTArithmeticFreeModel(new_model);
return(NULL);
}
int QccENTArithmeticSetModelContext(QccENTArithmeticModel *model,
int current_context)
{
if ((current_context < 0) || (current_context >= model->num_contexts))
{
QccErrorAddMessage("(QccENTArithmeticSetModelContext): Invalid context number");
return(1);
}
model->current_context = current_context;
return(0);
}
static int QccENTArithmeticDecodeGetBit(QccENTArithmeticModel *model,
QccBitBuffer *input_buffer,
int *bit_value)
{
int beyond_bounds;
if (model->target_num_bits == QCCENT_ANYNUMBITS)
beyond_bounds = QccBitBufferGetBit(input_buffer, bit_value);
else
if (input_buffer->bit_cnt >= model->target_num_bits)
beyond_bounds = 1;
else
beyond_bounds = QccBitBufferGetBit(input_buffer, bit_value);
if (beyond_bounds)
{
QccErrorClearMessages();
model->garbage_bits++;
if (model->garbage_bits > QCCENT_CODEVALUEBITS - 2)
return(1);
*bit_value = 0;
}
return(0);
}
static int QccENTArithmeticDecodeSymbol(int *symbol_index,
int context,
QccENTArithmeticModel *model,
QccBitBuffer *input_buffer)
{
long range;
int cumulative_frequency;
int bit_value;
range = (long)(model->high - model->low) + 1;
cumulative_frequency =
(((long)(model->current_code_value - model->low) + 1) *
model->cumulative_frequencies[context][0] - 1) / range;
for (*symbol_index = 1;
model->cumulative_frequencies[context][*symbol_index] >
cumulative_frequency;
*symbol_index += 1) ;
model->high = model->low +
(range * model->cumulative_frequencies[context][*symbol_index - 1]) /
model->cumulative_frequencies[context][0] - 1;
model->low = model->low +
(range * model->cumulative_frequencies[context][*symbol_index]) /
model->cumulative_frequencies[context][0];
for (;;)
{
if (model->high < QCCENT_HALFVALUE) ;
else if (model->low >= QCCENT_HALFVALUE)
{
model->current_code_value -= QCCENT_HALFVALUE;
model->low -= QCCENT_HALFVALUE;
model->high -= QCCENT_HALFVALUE;
}
else if (model->low >= QCCENT_FIRSTQUARTERVALUE &&
model->high < QCCENT_THIRDQUARTERVALUE)
{
model->current_code_value -= QCCENT_FIRSTQUARTERVALUE;
model->low -= QCCENT_FIRSTQUARTERVALUE;
model->high -= QCCENT_FIRSTQUARTERVALUE;
}
else
break;
model->low = 2 * model->low;
model->high = 2 * model->high + 1;
if (QccENTArithmeticDecodeGetBit(model, input_buffer, &bit_value))
return(1);
model->current_code_value = 2 * (model->current_code_value) +
bit_value;
}
return(0);
}
static int QccENTArithmeticSymbolIsEOF(int symbol_index,
int context,
QccENTArithmeticModel *model)
{
int EOF_symbol_index;
EOF_symbol_index = model->num_symbols[context];
return(symbol_index == EOF_symbol_index);
}
QccENTArithmeticModel *QccENTArithmeticDecodeStart(QccBitBuffer *input_buffer,
const int *num_symbols,
int num_contexts,
QccENTArithmeticGetContext
context_function,
int target_num_bits)
{
int bit_index;
int bit_value;
QccENTArithmeticModel *new_model = NULL;
if ((new_model =
QccENTArithmeticCreateModel(num_symbols, num_contexts,
context_function)) == NULL)
{
QccErrorAddMessage("(QccENTArithmeticDecodeStart): Error calling QccENTArithmeticCreateModel()");
return(NULL);
}
new_model->current_code_value = 0;
new_model->garbage_bits = 0;
new_model->target_num_bits = target_num_bits;
for (bit_index = 1; bit_index <= QCCENT_CODEVALUEBITS; bit_index++)
{
if (QccENTArithmeticDecodeGetBit(new_model, input_buffer, &bit_value))
{
QccErrorAddMessage("(QccENTArithmeticDecodeStart): Error calling QccENTArithmeticDecodeGetBit()");
QccENTArithmeticFreeModel(new_model);
return(NULL);
}
new_model->current_code_value = 2*(new_model->current_code_value) +
bit_value;
}
return(new_model);
}
int QccENTArithmeticDecode(QccBitBuffer *input_buffer,
QccENTArithmeticModel *model,
int *symbol_stream,
int symbol_stream_length)
{
int current_symbol;
int symbol_index;
if (input_buffer == NULL)
return(0);
if (symbol_stream == NULL)
return(0);
if (model == NULL)
return(0);
for (current_symbol = 0; current_symbol < symbol_stream_length;
current_symbol++)
{
if (model->context_function != NULL)
model->current_context =
(model->context_function)(symbol_stream, current_symbol);
if (QccENTArithmeticDecodeSymbol(&symbol_index, model->current_context,
model, input_buffer))
{
QccErrorAddMessage("(QccENTArithmeticDecode): Error calling QccENTArithmeticDecodeSymbol()");
return(1);
}
if (QccENTArithmeticSymbolIsEOF(symbol_index,
model->current_context, model))
return(2);
symbol_stream[current_symbol] =
model->translate_index_to_symbol[model->current_context][symbol_index];
if (model->adaptive_model == QCCENT_ADAPTIVE)
if (QccENTArithmeticUpdateModel(model,
symbol_index, model->current_context))
{
QccErrorAddMessage("(QccENTArithmeticDecode): Error calling QccENTArithmeticUpdateModel()");
return(1);
}
}
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -