📄 wdr.c
字号:
/* * * QccPack: Quantization, compression, and coding libraries * Copyright (C) 1997-2009 James E. Fowler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * *//* * This code was written by Yufei Yuan <yuanyufei@hotmail.com> */#include "libQccPack.h"#define QCCWAVWDR_ENCODE 0#define QCCWAVWDR_DECODE 1#define QCCWAVWDR_SYMBOLNUM 4#define QCCWAVWDR_LONGSYMBOL 2#define POSITIVE 2#define NEGATIVE 3#define ZERO 0#define ONE 1static const int QccWAVwdrArithmeticContexts[] = {4, 2};#define QCCWAVWDR_RUN_CONTEXT 0#define QCCWAVWDR_REFINEMENT_CONTEXT (QCCWAVWDR_RUN_CONTEXT + 1)#define QCCWAVWDR_NUM_CONTEXTS (QCCWAVWDR_REFINEMENT_CONTEXT + 1)#define QCCWAVWDR_MAXBITPLANES 128static int QccWAVwdrInputOutput(QccBitBuffer *buffer, int *symbol, int method, QccENTArithmeticModel *model, int target_bit_cnt){ int return_value; if (method == QCCWAVWDR_ENCODE) { if (model == NULL) { if (QccBitBufferPutBit(buffer, *symbol)) { QccErrorAddMessage("(QccWAVwdrInputOutput): Error calling QccBitBufferPutBit()"); goto Error; } } else { if (QccENTArithmeticEncode(symbol, 1, model, buffer)) { QccErrorAddMessage("(QccWAVwdrInputOutput): Error calling QccENTArithmeticEncode()"); goto Error; } } if (buffer->bit_cnt >= target_bit_cnt) { QccBitBufferFlush(buffer); return(2); } } else if (model == NULL) { if (QccBitBufferGetBit(buffer, symbol)) { QccErrorAddMessage("(QccWAVwdrInputOutput): Error calling QccBitBufferGetBit()"); return(2); } } else if (QccENTArithmeticDecode(buffer, model, symbol, 1)) { QccErrorAddMessage("(QccWAVwdrInputOutput): Error calling QccENTArithmeticDecode()"); return(2); } return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value); }static int QccWAVwdrInputSymbol(QccBitBuffer *bit_buffer, unsigned int *run_length, int *sign, QccENTArithmeticModel *model){ int symbol, return_value; int target_bit_cnt = 0; *run_length = 1; if ((return_value = QccWAVwdrInputOutput(bit_buffer, &symbol, QCCWAVWDR_DECODE, model, target_bit_cnt))) { if (return_value == 2) return(2); else { QccErrorAddMessage("(QccWAVwdrInputSymbol): Error Calling QccWAVwdrInputOutput()"); goto Error; } } while ((symbol != POSITIVE) && (symbol != NEGATIVE)) { if (symbol == ZERO) *run_length <<= 1; else *run_length = (*run_length <<= 1) + 1; if ((return_value = QccWAVwdrInputOutput(bit_buffer, &symbol, QCCWAVWDR_DECODE, model, target_bit_cnt))) { if (return_value == 2) return(2); else { QccErrorAddMessage("(QccWAVwdrInputSymbol): Error Calling QccWAVwdrInputOutput()"); goto Error; } } } if (symbol == POSITIVE) *sign = 0; else *sign = 1; return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value); }static int QccWAVwdrOutputSymbol(QccBitBuffer *bit_buffer, unsigned int run_length, int reduced_bits, int target_bit_cnt, QccENTArithmeticModel *model){ int i, symbol, return_value; unsigned int mask; for (i = reduced_bits - 1; i >= 0; i--) { mask = 1 << i; if (run_length & mask) symbol = ONE; else symbol = ZERO; if ((return_value = QccWAVwdrInputOutput(bit_buffer, &symbol, QCCWAVWDR_ENCODE, model, target_bit_cnt))) { if (return_value == 2) return(2); else { QccErrorAddMessage("(QccWAVwdrOutputSymbol): Error calling QccWAVwdrBitBufferPutBits()"); goto Error; } } } return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value); }static QccWAVwdrCoefficientBlock*QccWAVwdrGetCoefficientBlockFromNode(QccListNode *node){ return((QccWAVwdrCoefficientBlock *)(node->value));}int QccWAVwdrEncodeHeader(QccBitBuffer *buffer, int num_levels, int num_rows, int num_cols, double image_mean, int max_coefficient_bits){ int return_value; if (QccBitBufferPutChar(buffer, (unsigned char)num_levels)) { QccErrorAddMessage("(QccWAVwdrEncodeHeader): Error calling QccBitBufferPuChar()"); goto Error; } if (QccBitBufferPutInt(buffer, num_rows)) { QccErrorAddMessage("(QccWAVwdrEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutInt(buffer, num_cols)) { QccErrorAddMessage("(QccWAVwdrEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutDouble(buffer, image_mean)) { QccErrorAddMessage("(QccWAVwdrEncodeHeader): Error calling QccBitBufferPutDouble()"); goto Error; } if (QccBitBufferPutInt(buffer, max_coefficient_bits)) { QccErrorAddMessage("(QccWAVwdrEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value);}static int QccWAVwdrEncodeDWT(QccWAVSubbandPyramid *image_subband_pyramid, int **sign_array, const QccIMGImageComponent *image, int num_levels, double *image_mean, int *max_coefficient_bits, QccWAVSubbandPyramid *mask_subband_pyramid, const QccIMGImageComponent *mask, const QccWAVWavelet *wavelet, const QccWAVPerceptualWeights *perceptual_weights){ double max_coefficient = -MAXFLOAT; int row, col, return_value; if (mask == NULL) { if (QccMatrixCopy(image_subband_pyramid->matrix, image->image, image->num_rows, image->num_cols)) { QccErrorAddMessage("(QccWAVwdrEncodeDWT): Error calling QccMatrixCopy()"); return(1); } if (QccWAVSubbandPyramidSubtractMean(image_subband_pyramid, image_mean, NULL)) { QccErrorAddMessage("(QccWAVwdrEncodeDWT): Error calling QccWAVSubbandPyramidSubtractMean()"); return(1); } } else { if (QccMatrixCopy(mask_subband_pyramid->matrix, mask->image, mask->num_rows, mask->num_cols)) { QccErrorAddMessage("(QccWAVwdrEncodeDWT): 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("(QccWAVwdrEncodeDWT): Error calling QccWAVSubbandPyramidShapeAdaptiveDWT()"); return(1); } } else if (QccWAVSubbandPyramidDWT(image_subband_pyramid, num_levels, wavelet)) { QccErrorAddMessage("(QccWAVwdrEncodeDWT): Error calling QccWAVSubbandPyramidDWT()"); return(1); } if (perceptual_weights != NULL) { if (QccWAVPerceptualWeightsApply(image_subband_pyramid, perceptual_weights)) { QccErrorAddMessage("(QccWAVwdrEncodeDWT): Error calling QccWAVPerceptualWeightsApply()"); goto Error; } } for (row = 0; row < image_subband_pyramid->num_rows; row++) { for (col = 0; col < image_subband_pyramid->num_cols; col++) { if (image_subband_pyramid->matrix[row][col] >= 0) sign_array[row][col] = 0; else sign_array[row][col] = 1; image_subband_pyramid->matrix[row][col] = fabs(image_subband_pyramid->matrix[row][col]); if (image_subband_pyramid->matrix[row][col] > max_coefficient) max_coefficient = image_subband_pyramid->matrix[row][col]; } } *max_coefficient_bits = (int)floor(QccMathLog2(max_coefficient)); return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value);}static int QccWAVwdrDecodeInverseDWT(QccWAVSubbandPyramid *image_subband_pyramid, QccWAVSubbandPyramid *mask_subband_pyramid, int **sign_array, QccIMGImageComponent *image, double image_mean, const QccWAVWavelet *wavelet, const QccWAVPerceptualWeights *perceptual_weights) { int row, col; int return_value; 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; if (perceptual_weights != NULL) if (QccWAVPerceptualWeightsRemove(image_subband_pyramid, perceptual_weights)) { QccErrorAddMessage("(QccWAVwdrDecodeInverseDWT): Error calling QccWAVPerceptualWeightsRemove()"); goto Error; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -