📄 subband_pyramid.c
字号:
#include "spiht.h"
#include "spihtdecode.h"
int QccWAVSubbandPyramidInitialize(QccWAVSubbandPyramid *subband_pyramid)
{
if (subband_pyramid == NULL)
return(0);
QccStringMakeNull(subband_pyramid->filename);
QccStringCopy(subband_pyramid->magic_num, QCCWAVSUBBANDPYRAMID_MAGICNUM);
QccGetQccPackVersion(&subband_pyramid->major_version,
&subband_pyramid->minor_version,
NULL);
subband_pyramid->num_levels = 0;
subband_pyramid->num_rows = 0;
subband_pyramid->num_cols = 0;
subband_pyramid->origin_row = 0;
subband_pyramid->origin_col = 0;
subband_pyramid->subsample_pattern_row = 0;
subband_pyramid->subsample_pattern_col = 0;
subband_pyramid->matrix = NULL;
return(0);
}
int QccWAVSubbandPyramidAlloc(QccWAVSubbandPyramid *subband_pyramid)
{
int return_value;
if (subband_pyramid == NULL)
return(0);
if (subband_pyramid->matrix != NULL)
return(0);
if ((subband_pyramid->matrix =
QccMatrixAlloc(subband_pyramid->num_rows,
subband_pyramid->num_cols)) == NULL)
{
QccErrorAddMessage("(QccWAVSubbandPyramidAlloc): Error calling QccMatrixAlloc()");
goto QccError;
}
return_value = 0;
goto QccReturn;
QccError:
QccWAVSubbandPyramidFree(subband_pyramid);
return_value = 1;
QccReturn:
return(return_value);
}
void QccWAVSubbandPyramidFree(QccWAVSubbandPyramid *subband_pyramid)
{
if (subband_pyramid == NULL)
return;
QccMatrixFree(subband_pyramid->matrix,
subband_pyramid->num_rows);
subband_pyramid->matrix = NULL;
}
int QccWAVSubbandPyramidNumLevelsToNumSubbands(int num_levels)
{
return(num_levels*3 + 1);
}
int QccWAVSubbandPyramidCalcLevelFromSubband(int subband, int num_levels)
{
if (!num_levels)
return(0);
if (!subband)
return(num_levels);
return(num_levels - (subband - 1)/3);
}
int QccWAVSubbandPyramidSubbandSize(const QccWAVSubbandPyramid
*subband_pyramid,
int subband,
int *subband_num_rows,
int *subband_num_cols)
{
int num_rows = 0;
int num_cols = 0;
int level;
level =
QccWAVSubbandPyramidCalcLevelFromSubband(subband,
subband_pyramid->num_levels);
if (!subband)
{
num_rows =
QccWAVWaveletDWTSubbandLength(subband_pyramid->num_rows,
level,
0,
subband_pyramid->origin_row,
subband_pyramid->subsample_pattern_row);
num_cols =
QccWAVWaveletDWTSubbandLength(subband_pyramid->num_cols,
level,
0,
subband_pyramid->origin_col,
subband_pyramid->subsample_pattern_col);
}
else
switch ((subband - 1) % 3)
{
case 0:
num_rows =
QccWAVWaveletDWTSubbandLength(subband_pyramid->num_rows,
level,
1,
subband_pyramid->origin_row,
subband_pyramid->subsample_pattern_row);
num_cols =
QccWAVWaveletDWTSubbandLength(subband_pyramid->num_cols,
level,
0,
subband_pyramid->origin_col,
subband_pyramid->subsample_pattern_col);
break;
case 1:
num_rows =
QccWAVWaveletDWTSubbandLength(subband_pyramid->num_rows,
level,
0,
subband_pyramid->origin_row,
subband_pyramid->subsample_pattern_row);
num_cols =
QccWAVWaveletDWTSubbandLength(subband_pyramid->num_cols,
level,
1,
subband_pyramid->origin_col,
subband_pyramid->subsample_pattern_col);
break;
case 2:
num_rows =
QccWAVWaveletDWTSubbandLength(subband_pyramid->num_rows,
level,
1,
subband_pyramid->origin_row,
subband_pyramid->subsample_pattern_row);
num_cols =
QccWAVWaveletDWTSubbandLength(subband_pyramid->num_cols,
level,
1,
subband_pyramid->origin_col,
subband_pyramid->subsample_pattern_col);
break;
}
if (!num_rows || !num_cols)
num_rows = num_cols = 0;
if (subband_num_rows != NULL)
*subband_num_rows = num_rows;
if (subband_num_cols != NULL)
*subband_num_cols = num_cols;
return(0);
}
int QccWAVSubbandPyramidSubbandOffsets(const QccWAVSubbandPyramid
*subband_pyramid,
int subband,
int *row_offset,
int *col_offset)
{
int subband_num_rows;
int subband_num_cols;
QccWAVSubbandPyramid temp;
if (subband < 0)
return(0);
QccWAVSubbandPyramidInitialize(&temp);
temp.num_levels =
QccWAVSubbandPyramidCalcLevelFromSubband(subband,
subband_pyramid->num_levels);
temp.num_rows = subband_pyramid->num_rows;
temp.num_cols = subband_pyramid->num_cols;
temp.origin_row = subband_pyramid->origin_row;
temp.origin_col = subband_pyramid->origin_col;
temp.subsample_pattern_row = subband_pyramid->subsample_pattern_row;
temp.subsample_pattern_col = subband_pyramid->subsample_pattern_col;
if (QccWAVSubbandPyramidSubbandSize(&temp,
0,
&subband_num_rows,
&subband_num_cols))
{
QccErrorAddMessage("(QccWAVSubbandPyramidSubbandOffsets): Error calling QccWAVSubbandPyramidSubbandSize()");
return(1);
}
if (!subband)
{
*row_offset = 0;
*col_offset = 0;
}
else
switch ((subband - 1) % 3)
{
case 0:
*row_offset = subband_num_rows;
*col_offset = 0;
break;
case 1:
*row_offset = 0;
*col_offset = subband_num_cols;
break;
case 2:
*row_offset = subband_num_rows;
*col_offset = subband_num_cols;
break;
}
return(0);
}
int QccWAVSubbandPyramidAddMean(QccWAVSubbandPyramid *subband_pyramid,
double mean)
{
int subband_row, subband_col;
int subband_num_rows, subband_num_cols;
if (subband_pyramid == NULL)
return(0);
if (subband_pyramid->matrix == NULL)
return(0);
if (subband_pyramid->num_levels != 0)
{
QccErrorAddMessage("(QccWAVSubbandPyramidAddMean): Subband-pyramid number of levels is not zero");
return(1);
}
if (QccWAVSubbandPyramidSubbandSize(subband_pyramid,
0,
&subband_num_rows,
&subband_num_cols))
{
QccErrorAddMessage("(QccWAVSubbandPyramidAddMean): Error calling QccWAVSubbandPyramidSubbandSize()");
return(1);
}
for (subband_row = 0; subband_row < subband_num_rows; subband_row++)
for (subband_col = 0; subband_col < subband_num_cols; subband_col++)
subband_pyramid->matrix[subband_row][subband_col] += mean;
return(0);
}
int QccWAVSubbandPyramidDWT(QccWAVSubbandPyramid *subband_pyramid,
int num_levels,
const QccWAVWavelet *wavelet)
{
int return_value;
if (subband_pyramid == NULL)
return(0);
if (wavelet == NULL)
return(0);
if (subband_pyramid->num_levels != 0)
{
QccErrorAddMessage("(QccWAVSubbandPyramidDWT): Subband pyramid is already decomposed");
goto QccError;
}
subband_pyramid->num_levels = num_levels;
if (QccWAVWaveletDWT2D(subband_pyramid->matrix,
subband_pyramid->matrix,
subband_pyramid->num_rows,
subband_pyramid->num_cols,
subband_pyramid->origin_row,
subband_pyramid->origin_col,
subband_pyramid->subsample_pattern_row,
subband_pyramid->subsample_pattern_col,
num_levels,
wavelet))
{
QccErrorAddMessage("(QccWAVSubbandPyramidDWT): Error calling QccWAVWaveletDWT2D()");
goto QccError;
}
return_value = 0;
goto QccReturn;
QccError:
return_value = 1;
QccReturn:
return(return_value);
}
int QccWAVSubbandPyramidInverseDWT(QccWAVSubbandPyramid *subband_pyramid,
const QccWAVWavelet *wavelet)
{
int return_value;
if (subband_pyramid == NULL)
return(0);
if (wavelet == NULL)
return(0);
if (subband_pyramid->num_levels <= 0)
{
QccErrorAddMessage("(QccWAVSubbandPyramidInverseDWT): Subband pyramid is not decomposed");
goto QccError;
}
if (QccWAVWaveletInverseDWT2D(subband_pyramid->matrix,
subband_pyramid->matrix,
subband_pyramid->num_rows,
subband_pyramid->num_cols,
subband_pyramid->origin_row,
subband_pyramid->origin_col,
subband_pyramid->subsample_pattern_row,
subband_pyramid->subsample_pattern_col,
subband_pyramid->num_levels,
wavelet))
{
QccErrorAddMessage("(QccWAVSubbandPyramidInverseDWT): Error calling QccWAVWaveletDWT2D()");
goto QccError;
}
subband_pyramid->num_levels = 0;
return_value = 0;
goto QccReturn;
QccError:
return_value = 1;
QccReturn:
return(return_value);
}
int QccWAVSubbandPyramidInverseShapeAdaptiveDWT(QccWAVSubbandPyramid
*subband_pyramid,
QccWAVSubbandPyramid *mask,
const QccWAVWavelet *wavelet)
{
int return_value;
if (subband_pyramid == NULL)
return(0);
if (mask == NULL)
return(0);
if (wavelet == NULL)
return(0);
if (subband_pyramid->num_levels <= 0)
{
QccErrorAddMessage("(QccWAVSubbandPyramidInverseShapeAdaptiveDWT): Subband pyramid is not decomposed");
goto QccError;
}
if ((subband_pyramid->num_rows != mask->num_rows) ||
(subband_pyramid->num_cols != mask->num_cols))
{
QccErrorAddMessage("(QccWAVSubbandPyramidInverseShapeAdaptiveDWT): Subband pyramid and mask must have same number of rows and columns");
goto QccError;
}
if (subband_pyramid->num_levels != mask->num_levels)
{
QccErrorAddMessage("(QccWAVSubbandPyramidInverseShapeAdaptiveDWT): Subband pyramid and mask must have same number of levels of decomposition");
goto QccError;
}
if (QccWAVWaveletInverseShapeAdaptiveDWT2D(subband_pyramid->matrix,
mask->matrix,
subband_pyramid->matrix,
mask->matrix,
subband_pyramid->num_rows,
subband_pyramid->num_cols,
subband_pyramid->num_levels,
wavelet))
{
QccErrorAddMessage("(QccWAVSubbandPyramidInverseShapeAdaptiveDWT): Error calling QccWAVWaveletInverseShapeAdaptiveDWT2D()");
goto QccError;
}
subband_pyramid->num_levels = 0;
mask->num_levels = 0;
return_value = 0;
goto QccReturn;
QccError:
return_value = 1;
QccReturn:
return(return_value);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -