📄 bisk.c
字号:
const QccWAVWavelet *wavelet){ int row, col; if (mask == NULL) { if (QccMatrixCopy(image_subband_pyramid->matrix, image->image, image->num_rows, image->num_cols)) { QccErrorAddMessage("(QccWAVbiskEncodeDWT): Error calling QccMatrixCopy()"); return(1); } if (QccWAVSubbandPyramidSubtractMean(image_subband_pyramid, image_mean, NULL)) { QccErrorAddMessage("(QccWAVbiskEncodeDWT): Error calling QccWAVSubbandPyramidSubtractMean()"); return(1); } } else { if (QccMatrixCopy(mask_subband_pyramid->matrix, mask->image, mask->num_rows, mask->num_cols)) { QccErrorAddMessage("(QccWAVbiskEncodeDWT): Error calling QccMatrixCopy()"); return(1); } *image_mean = QccIMGImageComponentShapeAdaptiveMean(image, mask); for (row = 0; row < image_subband_pyramid->num_rows; row++) for (col = 0; col < image_subband_pyramid->num_cols; col++) if (QccAlphaTransparent(mask_subband_pyramid->matrix[row][col])) image_subband_pyramid->matrix[row][col] = 0; else image_subband_pyramid->matrix[row][col] = image->image[row][col] - *image_mean; } if (mask != NULL) { if (QccWAVSubbandPyramidShapeAdaptiveDWT(image_subband_pyramid, mask_subband_pyramid, num_levels, wavelet)) { QccErrorAddMessage("(QccWAVbiskEncodeDWT): Error calling QccWAVSubbandPyramidShapeAdaptiveDWT()"); return(1); } } else if (QccWAVSubbandPyramidDWT(image_subband_pyramid, num_levels, wavelet)) { QccErrorAddMessage("(QccWAVbiskEncodeDWT): Error calling QccWAVSubbandPyramidDWT()"); return(1); } return(0);}int QccWAVbiskEncodeHeader(QccBitBuffer *output_buffer, int num_levels, int num_rows, int num_cols, double image_mean, int max_coefficient_bits){ int return_value; if (QccBitBufferPutChar(output_buffer, (unsigned char)num_levels)) { QccErrorAddMessage("(QccWAVbiskEncodeHeader): Error calling QccBitBufferPuChar()"); goto Error; } if (QccBitBufferPutInt(output_buffer, num_rows)) { QccErrorAddMessage("(QccWAVbiskEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutInt(output_buffer, num_cols)) { QccErrorAddMessage("(QccWAVbiskEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutDouble(output_buffer, image_mean)) { QccErrorAddMessage("(QccWAVbiskEncodeHeader): Error calling QccBitBufferPutDouble()"); goto Error; } if (QccBitBufferPutInt(output_buffer, max_coefficient_bits)) { QccErrorAddMessage("(QccWAVbiskEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value);}static int QccWAVbiskEncodeExtractSigns(QccWAVSubbandPyramid *image_subband_pyramid, QccWAVSubbandPyramid *mask_subband_pyramid, char **sign_array, int *max_coefficient_bits){ double coefficient_magnitude; double max_coefficient = -MAXDOUBLE; int row, col; if (mask_subband_pyramid == NULL) for (row = 0; row < image_subband_pyramid->num_rows; row++) for (col = 0; col < image_subband_pyramid->num_cols; col++) { coefficient_magnitude = fabs(image_subband_pyramid->matrix[row][col]); if (image_subband_pyramid->matrix[row][col] != coefficient_magnitude) { image_subband_pyramid->matrix[row][col] = coefficient_magnitude; sign_array[row][col] = QCCBISK_NEGATIVE; } else sign_array[row][col] = QCCBISK_POSITIVE; if (coefficient_magnitude > max_coefficient) max_coefficient = coefficient_magnitude; } else for (row = 0; row < image_subband_pyramid->num_rows; row++) for (col = 0; col < image_subband_pyramid->num_cols; col++) if (!QccAlphaTransparent(mask_subband_pyramid->matrix[row][col])) { coefficient_magnitude = fabs(image_subband_pyramid->matrix[row][col]); if (image_subband_pyramid->matrix[row][col] != coefficient_magnitude) { image_subband_pyramid->matrix[row][col] = coefficient_magnitude; sign_array[row][col] = QCCBISK_NEGATIVE; } else sign_array[row][col] = QCCBISK_POSITIVE; if (coefficient_magnitude > max_coefficient) max_coefficient = coefficient_magnitude; } *max_coefficient_bits = (int)floor(QccMathLog2(max_coefficient)); return(0);}static int QccWAVbiskDecodeApplySigns(QccWAVSubbandPyramid *image_subband_pyramid, QccWAVSubbandPyramid *mask_subband_pyramid, char **sign_array){ int row, col; if (mask_subband_pyramid == NULL) { for (row = 0; row < image_subband_pyramid->num_rows; row++) for (col = 0; col < image_subband_pyramid->num_cols; col++) if (sign_array[row][col]) image_subband_pyramid->matrix[row][col] *= -1; } else for (row = 0; row < image_subband_pyramid->num_rows; row++) for (col = 0; col < image_subband_pyramid->num_cols; col++) if ((!QccAlphaTransparent(mask_subband_pyramid->matrix[row][col])) && sign_array[row][col]) image_subband_pyramid->matrix[row][col] *= -1; return(0);}int QccWAVbiskEncode2(QccWAVSubbandPyramid *image_subband_pyramid, QccWAVSubbandPyramid *mask_subband_pyramid, double image_mean, int target_bit_cnt, QccBitBuffer *output_buffer, FILE *rate_distortion_file){ int return_value; QccENTArithmeticModel *model = NULL; char **sign_array = NULL; char **significance_map = NULL; int max_coefficient_bits; double threshold; int row, col; QccList LIS; QccList LSP; int bitplane = 0; QccWAVbiskDistortionTrace distortion_trace; if (image_subband_pyramid == NULL) return(0); if (output_buffer == NULL) return(0); QccListInitialize(&LIS); QccListInitialize(&LSP); if ((sign_array = (char **)malloc(sizeof(char *) * image_subband_pyramid->num_rows)) == NULL) { QccErrorAddMessage("(QccWAVbiskEncode2): Error allocating memory"); goto Error; } for (row = 0; row < image_subband_pyramid->num_rows; row++) if ((sign_array[row] = (char *)malloc(sizeof(char) * image_subband_pyramid->num_cols)) == NULL) { QccErrorAddMessage("(QccWAVbiskEncode2): Error allocating memory"); goto Error; } if ((significance_map = (char **)malloc(sizeof(char *) * image_subband_pyramid->num_rows)) == NULL) { QccErrorAddMessage("(QccWAVbiskEncode2): Error allocating memory"); goto Error; } for (row = 0; row < image_subband_pyramid->num_rows; row++) if ((significance_map[row] = (char *)malloc(sizeof(char) * image_subband_pyramid->num_cols)) == NULL) { QccErrorAddMessage("(QccWAVbiskEncode2): Error allocating memory"); goto Error; } for (row = 0; row < image_subband_pyramid->num_rows; row++) for (col = 0; col < image_subband_pyramid->num_cols; col++) significance_map[row][col] = QCCBISK_INSIGNIFICANT; if (QccWAVbiskEncodeExtractSigns(image_subband_pyramid, mask_subband_pyramid, sign_array, &max_coefficient_bits)) { QccErrorAddMessage("(QccWAVbiskEncode2): Error calling QccWAVbiskEncodeExtractSigns()"); goto Error; } if (rate_distortion_file != NULL) QccWAVbiskDistortionTraceInitialize(&distortion_trace, image_subband_pyramid, mask_subband_pyramid, output_buffer, rate_distortion_file); if (QccWAVbiskEncodeHeader(output_buffer, image_subband_pyramid->num_levels, image_subband_pyramid->num_rows, image_subband_pyramid->num_cols, image_mean, max_coefficient_bits)) { QccErrorAddMessage("(QccWAVbiskEncode2): Error calling QccWAVbiskEncodeHeader()"); goto Error; } if ((model = QccENTArithmeticEncodeStart(QccWAVbiskNumSymbols, QCCBISK_NUM_CONTEXTS, NULL, target_bit_cnt)) == NULL) { QccErrorAddMessage("(QccWAVbiskEncode2): Error calling QccENTArithmeticEncodeStart()"); goto Error; } threshold = pow((double)2, (double)max_coefficient_bits); if (QccWAVbiskInitialization(&LIS, &LSP, image_subband_pyramid, mask_subband_pyramid)) { QccErrorAddMessage("(QccWAVbiskEncode2): Error calling QccWAVbiskInitialization()"); goto Error; } while (bitplane < QCCBISK_MAXBITPLANES) { return_value = QccWAVbiskSortingPass(image_subband_pyramid, mask_subband_pyramid, significance_map, sign_array, threshold, &LIS, &LSP, model, output_buffer, ((rate_distortion_file != NULL) ? &distortion_trace : NULL)); if (return_value == 1) { QccErrorAddMessage("(QccWAVbiskEncode2): Error calling QccWAVbiskSortingPass()"); goto Error; } else if (return_value == 2) goto Finished; return_value = QccWAVbiskRefinementPass(image_subband_pyramid, &LSP, threshold, model, output_buffer, ((rate_distortion_file != NULL) ? &distortion_trace : NULL)); if (return_value == 1) { QccErrorAddMessage("(QccWAVbiskEncode2): Error calling QccWAVbiskRefinementPass()"); goto Error; } else if (return_value == 2) goto Finished; threshold /= 2.0; bitplane++; } Finished: return_value = 0; 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); } if (significance_map != NULL) { for (row = 0; row < image_subband_pyramid->num_rows; row++) if (significance_map[row] != NULL) QccFree(significance_map[row]); QccFree(significance_map); } QccENTArithmeticFreeModel(model); QccWAVbiskFreeLIS(&LIS); QccListFree(&LSP); return(return_value);}int QccWAVbiskEncode(const QccIMGImageComponent *image, const QccIMGImageComponent *mask, int num_levels, int target_bit_cnt, const QccWAVWavelet *wavelet, QccBitBuffer *output_buffer, FILE *rate_distortion_file){ int return_value; QccWAVSubbandPyramid image_subband_pyramid; QccWAVSubbandPyramid mask_subband_pyramid; double image_mean; if (image == NULL) return(0); if (output_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("(QccWAVbiskEncode): Error calling QccWAVSubbandPyramidAlloc()"); goto Error; } if (mask != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -