spiht.c
来自「spiht的压缩解压缩c编写的」· C语言 代码 · 共 1,572 行 · 第 1/4 页
C
1,572 行
{
QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccSPIHTTypeB()");
goto Error;
}
break;
default:
break;
}
current_list_node = current_list_node->next;
}
return_value = 0;
goto Return;
Finished:
return_value = 2;
goto Return;
Error:
return_value = 1;
Return:
QccSPIHTListClean(LIP);
QccSPIHTListClean(LIS);
return(return_value);
}
static int QccSPIHTRefinementPass(QccWAVSubbandPyramid
*subband_pyramid,
QccBitBuffer *buffer,
double threshold,
QccList *LSP,
QccListNode *stop,
int method,
QccENTArithmeticModel *model,
int target_bit_cnt,
QccSPIHTDistortionTrace *distortion_trace)
{
QccListNode *current_node;
QccSPIHTCoefficientBlock *current_coefficient;
current_node = LSP->start;
if ((current_node == NULL) || (stop == NULL))
return(0);
stop = stop->next;
while (current_node != stop)
{
current_coefficient = QccSPIHTGetCoefficientBlockFromNode(current_node);
if (QccSPIHTInputOutputRefinementBit(subband_pyramid,
buffer,
threshold,
current_coefficient,
method,
model,
target_bit_cnt,
distortion_trace))
{
QccErrorAddMessage("(QccSPIHTRefinementPass): Error calling QccSPIHTInputOutputRefinementBit()");
return(2);
}
current_node = current_node->next;
}
return(0);
}
int QccSPIHTDecodeHeader(QccBitBuffer *buffer,
int *num_levels,
int *num_rows, int *num_cols,
double *image_mean,
int *max_coefficient_bits,
int *arithmetic_coded)
{
int return_value;
unsigned char ch;
if (QccBitBufferGetChar(buffer, &ch))
{
QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferPuChar()");
goto QccError;
}
*num_levels = (int)ch;
if (QccBitBufferGetInt(buffer, num_rows))
{
QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferGetInt()");
goto QccError;
}
if (QccBitBufferGetInt(buffer, num_cols))
{
QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferGetInt()");
goto QccError;
}
if (QccBitBufferGetDouble(buffer, image_mean))
{
QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferGetDouble()");
goto QccError;
}
if (QccBitBufferGetInt(buffer, max_coefficient_bits))
{
QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferGetChar()");
goto QccError;
}
if (QccBitBufferGetBit(buffer, arithmetic_coded))
{
QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferGetBit()");
goto QccError;
}
return_value = 0;
goto QccReturn;
QccError:
return_value = 1;
QccReturn:
return(return_value);
}
int QccSPIHTDecode2(QccBitBuffer *buffer,
QccWAVSubbandPyramid *image_subband_pyramid,
QccWAVSubbandPyramid *mask_subband_pyramid,
int max_coefficient_bits,
int target_bit_cnt,
int arithmetic_coded)
{
int return_value;
QccENTArithmeticModel *model = NULL;
int **sign_array = NULL;
QccList LSP;
QccList LIP;
QccList LIS;
QccListNode *stop;
double threshold;
int row, col;
int block_size;
if (image_subband_pyramid == NULL)
return(0);
if (buffer == NULL)
return(0);
QccListInitialize(&LSP);
QccListInitialize(&LIP);
QccListInitialize(&LIS);
if ((sign_array =
(int **)malloc(sizeof(int *) * image_subband_pyramid->num_rows)) ==
NULL)
{
QccErrorAddMessage("(QccSPIHTDecode2): Error allocating memory");
goto QccError;
}
for (row = 0; row < image_subband_pyramid->num_rows; row++)
if ((sign_array[row] =
(int *)malloc(sizeof(int) * image_subband_pyramid->num_cols)) == NULL)
{
QccErrorAddMessage("(QccSPIHTDecode2): Error allocating memory");
goto QccError;
}
for (row = 0; row < image_subband_pyramid->num_rows; row++)
for (col = 0; col < image_subband_pyramid->num_cols; col++)
{
image_subband_pyramid->matrix[row][col] = 0.0;
sign_array[row][col] = 0;
}
if (arithmetic_coded)
{
if ((model =
QccENTArithmeticDecodeStart(buffer,
QccSPIHTArithmeticContexts,
QCCSPIHT_NUM_CONTEXTS,
NULL,
target_bit_cnt))
== NULL)
{
QccErrorAddMessage("(QccSPIHTDecode2): Error calling QccENTArithmeticDecodeStart()");
goto QccError;
}
block_size = 2;
}
else
block_size = 1;
if (QccSPIHTAlgorithmInitialize(image_subband_pyramid,
mask_subband_pyramid,
&LIP,
&LIS,
block_size))
{
QccErrorAddMessage("(QccSPIHTDecode2): Error calling QccSPIHTAlgorithmInitialize()");
goto QccError;
}
threshold = pow((double)2, (double)max_coefficient_bits);
while (1)
{
stop = LSP.end;
return_value =
QccSPIHTSortingPass(image_subband_pyramid,
mask_subband_pyramid,
sign_array,
buffer,
threshold,
&LSP,
&LIP,
&LIS,
QCCSPIHT_DECODE,
model,
0,
block_size,
NULL);
if (return_value == 1)
{
QccErrorAddMessage("(QccSPIHTDecode2): Error calling QccSPIHTSortingPass()");
goto QccError;
}
else
if (return_value == 2)
break;
return_value =
QccSPIHTRefinementPass(image_subband_pyramid,
buffer,
threshold,
&LSP,
stop,
QCCSPIHT_DECODE,
model,
0,
NULL);
if (return_value == 1)
{
QccErrorAddMessage("(QccSPIHTDecode2): Error calling QccSPIHTRefinementPass()");
goto QccError;
}
else
if (return_value == 2)
break;
threshold /= 2.0;
}
if (QccSPIHTDecodeApplySigns(image_subband_pyramid,
sign_array))
{
QccErrorAddMessage("(QccSPIHTDecode2): Error calling QccSPIHTApplySigns()");
goto QccError;
}
return_value = 0;
QccErrorClearMessages();
goto QccReturn;
QccError:
return_value = 1;
QccReturn:
if (sign_array != NULL)
{
for (row = 0; row < image_subband_pyramid->num_rows; row++)
if (sign_array[row] != NULL)
free(sign_array[row]);
free(sign_array);
}
QccListFree(&LSP);
QccListFree(&LIP);
QccListFree(&LIS);
QccENTArithmeticFreeModel(model);
return(return_value);
}
int QccSPIHTDecode(QccBitBuffer *buffer,
QccIMGImageComponent *image,
const QccIMGImageComponent *mask,
int num_levels,
const QccWAVWavelet *wavelet,
const QccWAVPerceptualWeights *perceptual_weights,
double image_mean,
int max_coefficient_bits,
int target_bit_cnt,
int arithmetic_coded)
{
int return_value;
QccWAVSubbandPyramid image_subband_pyramid;
QccWAVSubbandPyramid mask_subband_pyramid;
QccWAVWavelet lazy_wavelet_transform;
if (image == NULL)
return(0);
if (buffer == NULL)
return(0);
if (wavelet == NULL)
return(0);
QccWAVSubbandPyramidInitialize(&image_subband_pyramid);
QccWAVSubbandPyramidInitialize(&mask_subband_pyramid);
QccWAVWaveletInitialize(&lazy_wavelet_transform);
image_subband_pyramid.num_levels = num_levels;
image_subband_pyramid.num_rows = image->num_rows;
image_subband_pyramid.num_cols = image->num_cols;
if (QccWAVSubbandPyramidAlloc(&image_subband_pyramid))
{
QccErrorAddMessage("(QccSPIHTDecode): Error calling QccWAVSubbandPyramidAlloc()");
goto QccError;
}
if (mask != NULL)
{
if ((mask->num_rows != image->num_rows) ||
(mask->num_cols != image->num_cols))
{
QccErrorAddMessage("(QccSPIHTDecode): Mask and image must be same size");
goto QccError;
}
if (QccWAVWaveletCreate(&lazy_wavelet_transform, "LWT.lft", "symmetric"))
{
QccErrorAddMessage("(QccSPIHTDecode): Error calling QccWAVWaveletCreate()");
goto QccError;
}
mask_subband_pyramid.num_levels = 0;
mask_subband_pyramid.num_rows = mask->num_rows;
mask_subband_pyramid.num_cols = mask->num_cols;
if (QccWAVSubbandPyramidAlloc(&mask_subband_pyramid))
{
QccErrorAddMessage("(QccSPIHTDecode): Error calling QccWAVSubbandPyramidAlloc()");
goto QccError;
}
if (QccMatrixCopy(mask_subband_pyramid.matrix,
mask->image,
mask->num_rows,
mask->num_cols))
{
QccErrorAddMessage("(QccSPIHTDecode): Error calling QccMatrixCopy()");
goto QccError;
}
if (QccWAVSubbandPyramidDWT(&mask_subband_pyramid,
num_levels,
&lazy_wavelet_transform))
{
QccErrorAddMessage("(QccSPIHTDecode): Error calling QccWAVSubbandPyramidDWT()");
goto QccError;
}
}
if (QccSPIHTDecode2(buffer,
&image_subband_pyramid,
(mask != NULL) ?
&mask_subband_pyramid : NULL,
max_coefficient_bits,
target_bit_cnt,
arithmetic_coded))
{
QccErrorAddMessage("(QccSPIHTDecode): Error calling QccSPIHTDecode2()");
goto QccError;
}
if (QccSPIHTDecodeInverseDWT(&image_subband_pyramid,
((mask != NULL) ? &mask_subband_pyramid : NULL),
image,
image_mean,
wavelet,
perceptual_weights))
{
QccErrorAddMessage("(QccSPIHTDecode): Error calling QccSPIHTDecodeInverseDWT()");
goto QccError;
}
return_value = 0;
QccErrorClearMessages();
goto QccReturn;
QccError:
return_value = 1;
QccReturn:
QccWAVSubbandPyramidFree(&image_subband_pyramid);
QccWAVSubbandPyramidFree(&mask_subband_pyramid);
QccWAVWaveletFree(&lazy_wavelet_transform);
return(return_value);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?