📄 intlbt.cpp
字号:
// IntLBT.cpp: implementation of the CIntLBT class.
// 作者:张增辉 国防科技大学理学院数学系 2001.11
// QQ:15105473 email: zenghui1980@163.com
//
// 此为整数叠式变换的程序,算法流程图有成老师文章给出。
// IntLBT 没有经过边界的延拓,可以做到完全无损的变换。 但是变换后的数据
// 存在边界存在4个数据的边。 因此在编码时候需要特殊的处理。
//
// 程序包括以下部分: IntDCT and I_IntDCT
// DCT_Butterfly and I_DCT_Butterfly .... the butterfly after IntDCT
// IntLBT and I_IntLBT after DCT_Butterfly
// IntLBT2D and I_IntLBT2D
////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ImgPro_IntLBT.h"
#include "IntLBT.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CIntLBT::CIntLBT()
{
}
CIntLBT::~CIntLBT()
{
}
void CIntLBT::IntLBT2D(int **data, int height, int width)
{
int i,j,k;
int nheight, nwidth;
nheight = (height >>3); // 列分块的数目
nwidth = (width >>3); // 行分块的数目
int n_write_data, *data_lap1, *data_lap2; // n_write_data 为写数据位置
data_lap1 = new int [8];
data_lap2 = new int [8];
/// 先对行进行IntLBT 变换
for (i=0; i<height; i++)
{
for (k=0; k<8; k++) *(data_lap1+k) = *(*(data+i) + k); //读取开始的8个点
DCT_Butterfly1D(data_lap1); //
for (k=0; k<4; k++) *(*(data+i) +k) = *(data_lap1+k); // 边界处理, 不做蝶式变换
n_write_data = 4;
for (j=1; j<nwidth-1; j++)
{
for (k=0; k<8; k++) *(data_lap2+k) = *(*(data + i) + n_write_data+k+4); //读取下8个点
DCT_Butterfly1D(data_lap2); //
IntLBT1D(data_lap1, data_lap2); // 蝶式变换 ,8+8 -----> 8
for (k=0; k<8; k++) *(*(data+i)+n_write_data+k) = *(data_lap1 + k); //变换后数据写入
for (k=0; k<8; k++) *(data_lap1 + k) = *(data_lap2 + k); //交换数据 供下一次变换使用
n_write_data += 8; // 移动写入标志
}
for (k=0; k<8; k++) *(data_lap2+k) = *(*(data + i) + n_write_data+k+4); //
DCT_Butterfly1D(data_lap2); //
IntLBT1D(data_lap1, data_lap2); //
for (k=0; k<8; k++) *(data_lap2+k) = *(*(data + i) + n_write_data+k+4); //
for (k=0; k<8; k++) *(*(data+i)+n_write_data+k) = *(data_lap1 + k); //
n_write_data += 8; // 计算到数第二块数据, 并保证最后8个数据不被破坏
DCT_Butterfly1D(data_lap2);
for (k=0; k<4; k++) *(*(data+i)+n_write_data+k) = *(data_lap2+k+4); // 边界处理
}
//对每一行做 IntLBT 变换结束
//按列进行
for (i=0; i<width; i++)
{
for (k=0; k<8; k++) *(data_lap1+k) = *(*(data+k) + i);
DCT_Butterfly1D(data_lap1);
for (k=0; k<4; k++) *(*(data+k) +i) = *(data_lap1+k);
n_write_data = 4;
for (j=1; j<nheight-1; j++)
{
for (k=0; k<8; k++) *(data_lap2+k) = *(*(data+n_write_data+k+4) + i);
DCT_Butterfly1D(data_lap2);
IntLBT1D(data_lap1, data_lap2);
for (k=0; k<8; k++) *(*(data+n_write_data+k)+i) = *(data_lap1 + k);
for (k=0; k<8; k++) *(data_lap1 + k) = *(data_lap2 + k);
n_write_data += 8;
}
for (k=0; k<8; k++) *(data_lap2+k) = *(*(data+n_write_data+k+4) + i);
DCT_Butterfly1D(data_lap2);
IntLBT1D(data_lap1, data_lap2);
for (k=0; k<8; k++) *(data_lap2+k) = *(*(data+n_write_data+k+4) + i);
for (k=0; k<8; k++) *(*(data+n_write_data+k)+i) = *(data_lap1 + k);
n_write_data += 8;
DCT_Butterfly1D(data_lap2);
for (k=0; k<4; k++) *(*(data+n_write_data+k)+i) = *(data_lap2+k+4);
}
delete data_lap1;
delete data_lap2;
}
void CIntLBT::I_IntLBT2D(int **data, int height, int width)
{
int i, j, k;
int nheight, nwidth;
nheight = (height >>3);
nwidth = (width >>3);
int n_write_data, *data_lap1, *data_lap2, *data_tmp;;
data_lap1 = new int [8];
data_lap2 = new int [8];
data_tmp = new int [8];
////////////////// 先按列做逆变换
for (i=0; i<width; i++)
{
//处理最开始的8个数据
for (k=0; k<4; k++) *(data_lap1+k) = *(*(data+k)+i); //读入前面4个数据
//处理下4个数据
for (k=0; k<8; k++) *(data_lap2+k) = *(*(data+k+4)+i); //读入下8个数据
I_IntLBT_1to1(data_lap2);
for (k=0; k<4; k++) *(data_lap1+k+4) = *(data_lap2+k);
I_DCT_Butterfly(data_lap1); //反变换求出前8个数据
for (k=0; k<8; k++) *(data_lap2+k) = *(*(data+k+4)+i);
for (k=0; k<8; k++) *(*(data+k)+i) = *(data_lap1+k); //写入数据
//处理中间的数据
for (k=0; k<8; k++) *(data_lap1+k) = *(data_lap2+k); //读入第一块
n_write_data = 8;
for (j=2; j<nheight; j++)
{
for (k=0; k<8; k++)
{
*(data_lap2+k) = *(*(data+4+n_write_data+k)+i); //读入下一块
*(data_tmp+k) = *(data_lap2+k); // 在反变换之前备份当前数据
}
I_IntLBT1D(data_lap1, data_lap2);
I_DCT_Butterfly(data_lap1);
for (k=0; k<8; k++) *(*(data+n_write_data+k)+i) = *(data_lap1+k); //写入数据
for (k=0; k<8; k++) *(data_lap1+k) = *(data_tmp+k);
n_write_data += 8;
}
//处理最后的8个数据
I_IntLBT_1to1(data_lap1);
for (k=0; k<4; k++) *(data_lap1+k) = *(data_lap1+k+4);
for (k=0; k<4; k++) *(data_lap1+k+4) = *(*(data+n_write_data+k+4)+i);
I_DCT_Butterfly(data_lap1);
for (k=0; k<8; k++) *(*(data+n_write_data+k)+i) = *(data_lap1+k);
}
////////////////// 按行做逆变换
for (i=0; i<height; i++)
{
//处理最开始的8个数据
for (k=0; k<4; k++) *(data_lap1+k) = *(*(data+i)+k); //读入前面4个数据
//处理下4个数据
for (k=0; k<8; k++) *(data_lap2+k) = *(*(data+i)+k+4); //读入下8个数据
I_IntLBT_1to1(data_lap2);
for (k=0; k<4; k++) *(data_lap1+k+4) = *(data_lap2+k);
I_DCT_Butterfly(data_lap1); //反变换求出前8个数据
for (k=0; k<8; k++) *(data_lap2+k) = *(*(data+i)+k+4);
for (k=0; k<8; k++) *(*(data+i)+k) = *(data_lap1+k); //写入数据
//处理中间的数据
for (k=0; k<8; k++) *(data_lap1+k) = *(data_lap2+k); //读入第一块
n_write_data = 8;
for (j=2; j<nwidth; j++)
{
for (k=0; k<8; k++)
{
*(data_lap2+k) = *(*(data+i)+4+n_write_data+k); //读入下一块
*(data_tmp+k) = *(data_lap2+k);
}
I_IntLBT1D(data_lap1, data_lap2);
I_DCT_Butterfly(data_lap1);
for (k=0; k<8; k++) *(*(data+i)+n_write_data+k) = *(data_lap1+k); //写入数据
for (k=0; k<8; k++) *(data_lap1+k) = *(data_tmp+k);
n_write_data += 8;
}
//处理最后的8个数据
for (k=0; k<8; k++) *(data_lap2+k) = *(data_lap1+k); //读入最后一个完整的变换后的块
I_IntLBT_1to1(data_lap2);
for (k=0; k<4; k++) *(data_lap1+k) = *(data_lap2+k+4);
for (k=0; k<4; k++) *(data_lap1+k+4) = *(*(data+i)+n_write_data+k+4);
I_DCT_Butterfly(data_lap1);
for (k=0; k<8; k++) *(*(data+i)+n_write_data+k) = *(data_lap1+k);
}
delete data_lap1;
delete data_lap2;
delete data_tmp;
}
void CIntLBT::IntLBT1D(int *data1, int *data2)
{
/// input the two block ------> data1 data2
/// output the lapped data -----> data1
// DCT_Butterfly1D(data1);
// DCT_Butterfly1D(data2);
*data1 = *(data1+4) + *data2;
*(data1+1) = *(data1+5) + *(data2+1);
*(data1+2) = *(data1+6) + *(data2+2);
*(data1+3) = *(data1+7) + *(data2+3);
*(data1+4) = *(data1+4) - *data2;
*(data1+5) = *(data1+5) - *(data2+1);
*(data1+6) = *(data1+6) - *(data2+2);
*(data1+7) = *(data1+7) - *(data2+3);
//做一个 旋转变换
*(data1+5) = *(data1+5) + (*(data1+4) >>2) - (*(data1+4) >>5);
*(data1+4) = *(data1+4) - (*(data1+5) >>2) - (*(data1+5) >>3) - (*(data1+5) >>5);
*(data1+5) = *(data1+5) + (*(data1+4) >>2) - (*(data1+4) >>5);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -