📄 tarp3d.c
字号:
/* * * QccPack: Quantization, compression, and coding utilities * Copyright (C) 1997-2009 James E. Fowler * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include "libQccPack.h"#define QCCTARP3D_BOUNDARY_VALUE 0.0#define QCCTARP3D_INSIGNIFICANT 0#define QCCTARP3D_PREVIOUSLY_SIGNIFICANT 1#define QCCTARP3D_NEWLY_SIGNIFICANT 2#define QCCTARP3D_SIGNIFICANCEMASK 0x03#define QCCTARP3D_SIGNMASK 0x04#define QCCTARP3D_MAXBITPLANES 128static void QccWAVTarp3DSetSignificance(unsigned char *state, int significance){ *state &= (0xff ^ QCCTARP3D_SIGNIFICANCEMASK); *state |= significance;}static int QccWAVTarp3DGetSignificance(unsigned char state){ return(state & QCCTARP3D_SIGNIFICANCEMASK);}static void QccWAVTarp3DSetSign(unsigned char *state, int sign_value){ if (sign_value) *state |= QCCTARP3D_SIGNMASK; else *state &= (0xff ^ QCCTARP3D_SIGNMASK); }static int QccWAVTarp3DGetSign(unsigned char state){ return((state & QCCTARP3D_SIGNMASK) == QCCTARP3D_SIGNMASK);}static int QccWAVTarp3DUpdateModel(QccENTArithmeticModel *model, double prob){ double p[2]; p[0] = 1 - prob; p[1] = prob; if (QccENTArithmeticSetModelProbabilities(model, p, 0)) { QccErrorAddMessage("(QccWAVTarp3DUpdateModel): Error calling QccENTArithmeticSetModelProbabilities()"); return(1); } return(0);}static int QccWAVTarp3DEncodeDWT(QccWAVSubbandPyramid3D *image_subband_pyramid, unsigned char ***state_array, const QccIMGImageCube *image, 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->volume, image->num_frames, image->num_rows, image->num_cols)) { QccErrorAddMessage("(QccWAVTarp3DEncodeDWT): Error calling QccVolumeCopy()"); return(1); } if (QccWAVSubbandPyramid3DSubtractMean(image_subband_pyramid, image_mean, NULL)) { QccErrorAddMessage("(QccWAVTarp3DEncodeDWT): Error calling QccWAVSubbandPyramid3DSubtractMean()"); return(1); } } else { if (QccVolumeCopy(mask_subband_pyramid->volume, mask->volume, mask->num_frames, mask->num_rows, mask->num_cols)) { QccErrorAddMessage("(QccWAVTarp3DEncodeDWT): Error calling QccVolumeCopy()"); return(1); } *image_mean = QccIMGImageCubeShapeAdaptiveMean(image, 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->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("(QccWAVTarp3DEncodeDWT): Error calling QccWAVSubbandPyramid3DShapeAdaptiveDWT()"); return(1); } } else if (QccWAVSubbandPyramid3DDWT(image_subband_pyramid, transform_type, temporal_num_levels, spatial_num_levels, wavelet)) { QccErrorAddMessage("(QccWAVTarp3DEncodeDWT): 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; QccWAVTarp3DSetSign(&state_array[frame][row][col], 1); } else QccWAVTarp3DSetSign(&state_array[frame][row][col], 0); if (coefficient_magnitude > max_coefficient) max_coefficient = coefficient_magnitude; } *max_coefficient_bits = (int)floor(QccMathLog2(max_coefficient)); return(0);}int QccWAVTarp3DEncodeHeader(QccBitBuffer *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, double alpha){ int return_value; if (QccBitBufferPutBit(buffer, transform_type)) { QccErrorAddMessage("(QccWAVTarp3DEncodeHeader): Error calling QccBitBufferPutBit()"); goto Error; } if (transform_type == QCCWAVSUBBANDPYRAMID3D_PACKET) { if (QccBitBufferPutChar(buffer, (unsigned char)temporal_num_levels)) { QccErrorAddMessage("(QccWAVTarp3DEncodeHeader): Error calling QccBitBufferPuChar()"); goto Error; } } if (QccBitBufferPutChar(buffer, (unsigned char)spatial_num_levels)) { QccErrorAddMessage("(QccWAVTarp3DEncodeHeader): Error calling QccBitBufferPuChar()"); goto Error; } if (QccBitBufferPutInt(buffer, num_frames)) { QccErrorAddMessage("(QccWAVTarp3DEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutInt(buffer, num_rows)) { QccErrorAddMessage("(QccWAVTarp3DEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutInt(buffer, num_cols)) { QccErrorAddMessage("(QccWAVTarp3DEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutDouble(buffer, image_mean)) { QccErrorAddMessage("(QccWAVTarp3DEncodeHeader): Error calling QccBitBufferPutDouble()"); goto Error; } if (QccBitBufferPutInt(buffer, max_coefficient_bits)) { QccErrorAddMessage("(QccWAVTarp3DEncodeHeader): Error calling QccBitBufferPutInt()"); goto Error; } if (QccBitBufferPutDouble(buffer, alpha)) { QccErrorAddMessage("(QccWAVTarpEncodeHeader3D): Error calling QccBitBufferPutDouble()"); goto Error; } return_value = 0; goto Return; Error: return_value = 1; Return: return(return_value);}static int QccWAVTarp3DSignificanceInputOutput(double *coefficient, double p, double threshold, unsigned char *state, QccENTArithmeticModel *model, QccBitBuffer *buffer){ int symbol; int return_value; if (QccWAVTarp3DGetSignificance(*state)) return(0); if (QccWAVTarp3DUpdateModel(model, p)) { QccErrorAddMessage("(QccWAVTarp3DSignificanceInputOutput): Error calling QccWAVTarp3DUpdateModel()"); return(1); } if (buffer->type == QCCBITBUFFER_OUTPUT) { if (*coefficient >= threshold) { symbol = 1; *coefficient -= threshold; } else symbol = 0; return_value = QccENTArithmeticEncode(&symbol, 1, model, buffer); if (return_value == 2) return(2); else if (return_value) { QccErrorAddMessage("(QccWAVTarp3DSignificanceInputOutput): Error calling QccENTArithmeticEncode()"); return(1); } } else { if (QccENTArithmeticDecode(buffer, model, &symbol, 1)) return(2); if (symbol) *coefficient = 1.5 * threshold; } if (symbol) { QccWAVTarp3DSetSignificance(state, QCCTARP3D_NEWLY_SIGNIFICANT); if (QccWAVTarp3DUpdateModel(model, 0.5)) { QccErrorAddMessage("(QccWAVTarp3DSignificanceInputOutput): Error calling QccWAVTarp3DUpdateModel()"); return(1); } if (buffer->type == QCCBITBUFFER_OUTPUT) { symbol = QccWAVTarp3DGetSign(*state); return_value = QccENTArithmeticEncode(&symbol, 1, model, buffer); if (return_value == 2) return(2); else if (return_value) { QccErrorAddMessage("(QccWAVTarp3DSignificanceInputOutput): Error calling QccENTArithmeticEncode()");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -