📄 spiht.c
字号:
base_col = coefficient_block->col;
if (QccSPIHTDescendantsOutsideMask(subband_pyramid,
mask,
base_row, base_col,
block_size))
return(0);
if (method == QCCSPIHT_ENCODE)
{
bit = QccSPIHTDescendantsSignificance(subband_pyramid,
base_row, base_col,
threshold,
block_size);
if (bit == -1)
return(0);
}
if (model != NULL)
if (QccENTArithmeticSetModelContext(model,
QCCSPIHT_LIS_TYPEA_CONTEXT +
coefficient_block->state))
{
QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccENTArithmeticSetModelContext()");
return(2);
}
if (QccSPIHTInputOutput(buffer, &bit, method, model, target_bit_cnt))
{
QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccSPIHTInputOutput()");
return(2);
}
if (!bit)
return(0);
num_offspring =
QccSPIHTGetOffspring(subband_pyramid,
base_row, base_col,
offspring_row,
offspring_col,
block_size);
for (offspring = 0; offspring < num_offspring; offspring++)
{
new_coefficient_block.row =
offspring_row[offspring];
new_coefficient_block.col =
offspring_col[offspring];
new_coefficient_block.type =
QCCSPIHT_TYPE_A;
new_coefficient_block.state = 0;
if (model != NULL)
if (QccENTArithmeticSetModelContext(model,
QCCSPIHT_LIS_TYPEA_OFFSPRING_CONTEXT +
coefficient_block->state))
{
QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccENTArithmeticSetModelContext()");
return(2);
}
if (QccSPIHTInputOutputSignificanceBits(subband_pyramid,
buffer,
&new_coefficient_block,
threshold,
method,
model,
target_bit_cnt,
block_size))
{
QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccSPIHTInputOutputSignificanceBits()");
return(2);
}
new_state = new_coefficient_block.state;
cnt = 0;
for (row = 0; row < block_size; row++)
for (col = 0; col < block_size; col++)
if (QccSPIHTIsSignificant(new_state, row, col, block_size))
{
cnt++;
if ((return_value =
QccSPIHTAddNodeToLSP(LSP,
offspring_row[offspring] + row,
offspring_col[offspring] + col,
subband_pyramid,
threshold,
sign_array,
buffer,
method,
model,
target_bit_cnt,
distortion_trace)))
{
QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccSPIHTAddNodeToLSP()");
return(return_value);
}
}
if (cnt != block_size * block_size)
{
if ((new_node =
QccListCreateNode(sizeof(QccSPIHTCoefficientBlock),
(void *)(&new_coefficient_block))) == NULL)
{
QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccListCreateNode()");
return(1);
}
if (QccListAppendNode(LIP, new_node))
{
QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccListAppendNode()");
return(1);
}
}
}
if (QccSPIHTGetOffspring(subband_pyramid,
offspring_row[0], offspring_col[0],
offspring_row, offspring_col,
block_size))
{
coefficient_block->type = QCCSPIHT_TYPE_B;
if ((new_node =
QccListCreateNode(sizeof(QccSPIHTCoefficientBlock),
(void *)(coefficient_block))) == NULL)
{
QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccListCreateNode()");
return(1);
}
if (QccListAppendNode(LIS, new_node))
{
QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccListAppendNode()");
return(1);
}
}
coefficient_block->type = QCCSPIHT_TYPE_DELETE;
return(0);
}
static int QccSPIHTTypeB(QccWAVSubbandPyramid *subband_pyramid,
QccWAVSubbandPyramid *mask,
int **sign_array,
QccBitBuffer *buffer,
QccSPIHTCoefficientBlock *coefficient_block,
QccListNode *current_list_node,
double threshold,
QccList *LIS,
int method,
QccENTArithmeticModel *model,
int target_bit_cnt,
int block_size)
{
int bit;
int offspring_row[4];
int offspring_col[4];
int num_offspring;
int offspring;
QccSPIHTCoefficientBlock new_coefficient_block;
QccListNode *new_node;
int base_row, base_col;
base_row = coefficient_block->row;
base_col = coefficient_block->col;
if (QccSPIHTDescendantsOutsideMask(subband_pyramid,
mask,
base_row, base_col,
block_size))
return(0);
if (method == QCCSPIHT_ENCODE)
{
bit = QccSPIHTLSignificance(subband_pyramid,
coefficient_block->row,
coefficient_block->col,
threshold,
block_size);
if (bit == -1)
return(0);
}
if (model != NULL)
if (QccENTArithmeticSetModelContext(model,
QCCSPIHT_LIS_TYPEB_CONTEXT +
coefficient_block->state))
{
QccErrorAddMessage("(QccSPIHTTypeB): Error calling QccENTArithmeticSetModelContext()");
return(2);
}
if (QccSPIHTInputOutput(buffer, &bit, method, model, target_bit_cnt))
{
QccErrorAddMessage("(QccSPIHTTypeB): Error calling QccSPIHTInputOutput()");
return(2);
}
if (!bit)
return(0);
num_offspring = QccSPIHTGetOffspring(subband_pyramid,
coefficient_block->row,
coefficient_block->col,
offspring_row,
offspring_col,
block_size);
for (offspring = 0; offspring < num_offspring; offspring++)
{
new_coefficient_block.row =
offspring_row[offspring];
new_coefficient_block.col =
offspring_col[offspring];
new_coefficient_block.type =
QCCSPIHT_TYPE_A;
new_coefficient_block.state = 0;
if ((new_node =
QccListCreateNode(sizeof(QccSPIHTCoefficientBlock),
(void *)(&new_coefficient_block))) == NULL)
{
QccErrorAddMessage("(QccSPIHTTypeB): Error calling QccListCreateNode()");
return(1);
}
if (QccListAppendNode(LIS, new_node))
{
QccErrorAddMessage("(QccSPIHTTypeB): Error calling QccListAppendNode()");
return(1);
}
}
QccSPIHTGetCoefficientBlockFromNode(current_list_node)->type =
QCCSPIHT_TYPE_DELETE;
return(0);
}
static int QccSPIHTSortingPass(QccWAVSubbandPyramid *subband_pyramid,
QccWAVSubbandPyramid *mask,
int **sign_array,
QccBitBuffer *buffer,
double threshold,
QccList *LSP,
QccList *LIP,
QccList *LIS,
int method,
QccENTArithmeticModel *model,
int target_bit_cnt,
int block_size,
QccSPIHTDistortionTrace *distortion_trace)
{
int return_value;
int old_state;
int new_state;
int row, col;
int cnt;
int base_row, base_col;
QccSPIHTCoefficientBlock *current_coefficient_block;
QccListNode *current_list_node;
current_list_node = LIP->start;
while (current_list_node != NULL)
{
current_coefficient_block =
QccSPIHTGetCoefficientBlockFromNode(current_list_node);
if (current_coefficient_block->type != QCCSPIHT_TYPE_DELETE)
{
old_state = current_coefficient_block->state;
if (model != NULL)
if (QccENTArithmeticSetModelContext(model,
QCCSPIHT_LIP_CONTEXT +
old_state))
{
QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccENTArithmeticSetModelContext()");
goto Finished;
}
if (QccSPIHTInputOutputSignificanceBits(subband_pyramid,
buffer,
current_coefficient_block,
threshold,
method,
model,
target_bit_cnt,
block_size))
{
QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccSPIHTInputOutputSignificanceBits()");
goto Finished;
}
new_state = current_coefficient_block->state;
base_row = current_coefficient_block->row;
base_col = current_coefficient_block->col;
cnt = 0;
for (row = 0; row < block_size; row++)
for (col = 0; col < block_size; col++)
if (QccSPIHTIsSignificant(new_state, row, col, block_size))
{
cnt++;
if (!QccSPIHTIsSignificant(old_state, row, col, block_size))
{
return_value =
QccSPIHTAddNodeToLSP(LSP,
base_row + row,
base_col + col,
subband_pyramid,
threshold,
sign_array,
buffer,
method,
model,
target_bit_cnt,
distortion_trace);
if (return_value == 2)
goto Finished;
else
if (return_value == 1)
{
QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccSPIHTAddNodeToLSP()");
goto Error;
}
}
}
if (cnt == block_size * block_size)
current_coefficient_block->type = QCCSPIHT_TYPE_DELETE;
}
current_list_node = current_list_node->next;
}
current_list_node = LIS->start;
while (current_list_node != NULL)
{
current_coefficient_block =
QccSPIHTGetCoefficientBlockFromNode(current_list_node);
switch (current_coefficient_block->type)
{
case QCCSPIHT_TYPE_A:
return_value =
QccSPIHTTypeA(subband_pyramid,
mask,
sign_array,
buffer,
current_coefficient_block,
current_list_node,
threshold,
LSP, LIP, LIS,
method,
model,
target_bit_cnt,
block_size,
distortion_trace);
if (return_value == 2)
goto Finished;
else
if (return_value == 1)
{
QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccSPIHTTypeA()");
goto Error;
}
break;
case QCCSPIHT_TYPE_B:
return_value =
QccSPIHTTypeB(subband_pyramid,
mask,
sign_array,
buffer,
current_coefficient_block,
current_list_node,
threshold,
LIS,
method,
model,
target_bit_cnt,
block_size);
if (return_value == 2)
goto Finished;
else
if (return_value == 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -