📄 sfq.c
字号:
} QccWAVZerotreeMakeFullTree(zerotree); if (QccWAVsfqPruneZerotree(squared_subband_images, quantized_subband_images, distortion_vector, channels, zerotree, highpass_quantizer, lambda, high_tree_thresholds, low_tree_thresholds)) { QccErrorAddMessage("(QccWAVsfqHighpassEncodeProcess): Error calling QccWAVsfqPruneZerotree()"); goto Error; } *distortion = 0.0; *rate = 0.0; total_num_symbols = 0; for (subband = 1; subband < num_subbands; subband++) { num_nonnull_symbols = 0; num_predicted_symbols = 0; for (row = 0, image_index = 0; row < subband_images[subband].num_rows; row++) for (col = 0; col < subband_images[subband].num_cols; col++, image_index++, total_num_symbols++) if (QccWAVZerotreeNullSymbol(zerotree->zerotree[subband][row][col])) { channels[subband].channel_symbols[image_index] = QCCCHANNEL_NULLSYMBOL; *distortion += subband_images[subband].image[row][col] * subband_images[subband].image[row][col]; } else if (zerotree->zerotree[subband][row][col] == QCCWAVZEROTREE_SYMBOLTEMP) { num_predicted_symbols++; *distortion += distortion_vector[subband][image_index]; QccWAVZerotreeMakeSymbolNull(&(zerotree->zerotree [subband][row][col])); } else { num_nonnull_symbols++; *distortion += distortion_vector[subband][image_index]; } *rate += QccChannelEntropy(&(channels[subband]), 1) * (num_predicted_symbols + num_nonnull_symbols) + num_nonnull_symbols; } *distortion /= total_num_symbols; *rate /= total_num_symbols; return_value = 0; goto Return; Error: return_value = 1; Return: if (distortion_vector != NULL) { for (subband = 0; subband < num_subbands; subband++) QccVectorFree(distortion_vector[subband]); QccFree(distortion_vector); } return(return_value);}int QccWAVsfqHighpassEncode(const QccWAVSubbandPyramid *subband_pyramid, QccWAVZerotree *zerotree, QccSQScalarQuantizer *highpass_quantizer, QccChannel *channels, double lambda, int *high_tree_thresholds, int *low_tree_thresholds, QccIMGImageComponent *reconstructed_baseband){ int return_value; double distortion = 0; double rate = 0; double highpass_quantizer_start_stepsize; double highpass_quantizer_end_stepsize; int done = 0; int last_time = 0; QccVector J = NULL; int pass; int num_passes; double min_J = MAXDOUBLE; double winner = 0; int subband; int row, col; QccIMGImageComponent *subband_images = NULL; QccIMGImageComponent *quantized_subband_images = NULL; QccVector *squared_subband_images = NULL; int num_subbands; double max_coefficient = -MAXDOUBLE; if ((subband_pyramid == NULL) || (zerotree == NULL) || (highpass_quantizer == NULL) || (channels == NULL)) return(0); num_subbands = zerotree->num_subbands; if ((subband_images = (QccIMGImageComponent *)malloc(sizeof(QccIMGImageComponent) * num_subbands)) == NULL) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error allocating memory"); goto Error; } if ((quantized_subband_images = (QccIMGImageComponent *)malloc(sizeof(QccIMGImageComponent) * num_subbands)) == NULL) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error allocating memory"); goto Error; } if ((squared_subband_images = (QccVector *)malloc(sizeof(QccVector)*num_subbands)) == NULL) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error allocating memory"); goto Error; } for (subband = 0; subband < num_subbands; subband++) { QccIMGImageComponentInitialize(&subband_images[subband]); subband_images[subband].num_rows = zerotree->num_rows[subband]; subband_images[subband].num_cols = zerotree->num_cols[subband]; QccIMGImageComponentInitialize(&quantized_subband_images[subband]); quantized_subband_images[subband].num_rows = zerotree->num_rows[subband]; quantized_subband_images[subband].num_cols = zerotree->num_cols[subband]; if (QccIMGImageComponentAlloc(&(subband_images[subband]))) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error calling QccIMGImageComponentAlloc()"); goto Error; } if (QccIMGImageComponentAlloc(&(quantized_subband_images[subband]))) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error calling QccIMGImageComponentAlloc()"); goto Error; } if ((squared_subband_images[subband] = QccVectorAlloc(channels[subband].channel_length)) == NULL) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error calling QccVectorAlloc()"); goto Error; } } if (QccWAVSubbandPyramidSplitToImageComponent(subband_pyramid, subband_images)) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error calling QccWAVSubbandPyramidSplitToImageComponent()"); goto Error; } for (subband = 1; subband < num_subbands; subband++) for (row = 0; row < subband_images[subband].num_rows; row++) for (col = 0; col < subband_images[subband].num_cols; col++) if (fabs(subband_images[subband].image[row][col]) > max_coefficient) max_coefficient = fabs(subband_images[subband].image[row][col]); if (highpass_quantizer->stepsize <= 0.0) { highpass_quantizer_start_stepsize = QCCWAVSFQ_HIGHPASSQUANTIZER_START_STEPSIZE; highpass_quantizer_end_stepsize = QCCWAVSFQ_HIGHPASSQUANTIZER_END_STEPSIZE; } else { highpass_quantizer_start_stepsize = highpass_quantizer_end_stepsize = highpass_quantizer->stepsize; last_time = 1; } num_passes = (highpass_quantizer_end_stepsize - highpass_quantizer_start_stepsize) / QCCWAVSFQ_HIGHPASSQUANTIZER_INCREMENT + 1; if ((J = QccVectorAlloc(num_passes)) == NULL) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error calling QccVectorAlloc()"); goto Error; } for (pass = 0; pass < num_passes; pass++) J[pass] = MAXDOUBLE; highpass_quantizer->stepsize = highpass_quantizer_start_stepsize; pass = 0; do { if (last_time) done = 1; if (QccSQScalarQuantization(max_coefficient, highpass_quantizer, NULL, &(channels[1].alphabet_size))) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error calling QccSQScalarQuantization()"); goto Error; } channels[1].alphabet_size = channels[1].alphabet_size * 2 + 1; highpass_quantizer->num_levels = channels[1].alphabet_size; for (subband = 2; subband < num_subbands; subband++) channels[subband].alphabet_size = channels[1].alphabet_size; if (QccWAVsfqHighpassEncodeProcess(subband_images, quantized_subband_images, squared_subband_images, zerotree, highpass_quantizer, channels, lambda, high_tree_thresholds, low_tree_thresholds, &distortion, &rate, reconstructed_baseband)) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error calling QccWAVsfqEncode()"); goto Error; } if (!done) { J[pass] = distortion + lambda * rate; /****/ /* printf(" step: %f\n", highpass_quantizer->stepsize); printf(" MSE: %f\n", distortion); printf(" rate: %f\n", rate); printf(" J: %f\n\n", J[pass]); */ if (pass == num_passes - 1) { for (pass = 0; pass < num_passes; pass++) if (J[pass] < min_J) { min_J = J[pass]; winner = highpass_quantizer_start_stepsize + QCCWAVSFQ_HIGHPASSQUANTIZER_INCREMENT * pass; } highpass_quantizer->stepsize = winner; last_time = 1; } else { highpass_quantizer->stepsize += QCCWAVSFQ_HIGHPASSQUANTIZER_INCREMENT; pass++; } } } while (!done); for (subband = 1; subband < num_subbands; subband++) if (QccChannelRemoveNullSymbols(&(channels[subband]))) { QccErrorAddMessage("(QccWAVsfqHighpassEncode): Error calling QccChannelRemoveNullSymbols()"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: QccVectorFree(J); if (subband_images != NULL) { for (subband = 0; subband < num_subbands; subband++) QccIMGImageComponentFree(&(subband_images[subband])); QccFree(subband_images); } if (squared_subband_images != NULL) { for (subband = 0; subband < num_subbands; subband++) QccVectorFree(squared_subband_images[subband]); QccFree(squared_subband_images); } if (quantized_subband_images != NULL) { for (subband = 0; subband < num_subbands; subband++) QccIMGImageComponentFree(&(quantized_subband_images[subband])); QccFree(quantized_subband_images); } return(return_value);}static int QccWAVsfqDecodeReconstructZerotree(QccWAVZerotree *zerotree, int *zerotree_symbols, int *zerotree_index, int *high_tree_thresholds, int *low_tree_thresholds, int subband, QccIMGImageComponent *subband_images){ int return_value; int row, col; QccIMGImageComponent variances; QccIMGImageComponent filtered_variances; double filter_coefficients[] = { 0.333333, 0.333333, 0.333333 }; QccFilter filter = { QCCFILTER_SYMMETRICWHOLE, 3, NULL }; int parent_subband; int variance_index; double high_variance, low_variance, parent_variance; filter.coefficients = filter_coefficients; if ((subband <= 0) || (subband >= zerotree->num_subbands - 3)) return(0); if ((high_tree_thresholds == NULL) || (low_tree_thresholds == NULL)) { for (row = 0; row < zerotree->num_rows[subband]; row++) for (col = 0; col < zerotree->num_cols[subband]; col++) if (!QccWAVZerotreeNullSymbol(zerotree->zerotree[subband][row][col])) { zerotree->zerotree[subband][row][col] = zerotree_symbols[(*zerotree_index)++]; if (zerotree->zerotree[subband][row][col] == QCCWAVZEROTREE_SYMBOLZTROOT) QccWAVZerotreeCarveOutZerotree(zerotree, subband, row, col); } return(0); } parent_subband = (subband < 4) ? 0 : subband - 3; QccIMGImageComponentInitialize(&variances); QccIMGImageComponentInitialize(&filtered_variances); variances = subband_images[parent_subband]; variances.image = NULL; filtered_variances = subband_images[parent_subband]; filtered_variances.image = NULL; if (QccIMGImageComponentAlloc(&variances)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -