📄 wdr3d.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 Justin Rucker, based on * the 2D WDR implementation by Yufei Yuan. */#include "libQccPack.h"#define QCCWAVWDR3D_ENCODE 0#define QCCWAVWDR3D_DECODE 1#define QCCWAVWDR3D_SYMBOLNUM 4#define QCCWAVWDR3D_LONGSYMBOL 2#define POSITIVE 2#define NEGATIVE 3#define ZERO 0#define ONE 1static const int QccWAVwdr3DArithmeticContexts[] = {4, 2};#define QCCWAVWDR3D_RUN_CONTEXT 0#define QCCWAVWDR3D_REFINEMENT_CONTEXT (QCCWAVWDR3D_RUN_CONTEXT + 1)#define QCCWAVWDR3D_NUM_CONTEXTS (QCCWAVWDR3D_REFINEMENT_CONTEXT + 1)#define QCCWAVWDR3D_SIGNIFICANCEMASK 0x03#define QCCWAVWDR3D_SIGNMASK 0x04#define QCCWAVWDR3D_MAXBITPLANES 128static void QccWAVwdr3DPutSign(unsigned char *state, int sign_value){ *state = sign_value; }static int QccWAVwdr3DGetSign(unsigned char state){ return(state);}static int QccWAVwdr3DInputOutput(QccBitBuffer *buffer, int *symbol, int method, QccENTArithmeticModel *model, int target_bit_cnt){ int return_value; if (method == QCCWAVWDR3D_ENCODE) { if (model == NULL) { if (QccBitBufferPutBit(buffer, *symbol)) { QccErrorAddMessage("(QccWAVwdr3DInputOutput): Error calling QccBitBufferPutBit()"); goto Error; } } else { if (QccENTArithmeticEncode(symbol, 1, model, buffer)) { QccErrorAddMessage("(QccWAVwdr3DInputOutput): 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("(QccWAVwdr3DInputOutput): Error calling QccBitBufferGetBit()"); return(2); } } else if (QccENTArithmeticDecode(buffer, model, symbol, 1)) { QccErrorAddMessage("(QccWAVwdr3DInputOutput): Error calling QccENTArithmeticDecode()"); return(2); } return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value); }static int QccWAVwdr3DInputSymbol(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 = QccWAVwdr3DInputOutput(bit_buffer, &symbol, QCCWAVWDR3D_DECODE, model, target_bit_cnt))) { if (return_value == 2) return(2); else { QccErrorAddMessage("(QccWAVwdr3DInputSymbol): Error Calling QccWAVwdr3DInputOutput()"); goto Error; } } while ((symbol != POSITIVE) && (symbol != NEGATIVE)) { if (symbol == ZERO) *run_length <<= 1; else *run_length = (*run_length <<= 1) + 1; if ((return_value = QccWAVwdr3DInputOutput(bit_buffer, &symbol, QCCWAVWDR3D_DECODE, model, target_bit_cnt))) { if (return_value == 2) return(2); else { QccErrorAddMessage("(QccWAVwdr3DInputSymbol): Error Calling QccWAVwdr3DInputOutput()"); goto Error; } } } if (symbol == POSITIVE) *sign = POSITIVE; else *sign = NEGATIVE; return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value); }static int QccWAVwdr3DOutputSymbol(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 = QccWAVwdr3DInputOutput(bit_buffer, &symbol, QCCWAVWDR3D_ENCODE, model, target_bit_cnt))) { if (return_value == 2) return(2); else { QccErrorAddMessage("(QccWAVwdr3DOutputSymbol): Error calling QccWAVwdr3DBitBufferPutBits()"); goto Error; } } } return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value); }static QccWAVwdr3DCoefficientBlock*QccWAVwdr3DGetCoefficientBlockFromNode(QccListNode *node){ return((QccWAVwdr3DCoefficientBlock *)(node->value));}int QccWAVwdr3DEncodeHeader(QccBitBuffer *output_buffer, int transform_type, int temporal_num_levels, int spatial_num_levels, int num_frames, int num_rows, int num_cols, double image_mean, int max_coefficient_bits){ int return_value; if (QccBitBufferPutBit(output_buffer, transform_type)) { QccErrorAddMessage("(QccWAVwdr3DEncodeHeader): Error calling QccBitBufferPutBit()"); goto Error; } if (transform_type == QCCWAVSUBBANDPYRAMID3D_PACKET) { if (QccBitBufferPutChar(output_buffer, (unsigned char)temporal_num_levels)) { QccErrorAddMessage("(QccWAVwdr3DEncodeHeader): Error calling QccBitBufferPuChar()"); goto Error; } } if (QccBitBufferPutChar(output_buffer, (unsigned char)spatial_num_levels)) { QccErrorAddMessage("(QccWAVwdr3DEncodeHeader): Error calling QccBitBufferPuChar()"); goto Error; } if (QccBitBufferPutInt(output_buffer, num_frames)) { QccErrorAddMessage("(QccWAVwdr3DEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutInt(output_buffer, num_rows)) { QccErrorAddMessage("(QccWAVwdr3DEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutInt(output_buffer, num_cols)) { QccErrorAddMessage("(QccWAVwdr3DEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutDouble(output_buffer, image_mean)) { QccErrorAddMessage("(QccWAVwdr3DEncodeHeader): Error calling QccBitBufferPutDouble()"); goto Error; } if (QccBitBufferPutInt(output_buffer, max_coefficient_bits)) { QccErrorAddMessage("(QccWAVwdr3DEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value);}static int QccWAVwdr3DEncodeDWT(QccWAVSubbandPyramid3D *image_subband_pyramid, unsigned char ***sign_array, const QccIMGImageCube *image_cube, int transform_type, int temporal_num_levels, int spatial_num_levels, double *image_mean, int *max_coefficient_bits, QccWAVSubbandPyramid3D *mask_subband_pyramid, const QccIMGImageCube *mask, const QccWAVWavelet *wavelet){ double coefficient_magnitude; double max_coefficient = -MAXFLOAT; int frame, row, col; if (mask == NULL) { if (QccVolumeCopy(image_subband_pyramid->volume, image_cube->volume, image_cube->num_frames, image_cube->num_rows, image_cube->num_cols)) { QccErrorAddMessage("(QccWAVwdr3DEncodeDWT): Error calling QccVolumeCopy()"); return(1); } if (QccWAVSubbandPyramid3DSubtractMean(image_subband_pyramid, image_mean, NULL)) { QccErrorAddMessage("(QccWAVwdr3DEncodeDWT): Error calling QccWAVSubbandPyramid3DSubtractMean()"); return(1); } } else { if (QccVolumeCopy(mask_subband_pyramid->volume, mask->volume, mask->num_frames, mask->num_rows, mask->num_cols)) { QccErrorAddMessage("(QccWAVwdr3DEncodeDWT): Error calling QccVolumeCopy()"); return(1); } *image_mean = QccIMGImageCubeShapeAdaptiveMean(image_cube, mask); for (frame = 0; frame < image_subband_pyramid->num_frames; frame++) 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->volume [frame][row][col])) image_subband_pyramid->volume[frame][row][col] = 0; else image_subband_pyramid->volume[frame][row][col] = image_cube->volume[frame][row][col] - *image_mean; } if (mask != NULL) { if (QccWAVSubbandPyramid3DShapeAdaptiveDWT(image_subband_pyramid, mask_subband_pyramid, transform_type, temporal_num_levels, spatial_num_levels, wavelet)) { QccErrorAddMessage("(QccWAVwdr3DEncodeDWT): Error calling QccWAVSubbandPyramid3DShapeAdaptiveDWT()"); return(1); } } else if (QccWAVSubbandPyramid3DDWT(image_subband_pyramid, transform_type, temporal_num_levels, spatial_num_levels, wavelet)) { QccErrorAddMessage("(QccWAVwdr3DEncodeDWT): Error calling QccWAVSubbandPyramid3DDWT()"); return(1); } for (frame = 0; frame < image_subband_pyramid->num_frames; frame++) 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->volume[frame][row][col]); if (image_subband_pyramid->volume[frame][row][col] != coefficient_magnitude) { image_subband_pyramid->volume[frame][row][col] = coefficient_magnitude; QccWAVwdr3DPutSign(&sign_array[frame][row][col], NEGATIVE); } else QccWAVwdr3DPutSign(&sign_array[frame][row][col], POSITIVE); if (coefficient_magnitude > max_coefficient) max_coefficient = coefficient_magnitude; } *max_coefficient_bits = (int)floor(QccMathLog2(max_coefficient)); return(0);}static int QccWAVwdr3DDecodeInverseDWT(QccWAVSubbandPyramid3D *image_subband_pyramid, QccWAVSubbandPyramid3D *mask_subband_pyramid, unsigned char ***sign_array, QccIMGImageCube *image_cube, double image_mean, const QccWAVWavelet *wavelet){ int frame, row, col; for (frame = 0; frame < image_subband_pyramid->num_frames; frame++) for (row = 0; row < image_subband_pyramid->num_rows; row++) for (col = 0; col < image_subband_pyramid->num_cols; col++) if (QccWAVwdr3DGetSign(sign_array[frame][row][col]) == NEGATIVE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -