📄 spiht.c
字号:
if ((new_node =
QccListCreateNode(sizeof(QccSPIHTCoefficientBlock),
(void *)(&coefficient_block))) == NULL)
{
QccErrorAddMessage("(QccSPIHTAlgorithmInitialize): Error calling QccListCreateNode()");
return(1);
}
if (QccListAppendNode(LIP, new_node))
{
QccErrorAddMessage("(QccSPIHTAlgorithmInitialize): Error calling QccListAppendNode()");
return(1);
}
if ((new_node =
QccListCreateNode(sizeof(QccSPIHTCoefficientBlock),
(void *)(&coefficient_block))) == NULL)
{
QccErrorAddMessage("(QccSPIHTAlgorithmInitialize): Error calling QccListCreateNode()");
return(1);
}
if (QccListAppendNode(LIS, new_node))
{
QccErrorAddMessage("(QccSPIHTAlgorithmInitialize): Error calling QccListAppendNode()");
return(1);
}
}
return(0);
}
static double QccSPIHTMaximumCoefficient(QccWAVSubbandPyramid
*subband_pyramid,
int base_row, int base_col,
int block_size)
{
int row, col;
double maximum_coefficient = -MAXFLOAT;
for (row = 0; row < block_size; row++)
for (col = 0; col < block_size; col++)
if (subband_pyramid->matrix[base_row + row][base_col + col] >
maximum_coefficient)
maximum_coefficient =
subband_pyramid->matrix[base_row + row][base_col + col];
return(maximum_coefficient);
}
static int QccSPIHTDescendantsSignificance(QccWAVSubbandPyramid
*subband_pyramid,
int row, int col,
double threshold,
int block_size)
{
int offspring_row[4];
int offspring_col[4];
int num_offspring;
int offspring;
num_offspring =
QccSPIHTGetOffspring(subband_pyramid,
row, col,
offspring_row, offspring_col,
block_size);
if (!num_offspring)
return(-1);
for (offspring = 0; offspring < num_offspring; offspring++)
if (QccSPIHTMaximumCoefficient(subband_pyramid,
offspring_row[offspring],
offspring_col[offspring],
block_size) >=
threshold)
return(1);
for (offspring = 0; offspring < num_offspring; offspring++)
if (QccSPIHTDescendantsSignificance(subband_pyramid,
offspring_row[offspring],
offspring_col[offspring],
threshold,
block_size) == 1)
return(1);
return(0);
}
static int QccSPIHTLSignificance(QccWAVSubbandPyramid
*subband_pyramid,
int row, int col,
double threshold,
int block_size)
{
int offspring_row[4];
int offspring_col[4];
int num_offspring;
int offspring;
int return_value;
num_offspring =
QccSPIHTGetOffspring(subband_pyramid,
row, col,
offspring_row, offspring_col,
block_size);
if (!num_offspring)
return(-1);
for (offspring = 0; offspring < num_offspring; offspring++)
if ((return_value =
QccSPIHTDescendantsSignificance(subband_pyramid,
offspring_row[offspring],
offspring_col[offspring],
threshold,
block_size)))
return(return_value);
return(0);
}
static int QccSPIHTInputOutputRefinementBit(QccWAVSubbandPyramid
*subband_pyramid,
QccBitBuffer *buffer,
double threshold,
QccSPIHTCoefficientBlock
*coefficient,
int method,
QccENTArithmeticModel *model,
int target_bit_cnt,
QccSPIHTDistortionTrace
*distortion_trace)
{
int bit;
if (method == QCCSPIHT_ENCODE)
{
bit =
(subband_pyramid->matrix[coefficient->row][coefficient->col] >=
threshold);
if (bit)
subband_pyramid->matrix[coefficient->row][coefficient->col] -=
threshold;
}
if (model != NULL)
if (QccENTArithmeticSetModelContext(model, QCCSPIHT_REFINEMENT_CONTEXT))
{
QccErrorAddMessage("(QccSPIHTInputOutputRefinementBit): Error calling QccENTArithmeticSetModelContext()");
return(2);
}
if (QccSPIHTInputOutput(buffer, &bit, method, model, target_bit_cnt))
{
QccErrorAddMessage("(QccSPIHTInputOutputRefinementBit): Error calling QccSPIHTInputOutput()");
return(2);
}
if (method == QCCSPIHT_DECODE)
QccSPIHTRefineCoefficient(&(subband_pyramid->matrix
[coefficient->row][coefficient->col]),
bit,
threshold);
if (distortion_trace != NULL)
{
double *coefficient_value =
&(distortion_trace->reconstructed_coefficients.matrix
[coefficient->row][coefficient->col]);
QccSPIHTRefineCoefficient(coefficient_value,
bit,
threshold);
QccSPIHTDistortionTraceUpdate(distortion_trace,
coefficient->row,
coefficient->col,
buffer);
}
return(0);
}
static int QccSPIHTUpdateState(int state, int bit, int row, int col,
int block_size)
{
int mask = 0;
if (bit)
{
mask = 1 << (row * block_size + col);
state |= mask;
}
return(state);
}
static int QccSPIHTIsSignificant(int state, int row, int col,
int block_size)
{
int mask = 0;
mask = 1 << (row * block_size + col);
return(state & mask);
}
static int QccSPIHTInputOutputSignificanceBits(QccWAVSubbandPyramid
*subband_pyramid,
QccBitBuffer *buffer,
QccSPIHTCoefficientBlock
*coefficient_block,
double threshold,
int method,
QccENTArithmeticModel *model,
int target_bit_cnt,
int block_size)
{
int base_row, base_col;
int row, col;
int bit;
int mask;
int symbol = 0;
int old_state;
base_row = coefficient_block->row;
base_col = coefficient_block->col;
old_state = coefficient_block->state;
if (model == NULL)
{
for (row = 0; row < block_size; row++)
for (col = 0; col < block_size; col++)
if (!QccSPIHTIsSignificant(old_state, row, col, block_size))
{
if (method == QCCSPIHT_ENCODE)
bit =
subband_pyramid->matrix[base_row + row][base_col + col] >=
threshold;
if (QccSPIHTInputOutput(buffer, &bit, method, model,
target_bit_cnt))
{
QccErrorAddMessage("(QccSPIHTInputOutputSignificanceBits): Error calling QccSPIHTInputOutput()");
return(2);
}
coefficient_block->state =
QccSPIHTUpdateState(coefficient_block->state, bit, row, col,
block_size);
}
}
else
{
if (method == QCCSPIHT_ENCODE)
for (row = 0, mask = 1; row < block_size; row++)
for (col = 0; col < block_size; col++)
if (!QccSPIHTIsSignificant(old_state, row, col, block_size))
{
bit =
subband_pyramid->matrix[base_row + row][base_col + col] >=
threshold;
if (bit)
symbol |= mask;
coefficient_block->state =
QccSPIHTUpdateState(coefficient_block->state, bit, row, col,
block_size);
mask <<= 1;
}
if (QccSPIHTInputOutput(buffer, &symbol, method, model, target_bit_cnt))
{
QccErrorAddMessage("(QccSPIHTInputOutputSignificanceBits): Error calling QccSPIHTInputOutput()");
return(2);
}
if (method == QCCSPIHT_DECODE)
for (row = 0, mask = 1; row < block_size; row++)
for (col = 0; col < block_size; col++)
if (!QccSPIHTIsSignificant(old_state, row, col, block_size))
{
bit =
symbol & mask;
coefficient_block->state =
QccSPIHTUpdateState(coefficient_block->state, bit, row, col,
block_size);
mask <<= 1;
}
}
return(0);
}
static int QccSPIHTAddNodeToLSP(QccList *LSP,
int row,
int col,
QccWAVSubbandPyramid *subband_pyramid,
double threshold,
int **sign_array,
QccBitBuffer *buffer,
int method,
QccENTArithmeticModel *model,
int target_bit_cnt,
QccSPIHTDistortionTrace *distortion_trace)
{
QccSPIHTCoefficientBlock coefficient_block;
QccListNode *new_node = NULL;
coefficient_block.row = row;
coefficient_block.col = col;
coefficient_block.type = QCCSPIHT_TYPE_A;
coefficient_block.state = 0;
if ((new_node =
QccListCreateNode(sizeof(QccSPIHTCoefficientBlock),
(void *)(&coefficient_block))) == NULL)
{
QccErrorAddMessage("(QccSPIHTAddNodeToLSP): Error calling QccListCreateNode()");
return(1);
}
if (QccListAppendNode(LSP, new_node))
{
QccErrorAddMessage("(QccSPIHTAddNodeToLSP): Error calling QccListAppendNode()");
return(1);
}
if (model != NULL)
if (QccENTArithmeticSetModelContext(model, QCCSPIHT_SIGN_CONTEXT))
{
QccErrorAddMessage("(QccSPIHTAddNodeToLSP): Error calling QccENTArithmeticSetModel()");
return(2);
}
if (QccSPIHTInputOutput(buffer,
&sign_array[row][col],
method,
model,
target_bit_cnt))
{
QccErrorAddMessage("(QccSPIHTAddNodeToLSP): Error calling QccSPIHTInputOutput()");
return(2);
}
if (method == QCCSPIHT_ENCODE)
subband_pyramid->matrix[row][col] -= threshold;
else
subband_pyramid->matrix[row][col] = 1.5 * threshold;
if (distortion_trace != NULL)
{
distortion_trace->reconstructed_coefficients.matrix[row][col] =
1.5 * threshold;
QccSPIHTDistortionTraceUpdate(distortion_trace,
row,
col,
buffer);
}
return(0);
}
static int QccSPIHTTypeA(QccWAVSubbandPyramid
*subband_pyramid,
QccWAVSubbandPyramid *mask,
int **sign_array,
QccBitBuffer *buffer,
QccSPIHTCoefficientBlock *coefficient_block,
QccListNode *current_list_node,
double threshold,
QccList *LSP,
QccList *LIP,
QccList *LIS,
int method,
QccENTArithmeticModel *model,
int target_bit_cnt,
int block_size,
QccSPIHTDistortionTrace *distortion_trace)
{
int base_row, base_col;
QccSPIHTCoefficientBlock new_coefficient_block;
QccListNode *new_node = NULL;
int bit;
int offspring_row[4];
int offspring_col[4];
int num_offspring;
int offspring;
int new_state;
int cnt;
int row, col;
int return_value;
base_row = coefficient_block->row;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -