📄 dcttce.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. * *//* * * Modified by Vijay Shah, at Mississippi State University, 2005, to perform * DCT-TCE encode and decode of the coefficients. Original TCE code by * Chao Tian. * */#include "libQccPack.h"#define QCCWAVDCTTCE_BOUNDARY_VALUE (1e-6)//definition used in context information#define QCCWAVDCTTCE_Z 0 //zero, AKA, insignificant#define QCCWAVDCTTCE_NZN_NEW 2 //non-zero-neighbor#define QCCWAVDCTTCE_S 3 //significant#define QCCWAVDCTTCE_S_NEW 4#define QCCWAVDCTTCE_NZN 5// more refinement can be made if direction of Tarp filter is considered// but the improvement is minor#define QCCWAVTCE_ALPHA 0.4#define QCCWAVTCE_ALPHA_HIGH 0.4#define QCCWAVTCE_ALPHA_LOW 0.4//ugly fix, use 1-D IIR filter to provide PMF estimate#define QCCWAVTCE_ALPHA_1D 0.995 #define QCCWAVTCE_ALPHA_1D_O 0.005// this should be 0.5, however, 0.3 seems to work a little better (minor)// reason unknown#define QCCWAVTCE_REFINE_HOLDER 0.5// threshold for cross-scale prediction...#define QCCWAVTCE_PREDICT_THRESHOLD 0.05//weight factor for cross-scale and current scale#define QCCWAVTCE_CURRENT_SCALE 0.8#define QCCWAVTCE_PARENT_SCALE 0.2// NO need to change this function for DCTstatic int QccWAVdcttceUpdateModel(QccENTArithmeticModel *model, double prob){ double probabilities[2]; probabilities[1] = prob; probabilities[0] = 1 - probabilities[1]; if (QccENTArithmeticSetModelProbabilities(model, probabilities, 0)) { QccErrorAddMessage("(QccWAVdcttceUpdateModel): Error calling QccENTArithmeticSetModelProbabilities()"); return(1); } return(0);}static int QccWAVdcttceCreateDCTSubbandMatrix(QccMatrixInt dctwav_matrix, int num_levels, int block_size, int row){ int return_value; QccMatrixInt array_val = NULL; int total_block; QccVolume row_3D = NULL; int i, j, m, n, k, ps_rs, ps_cs, r_w, r_c; total_block = row / block_size; if ((array_val = QccMatrixIntAlloc(row, row)) == NULL) { QccErrorAddMessage("(QccWAVdcttceCreateDCTSubbandMatrix): Error calling QccMatrixIntAlloc()"); goto Error; } if ((row_3D = QccVolumeAlloc(total_block * total_block, block_size, block_size)) == NULL) { QccErrorAddMessage("(QccWAVdcttceCreateDCTSubbandMatrix): Error calling QccVolumeAlloc()"); goto Error; } /* Intialize to column size matrix */ for (i = 0; i < row; i++) for (j = 0; j < row; j++) array_val[i][j] = i; /* Convert it in the three-d volume space */ for (i = 0; i < total_block; i++) for (j = 0; j < total_block; j++) for (m = 0; m < block_size; m++) for (n = 0; n < block_size; n++) row_3D[(i*total_block)+ j][m][n] = array_val[(i * block_size) + m][(j * block_size) + n]; for (m = 0; m < 3*num_levels + 1; m++) { k = (int) ceil(((double)m) / 3) - 1; for (i = 0;i < total_block; i++) for (j = 0; j < total_block; j++) if (m == 0) dctwav_matrix[i][j] = row_3D[(i*total_block) + j][0][0]; else { if ((m % 3) == 1) ps_rs = 0; else ps_rs=(int)pow(2, k); for (r_w = ((int)pow(2, k) * i); r_w < (int)pow(2,k) * (i + 1); r_w++) { if ((m % 3) == 2) ps_cs = 0; else ps_cs = (int)pow(2, k); for (r_c = ((int)pow(2, k) * j); r_c < ((int)pow(2, k) * (j + 1)); r_c++) { if ((m % 3) == 1) dctwav_matrix[r_w + (int)(pow(2, k) * total_block)] [r_c] = row_3D[(i) * total_block + j][ps_rs][ps_cs]; else if ((m % 3) == 2) dctwav_matrix[r_w] [r_c + (int)(pow(2, k)*total_block)] = row_3D[(i) * total_block + j ][ps_rs][ps_cs]; else dctwav_matrix[r_w + (int)(pow(2, k) * total_block)] [r_c + ((int)pow(2,k)*total_block)] = row_3D[(i) * total_block + j][ps_rs][ps_cs]; ps_cs = ps_cs + 1; } ps_rs = ps_rs + 1; } } } return_value = 0; goto Return; Error: return_value = 1; Return: QccMatrixIntFree(array_val, row); QccVolumeFree(row_3D, total_block * total_block, block_size); return(return_value);}static int QccWAVdcttceEncodeDCT(QccWAVSubbandPyramid *image_subband_pyramid, char **sign_array, const QccIMGImageComponent *image, int num_levels, double *image_mean, int *max_coefficient_bits, double stepsize, int overlap_sample, double smooth_factor){ int return_value; double coefficient_magnitude; double max_coefficient; int num_subbands,subband; int row, col, m, n; int subband_origin_row; int subband_origin_col; int subband_num_rows; int subband_num_cols; QccMatrixInt dctrow_array = NULL; QccIMGImageComponent dctimage; int block_size; QccIMGImageComponentInitialize(&dctimage); /* Get the number of subbands */ num_subbands = QccWAVSubbandPyramidNumLevelsToNumSubbands(num_levels); /* Intialize the dct row array */ if ((dctrow_array = QccMatrixIntAlloc(image->num_rows, image->num_cols)) == NULL) { QccErrorAddMessage("(QccWAVdcttceEncodeDCT): Error calling QccMatrixIntAlloc()"); goto Error; } /* Allocate the memory for DCT image */ if (QccIMGImageComponentAlloc(&dctimage)) { QccErrorAddMessage("(QccWAVdcttceEncodeDCT): Error calling QccIMGImageComponentAlloc()"); goto Error; } /* Copy the Image into DCT to get a copy */ if (QccIMGImageComponentCopy(&dctimage, image)) { QccErrorAddMessage("(QccWAVdcttceEncodeDCT): Error calling QccIMGImageComponentCopy()"); goto Error; } /* Subtract Mean from the image to perform dct */ if (QccIMGImageComponentSubtractMean(&dctimage, image_mean, NULL)) { QccErrorAddMessage("(QccWAVdcttceEncodeDCT): Error calling QccIMGImageComponentSubtractMean()"); goto Error; } block_size = (1 << num_levels); if (QccIMGImageComponentLBT(&dctimage, &dctimage, overlap_sample, block_size, smooth_factor)) { QccErrorAddMessage("(QccWAVdcttceEncodeDCT): Error calling QccIMGImageComponentLBT()"); goto Error; } /* Generate the Matrix that contains the reference to correct index in dct matrix to dwt pyramid */ if (QccWAVdcttceCreateDCTSubbandMatrix(dctrow_array, num_levels, block_size, image->num_rows)) { QccErrorAddMessage("(QccWAVdcttceEncodeDCT): Error calling QccDCT2SubnandMatrix()"); goto Error; } for (m = 0; m < image->num_rows; m++) for (n = 0; n < image->num_cols; n++) image_subband_pyramid->matrix[m][n] = dctimage.image[dctrow_array[m][n]][dctrow_array[n][m]]; /* Change the image_subband_pyramid num_levels so that it works correctly */ image_subband_pyramid->num_levels = num_levels; for (subband = 0; subband < num_subbands; subband++) { if (QccWAVSubbandPyramidSubbandSize(image_subband_pyramid, subband, &subband_num_rows, &subband_num_cols)) { QccErrorAddMessage("(QccWAVdcttceEncodeDCT): Error calling QccWAVSubbandPyramidSubbandSize()"); goto Error; } if (QccWAVSubbandPyramidSubbandOffsets(image_subband_pyramid, subband, &subband_origin_row, &subband_origin_col)) { QccErrorAddMessage("(QccSubbabdtceEncodeDCT): Error calling QccWAVSubbandPyramidSubbandOffsets()"); goto Error; } max_coefficient = -MAXFLOAT; if (stepsize > 0) for (row = 0; row < subband_num_rows; row++) for (col = 0; col < subband_num_cols; col++) { coefficient_magnitude = floor(fabs(image_subband_pyramid->matrix [subband_origin_row + row] [subband_origin_col + col] / stepsize)); if (image_subband_pyramid->matrix [subband_origin_row + row] [subband_origin_col + col] < 0) sign_array [subband_origin_row + row] [subband_origin_col + col] = 1; else sign_array [subband_origin_row + row] [subband_origin_col + col] = 0; image_subband_pyramid->matrix [subband_origin_row + row] [subband_origin_col + col] = coefficient_magnitude; if (coefficient_magnitude > max_coefficient) max_coefficient = coefficient_magnitude; } else for (row = 0; row < subband_num_rows; row++) for (col = 0; col < subband_num_cols; col++) { coefficient_magnitude = fabs(image_subband_pyramid->matrix [subband_origin_row + row] [subband_origin_col + col]); if (image_subband_pyramid->matrix [subband_origin_row + row] [subband_origin_col + col] < 0) sign_array [subband_origin_row + row] [subband_origin_col + col] = 1; else sign_array [subband_origin_row + row] [subband_origin_col + col] = 0; image_subband_pyramid->matrix [subband_origin_row + row] [subband_origin_col + col] = coefficient_magnitude; if (coefficient_magnitude > max_coefficient) max_coefficient = coefficient_magnitude; } max_coefficient_bits[subband] = (int)floor(QccMathMax(0, QccMathLog2(max_coefficient + 0.0001))); } return_value = 0; goto Return; Error: return_value = 1; Return: QccMatrixIntFree(dctrow_array, image->num_rows); QccIMGImageComponentFree(&dctimage); return(return_value);}static int QccWAVdcttceEncodeBitPlaneInfo(QccBitBuffer *output_buffer, int num_subbands, int *max_coefficient_bits){ int subband; int num_zeros = 0; for (subband = 1; subband < num_subbands; subband++) { for (num_zeros = max_coefficient_bits[0] - max_coefficient_bits[subband]; num_zeros > 0; num_zeros--) if (QccBitBufferPutBit(output_buffer, 0)) return(1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -