📄 spiht.c
字号:
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 QccSPIHTEncode2(QccWAVSubbandPyramid *image_subband_pyramid, QccWAVSubbandPyramid *mask_subband_pyramid, double image_mean, QccBitBuffer *buffer, int target_bit_cnt, int arithmetic_coded, FILE *rate_distortion_file){ int return_value; QccENTArithmeticModel *model = NULL; int **sign_array = NULL; int max_coefficient_bits; QccList LSP; QccList LIP; QccList LIS; QccListNode *stop; double threshold; int row; int block_size; QccSPIHTDistortionTrace distortion_trace; int bitplane = 0; 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("(QccSPIHTEncode2): Error allocating memory"); goto Error; } 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("(QccSPIHTEncode2): Error allocating memory"); goto Error; } if (QccSPIHTEncodeExtractSigns(image_subband_pyramid, mask_subband_pyramid, sign_array, &max_coefficient_bits)) { QccErrorAddMessage("(QccSPIHTEncode2): Error calling QccSPIHTEncodeExtractSigns()"); goto Error; } if (rate_distortion_file != NULL) QccSPIHTDistortionTraceInitialize(&distortion_trace, image_subband_pyramid, mask_subband_pyramid, buffer, rate_distortion_file); if (QccSPIHTEncodeHeader(buffer, image_subband_pyramid->num_levels, image_subband_pyramid->num_rows, image_subband_pyramid->num_cols, image_mean, max_coefficient_bits, arithmetic_coded)) { QccErrorAddMessage("(QccSPIHTEncode2): Error calling QccSPIHTEncodeHeader()"); goto Error; } if (arithmetic_coded) { if ((model = QccENTArithmeticEncodeStart(QccSPIHTArithmeticContexts, QCCSPIHT_NUM_CONTEXTS, NULL, target_bit_cnt)) == NULL) { QccErrorAddMessage("(QccSPIHTEncode2): Error calling QccENTArithmeticEncodeStart()"); goto Error; } block_size = 2; } else block_size = 1; if (QccSPIHTAlgorithmInitialize(image_subband_pyramid, mask_subband_pyramid, &LIP, &LIS, block_size)) { QccErrorAddMessage("(QccSPIHTEncode2): Error calling QccSPIHTAlgorithmInitialize()"); goto Error; } threshold = pow((double)2, (double)max_coefficient_bits); while (bitplane < QCCSPIHT_MAXBITPLANES) { stop = LSP.end; return_value = QccSPIHTSortingPass(image_subband_pyramid, mask_subband_pyramid, sign_array, buffer, threshold, &LSP, &LIP, &LIS, QCCSPIHT_ENCODE, model, target_bit_cnt, block_size, ((rate_distortion_file != NULL) ? &distortion_trace : NULL)); if (return_value == 1) { QccErrorAddMessage("(QccSPIHTEncode2): Error calling QccSPIHTSortingPass()"); goto Error; } else if (return_value == 2) break; return_value = QccSPIHTRefinementPass(image_subband_pyramid, buffer, threshold, &LSP, stop, QCCSPIHT_ENCODE, model, target_bit_cnt, ((rate_distortion_file != NULL) ? &distortion_trace : NULL)); if (return_value == 1) { QccErrorAddMessage("(QccSPIHTEncode2): Error calling QccSPIHTRefinementPass()"); goto Error; } else if (return_value == 2) break; threshold /= 2.0; bitplane++; } return_value = 0; QccErrorClearMessages(); goto Return; Error: return_value = 1; Return: if (sign_array != NULL) { for (row = 0; row < image_subband_pyramid->num_rows; row++) if (sign_array[row] != NULL) QccFree(sign_array[row]); QccFree(sign_array); } QccListFree(&LSP); QccListFree(&LIP); QccListFree(&LIS); QccENTArithmeticFreeModel(model); return(return_value);}int QccSPIHTEncode(const QccIMGImageComponent *image, const QccIMGImageComponent *mask, QccBitBuffer *buffer, int num_levels, const QccWAVWavelet *wavelet, const QccWAVPerceptualWeights *perceptual_weights, int target_bit_cnt, int arithmetic_coded, FILE *rate_distortion_file){ int return_value; double image_mean; QccWAVSubbandPyramid image_subband_pyramid; QccWAVSubbandPyramid mask_subband_pyramid; if (image == NULL) return(0); if (buffer == NULL) return(0); if (wavelet == NULL) return(0); QccWAVSubbandPyramidInitialize(&image_subband_pyramid); QccWAVSubbandPyramidInitialize(&mask_subband_pyramid); image_subband_pyramid.num_levels = 0; image_subband_pyramid.num_rows = image->num_rows; image_subband_pyramid.num_cols = image->num_cols; if (QccWAVSubbandPyramidAlloc(&image_subband_pyramid)) { QccErrorAddMessage("(QccSPIHTEncode): Error calling QccWAVSubbandPyramidAlloc()"); goto Error; } if (mask != NULL) { if ((mask->num_rows != image->num_rows) || (mask->num_cols != image->num_cols)) { QccErrorAddMessage("(QccSPIHTEncode): Mask and image must be same size"); goto Error; } 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("(QccSPIHTEncode): Error calling QccWAVSubbandPyramidAlloc()"); goto Error; } } if (QccSPIHTEncodeDWT(&image_subband_pyramid, &image_mean, image, num_levels, &mask_subband_pyramid, mask, wavelet, perceptual_weights)) { QccErrorAddMessage("(QccSPIHTEncode): Error calling QccSPIHTEncodeDWT()"); goto Error; } if (QccSPIHTEncode2(&image_subband_pyramid, (mask != NULL) ? &mask_subband_pyramid : NULL, image_mean, buffer, target_bit_cnt, arithmetic_coded, rate_distortion_file)) { QccErrorAddMessage("(QccSPIHTEncode): Error calling QccSPIHTEncode2()"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: QccWAVSubbandPyramidFree(&image_subband_pyramid); QccWAVSubbandPyramidFree(&mask_subband_pyramid); return(return_value);}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 Error; } *num_levels = (int)ch; if (QccBitBufferGetInt(buffer, num_rows)) { QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferGetInt()"); goto Error; } if (QccBitBufferGetInt(buffer, num_cols)) { QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferGetInt()"); goto Error; } if (QccBitBufferGetDouble(buffer, image_mean)) { QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferGetDouble()"); goto Error; } if (QccBitBufferGetInt(buffer, max_coefficient_bits)) { QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferGetChar()"); goto Error; } if (QccBitBufferGetBit(buffer, arithmetic_coded)) { QccErrorAddMessage("(QccSPIHTDecodeHeader): Error calling QccBitBufferGetBit()"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: 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 == NU
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -