📄 watermethod.cpp
字号:
// Watermethod.cpp: implementation of the CWatermethod class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DCTWater.h"
#include "Watermethod.h"
#include <math.h>
#include "io.h"
#include "DCTWaterDoc.h"
#include "fcntl.h"
#include "math.h"
#include "time.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CWatermethod::CWatermethod()
{
}
CWatermethod::~CWatermethod()
{
}
void CWatermethod::BitDecomposition(unsigned char *bytes,unsigned char *bits,long int numberofbytes)
{
long int i;
unsigned char bt;
for(i=0;i<numberofbytes;i++)
{
bt=bytes[i];
if(bt>=128)
{
bits[i*8+7]=1;
bt=bt-128;
}
else
bits[i*8+7]=0;
if(bt>=64)
{
bits[i*8+6]=1;
bt=bt-64;
}
else
bits[i*8+6]=0;
if(bt>=32)
{
bits[i*8+5]=1;
bt=bt-32;
}
else
bits[i*8+5]=0;
if(bt>=16)
{
bits[i*8+4]=1;
bt=bt-16;
}
else
bits[i*8+4]=0;
if(bt>=8)
{
bt=bt-8;
bits[i*8+3]=1;
}
else
bits[i*8+3]=0;
if(bt>=4)
{
bt=bt-4;
bits[i*8+2]=1;
}
else
bits[i*8+2]=0;
if(bt>=2)
{
bt=bt-2;
bits[i*8+1]=1;
}
else
bits[i*8+1]=0;
bits[i*8]=bt;
}
}
void CWatermethod::ByteComposition(unsigned char *bits,unsigned char *bytes,long int numberofbytes)
{
long int i;
for(i=0;i<numberofbytes;i++)
{
bytes[i]=(bits[i*8+7]&1)*128;
bytes[i]+=(bits[i*8+6]&1)*64;
bytes[i]+=(bits[i*8+5]&1)*32;
bytes[i]+=(bits[i*8+4]&1)*16;
bytes[i]+=(bits[i*8+3]&1)*8;
bytes[i]+=(bits[i*8+2]&1)*4;
bytes[i]+=(bits[i*8+1]&1)*2;
bytes[i]+=(bits[i*8]&1)*1;
}
}
void CWatermethod::Permuted(unsigned char *original,unsigned char *permuted,long int *key,long int number,int method)
{
long int i,j;
for(i=0;i<number;i++)
key[i]=i;
if(method==0)
{
long int *keytemp1,*keytemp2;
double tt;
if(number<4||number>65536)return;
for(i=0;i<number;i++)
key[i]=i;
srand((unsigned)time(NULL));
tt=1.0/32767.0*(number-1);
for(keytemp1=key;keytemp1<key+number;keytemp1++)
{
*keytemp1=(int)((double)rand()*tt);
for(keytemp2=key;keytemp2<keytemp1;keytemp2++)
{
if(*keytemp1==*keytemp2)
{
*keytemp1=(int)((double)rand()*tt);
keytemp2=key;
keytemp1=keytemp1-1;
}
}
}
}
else if(method==1)
{
int bit[16];
long int a,b,scale,temp;
long int tempkey[65536];
double tt;
if(number<4||number>65536)return;
for(i=0;i<number;i++)
key[i]=i;
//取得m序列的阶数
scale=0;//scale 级反馈移位寄存器--用于产生长为2^scale-1的m序列
temp=number;
while(temp!=1)//求阶数
{
temp=temp/2;
scale=scale+1;
}
//产生一个[0,2^scale-1]之间的随机数a 2^scale=number
srand((unsigned)time(NULL));
tt=1.0/32767.0*(number-1);
a=(long int)((double)rand()*tt);
key[a]=0;//令该地址的数为0
b=0;
while(b==0)b=(long int)((double)rand()*tt);
tempkey[0]=b;//设m序列初值为1到number-1的随机数
for(i=0;i<number-1;i++)//周期为number-1,产生从1到number-1的伪随机值
{
for(j=0;j<scale;j++)//取各位0/1值-->bit[i]
{
temp=tempkey[i]>>j;
bit[j]=temp&1;
}
switch(scale)//作模2加法
{
case 2:
temp=bit[0]+bit[1];
break;
case 3:
temp=bit[0]+bit[2];
break;
case 4:
temp=bit[0]+bit[3];
break;
case 5:
temp=bit[0]+bit[3];
break;
case 6:
temp=bit[0]+bit[5];
break;
case 7:
temp=bit[0]+bit[4];
break;
case 8:
temp=bit[0]+bit[4]+bit[5]+bit[6];
break;
case 9:
temp=bit[0]+bit[5];
break;
case 10:
temp=bit[0]+bit[7];
break;
case 11:
temp=bit[0]+bit[9];
break;
case 12:
temp=bit[0]+bit[6]+bit[8]+bit[11];
break;
case 13:
temp=bit[0]+bit[9]+bit[10]+bit[12];
break;
case 14:
temp=bit[0]+bit[4]+bit[8]+bit[13];
break;
case 15:
temp=bit[0]+bit[14];
break;
case 16:
temp=bit[0]+bit[4]+bit[13]+bit[15];
break;
default:
break;
}
bit[scale]=temp&1;
tempkey[i]=(long int)(bit[scale]*(pow(2,(scale-1)))+(tempkey[i]>>1));
tempkey[i+1]=tempkey[i];
}
for(i=0;i<number;i++)
{
if(i<a)
key[i]=tempkey[i];
if(i>a)
key[i]=tempkey[i-1];
}
}
else if(method==2)
//Generate a key--random number sequence
{
long int *keytemp1,*keytemp2,keytemp;
for(j=0;j<256*256;j++)
{
key[j]=j;
}
for(keytemp1=key;keytemp1<key+number;keytemp1++)
{
for(keytemp2=key;keytemp2<keytemp1;keytemp2++)
{
if(original[*keytemp2]>original[*keytemp1])
{
//Exchange the values of two elements
keytemp=*keytemp2;
*keytemp2=*keytemp1;
*keytemp1=keytemp;
keytemp2=key;
keytemp1=keytemp1-1;
}
}
}
}
//Generate ordinal sequence
for(i=0;i<number;i++)
{
j=key[i];
permuted[i]=original[j];
}
}
void CWatermethod::ReversePermuted(unsigned char *permuted,unsigned char *reverse,long int *key,long int number)
{
long int i,j;
for(i=0;i<number;i++)
{
j=key[i];
reverse[j]=permuted[i];
}
}
/////////////////////////////////////////////////////////////////////////////////
///////////The Program of DCT and the IDCT in Unsigned Char Format//////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//The Define of DCT--Discrete Cosine Transform
//F(k1,k2)=DCT(f(n1,n2))=c1[k1]c2[k2]∑(i=0:1:N1-1)∑(j=0:1:N2-1)f(i,j)
// *cos(((2*n1+1)/(2*N1))*PI*k1)*cos(((2*n2+1)/(2*N2))*PI*k2)
//c1[i]=sqrt(1/N1) if i==0; c1[i]=sqrt(2/N1) if i!=0;
//c2[i]=sqrt(1/N2) if i==0; c2[j]=sqrt(2/N2) if i!=0;
void CWatermethod::DCT(unsigned char *OriginalImageBlock[MAXBLOCKHEIGHT],double *DCTBlock[MAXBLOCKHEIGHT],int blockheight,int blockwidth) //input[0] the row pointer of the input matrix
{
int i; //Define the repeating variable
int timerow,timecolumn; //Define the input interative variable(Time Domain)
int frerow,frecolumn; //Define the output interative variable(Frequency Domain)
double row[MAXBLOCKHEIGHT]; //Define the parameter of the first parameter
double column[MAXBLOCKWIDTH]; //Define the parameter of the second parameter
double temp; //Define the temporary variable
double temp1; //Define the first temporary variable
double temp2; //Define the second temporary variable
//Initiaize the transform parameters
row[0]=sqrt(1.0/blockheight);
column[0]=sqrt(1.0/blockwidth);
for(i=1;i<blockheight;i++)
{
row[i]=sqrt(2.0/blockheight);
}
for(i=1;i<blockwidth;i++)
{
column[i]=sqrt(2.0/blockwidth);
}
//Calculate the DCT of blockheight*blockwidth points
for(frerow=0;frerow<blockheight;frerow++)
{
for(frecolumn=0;frecolumn<blockwidth;frecolumn++)
{
//Calculate the DCT for one point
temp1=0.0;
for(timerow=0;timerow<blockheight;timerow++)
{
temp2=0;
for(timecolumn=0;timecolumn<blockwidth;timecolumn++)
{
temp=(2.0*timecolumn+1.0)/(2.0*blockwidth)*frecolumn*PI;
temp2=temp2+OriginalImageBlock[timerow][timecolumn]*cos(temp);
}
temp=(2.0*timerow+1.0)/(2.0*blockheight)*frerow*PI;
temp1=temp1+temp2*cos(temp);
}
DCTBlock[frerow][frecolumn]=temp1*row[frerow]*column[frecolumn];
}
}
}
//IDCT(F(k1,k2))=(1/N1)*(1/N2)∑(k1=0:1:N1-1)∑(k2=0:1:N2-1)c1[k1]c2[k2]*F(k1,k2)
// *cos(((2*n1+1)/(2*N1))*PI*k1)*cos(((2*n2+1)/(2*N2))*PI*k2)
//c1[i]=sqrt(1/N1) if i==0; c1[i]=sqrt(2/N1) if i!=0;
//c2[i]=sqrt(1/N2) if i==0; c2[j]=sqrt(2/N2) if i!=0;
void CWatermethod::IDCT(double *DCTBlock[MAXBLOCKHEIGHT],unsigned char *ReconstructedImageBlock[MAXBLOCKHEIGHT],int blockheight,int blockwidth) //input[0] the row pointer of the input matrix
{
int i; //Define the repeating variable
int frerow,frecolumn; //Define the input interative variable(Frequency Domain)
int timerow,timecolumn; //Define the output interative variable(Time Domain)
double row[MAXBLOCKHEIGHT]; //Define the parameter of the first parameter
double column[MAXBLOCKWIDTH]; //Define the parameter of the second parameter
double temp; //Define the temporary variable
double temp1; //Define the first temporary variable
double temp2; //Define the second temporary variable
//Initiaize the transform parameters
row[0]=sqrt(1.0/blockheight);
column[0]=sqrt(1.0/blockwidth);
for(i=1;i<blockheight;i++)
{
row[i]=sqrt(2.0/blockheight);
}
for(i=1;i<blockwidth;i++)
{
column[i]=sqrt(2.0/blockwidth);
}
//Calculate the IDCT of blockheight*blockwidth points
for(timerow=0;timerow<blockheight;timerow++)
{
for(timecolumn=0;timecolumn<blockwidth;timecolumn++)
{
//Calculate the IDCT of one point
temp1=0.0;
for(frerow=0;frerow<blockheight;frerow++)
{
temp2=0.0;
for(frecolumn=0;frecolumn<blockwidth;frecolumn++)
{
temp=(2.0*timecolumn+1.0)/(2.0*blockwidth)*frecolumn*PI;
temp2=temp2+DCTBlock[frerow][frecolumn]*cos(temp)*column[frecolumn];
}
temp=(2.0*timerow+1.0)/(2.0*blockheight)*frerow*PI;
temp1=temp1+temp2*cos(temp)*row[frerow];
}
//The Rounding Operation (To The Nearest Integer Number)
if(temp1>=254.5)
{
ReconstructedImageBlock[timerow][timecolumn]=255;
}
else
{
if(temp1<0.5)
{
ReconstructedImageBlock[timerow][timecolumn]=0;
}
else
{
ReconstructedImageBlock[timerow][timecolumn]=(unsigned char)(temp1+0.5);
}
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////
///////////The Program of DCT and the IDCT in Unsigned Char Format//////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//The Define of DCT--Discrete Cosine Transform
//F(k1,k2)=DCT(f(n1,n2))=c1[k1]c2[k2]∑(i=0:1:N1-1)∑(j=0:1:N2-1)f(i,j)
// *cos(((2*n1+1)/(2*N1))*PI*k1)*cos(((2*n2+1)/(2*N2))*PI*k2)
//c1[i]=sqrt(1/N1) if i==0; c1[i]=sqrt(2/N1) if i!=0;
//c2[i]=sqrt(1/N2) if i==0; c2[j]=sqrt(2/N2) if i!=0;
void CWatermethod::DCT1(char *OriginalImageBlock[MAXBLOCKHEIGHT],double *DCTBlock[MAXBLOCKHEIGHT],int blockheight,int blockwidth) //input[0] the row pointer of the input matrix
{
int i; //Define the repeating variable
int timerow,timecolumn; //Define the input interative variable(Time Domain)
int frerow,frecolumn; //Define the output interative variable(Frequency Domain)
double row[MAXBLOCKHEIGHT]; //Define the parameter of the first parameter
double column[MAXBLOCKWIDTH]; //Define the parameter of the second parameter
double temp; //Define the temporary variable
double temp1; //Define the first temporary variable
double temp2; //Define the second temporary variable
//Initiaize the transform parameters
row[0]=sqrt(1.0/blockheight);
column[0]=sqrt(1.0/blockwidth);
for(i=1;i<blockheight;i++)
{
row[i]=sqrt(2.0/blockheight);
}
for(i=1;i<blockwidth;i++)
{
column[i]=sqrt(2.0/blockwidth);
}
//Calculate the DCT of blockheight*blockwidth points
for(frerow=0;frerow<blockheight;frerow++)
{
for(frecolumn=0;frecolumn<blockwidth;frecolumn++)
{
//Calculate the DCT for one point
temp1=0.0;
for(timerow=0;timerow<blockheight;timerow++)
{
temp2=0;
for(timecolumn=0;timecolumn<blockwidth;timecolumn++)
{
temp=(2.0*timecolumn+1.0)/(2.0*blockwidth)*frecolumn*PI;
temp2=temp2+OriginalImageBlock[timerow][timecolumn]*cos(temp);
}
temp=(2.0*timerow+1.0)/(2.0*blockheight)*frerow*PI;
temp1=temp1+temp2*cos(temp);
}
DCTBlock[frerow][frecolumn]=temp1*row[frerow]*column[frecolumn];
}
}
}
/*
//IDCT(F(k1,k2))=(1/N1)*(1/N2)∑(k1=0:1:N1-1)∑(k2=0:1:N2-1)c1[k1]c2[k2]*F(k1,k2)
// *cos(((2*n1+1)/(2*N1))*PI*k1)*cos(((2*n2+1)/(2*N2))*PI*k2)
//c1[i]=sqrt(1/N1) if i==0; c1[i]=sqrt(2/N1) if i!=0;
//c2[i]=sqrt(1/N2) if i==0; c2[j]=sqrt(2/N2) if i!=0;
void CWatermethod::IDCT1(double *DCTBlock[MAXBLOCKHEIGHT],char *ReconstructedImageBlock[MAXBLOCKHEIGHT],int blockheight,int blockwidth) //input[0] the row pointer of the input matrix
{
int i; //Define the repeating variable
int frerow,frecolumn; //Define the input interative variable(Frequency Domain)
int timerow,timecolumn; //Define the output interative variable(Time Domain)
double row[MAXBLOCKHEIGHT]; //Define the parameter of the first parameter
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -