⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 watermethod.cpp

📁 站长!这是DCT域的图像数字水印嵌入及提取程序!请查收!暂归入加密解密类别!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// 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 + -