http://bcn.bathome.net/s/tool/index.html?key=dct
使用了DCT离散余弦变换,可以在图片中嵌入全盲数字水印,利用模拟量子态,成功解决信息的稳定性。图片即使被调色,被ps处理,其嵌入的数字水印依然可读取。本工具采取非开源策略。
使用说明:- 加数字盲水印:
- dct [输入图片] [输出图片] [水印字符串]
- 解数字盲水印:
- dct [输入图片]
复制代码
核心函数- // 离散余弦变换核心
- 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;
- }
复制代码
|