// 离散余弦变换核心
int DCT2D(double* cMatrix, double* pBmpMatrix, double* cMatrixT, int Nx, int Ny, int N, DCT2Mode mode, byte* insertData, int insertLen)
{
// 如果在编码模式下
if(mode == DCT2_ENCODE_MODE)
{
// 检测插入长度是否合法
if
(
(insertLen <= 0) ||
(insertLen > Nx * Ny / 8) ||
(Nx == 0) ||
(Ny == 0)
)
{
// 插入数据量过大,则退出
fprintf(stdout, "You can't inserted bytes to the picture\n");
exit(1);
}
}
// 辅助数组
double* pTmp = (double*)malloc(N * N * sizeof(double));
int pBmpMatrixWith = Nx * N;
// 插入索引位
int insertIndex = 0;
// 分块DCT变换
for(int j = 0; j < Ny; j ++)
{
for(int i = 0; i < Nx; i ++)
{
int xOffset = i * N;
int yOffset = j * N * pBmpMatrixWith;
// 正交化乘以系数矩阵
for(int dy = 0; dy < N; dy ++)
{
for(int dx = 0; dx < N; dx ++)
{
double sum = 0.0f;
for(int sn = 0; sn < N; sn ++)
{
sum += (*(cMatrix + (dy * N + sn))) * (*(pBmpMatrix + (yOffset + sn * pBmpMatrixWith) + (xOffset+ dx)));
}
*(pTmp + (dy * N + dx)) = sum;
}
}
// 正交化乘以转置系数矩阵
for(int dy = 0; dy < N; dy ++)
{
for(int dx = 0; dx < N; dx ++)
{
double sum = 0.0f;
for(int sn = 0; sn < N; sn ++)
{
sum += (*(pTmp + (dy * N + sn))) * (*(cMatrixT + (sn * N) + dx));
}
*(pBmpMatrix + (yOffset + dy * pBmpMatrixWith) + (xOffset+ dx)) = sum;
}
}
// 逆变换模式
if(mode == DCT2_INVERSE_TRANSFORM)
{
continue;
}
// 编码模式
if(mode == DCT2_ENCODE_MODE)
{
double* pA = pBmpMatrix + (yOffset + 5 * pBmpMatrixWith) + (xOffset+ 5);
double* pB = pBmpMatrix + (yOffset + 6 * pBmpMatrixWith) + (xOffset+ 6);
// 采集密文bit位
int insertV = ((int)(*(insertData + insertIndex / 8))) & ((int)(0x80 >> (insertIndex & 7)));
if(insertV == 0)
{
if(*pA > *pB)
{
SWAP_DOUBLE(*pA, *pB);
}
*pB += 1.0f;
}
else
{
if(*pA < *pB)
{
SWAP_DOUBLE(*pA, *pB);
}
*pB -= 1.0f;
}
// 插入计数器
insertIndex ++;
continue;
}
// 解码模式
if(mode == DCT2_DECODE_MODE)
{
double* pA = pBmpMatrix + (yOffset + 5 * pBmpMatrixWith) + (xOffset+ 5);
double* pB = pBmpMatrix + (yOffset + 6 * pBmpMatrixWith) + (xOffset+ 6);
byte* pInsertV = (byte*)(insertData + (insertIndex >> 3));
if(*pA > *pB)
{
*pInsertV |= (byte)(0x80 >> (insertIndex & 7));
}
// 插入计数器
insertIndex ++;
continue;
}
}
}
// 释放辅助数组
free(pTmp);
return 0;
}