lsbanalysisdoc.cpp

来自「信息隐藏中用于数字隐写的常用算法:LSB替换LSB匹配,包括随机的和排序的,以及」· C++ 代码 · 共 1,714 行 · 第 1/4 页

CPP
1,714
字号
}


//..........................................................//
//                    随机LSB Replace嵌入                   //
//         pImg:图像数据指针, pData:嵌入数据指针            //
//                  pImgPerm:图像置乱后的排序               //
//         dwImgSize:图像大小, dwCount:嵌入数据大小         //
//..........................................................//
void CLSBAnalysisDoc::LSBReplaceEmbed(BYTE* pImg, BYTE* pData, int* pImgPerm,
									  DWORD dwImgSize, float ratio)
{
	//判断条件
	if (pImg == NULL || pData == NULL)
		return;
	if( ratio == 0.0)
		return;

//.....................嵌入.............................
	DWORD i;
	DWORD  dwCurPos = 0;
//	srand((unsigned)time(NULL));
	long nSeed = (unsigned)time(NULL) % 1048576;	

	DWORD dwCount0 = 0;       //在嵌入数据中(非全部图像数据中)LSB 没有改变的次数
	DWORD dwCount1 = 0;       //LSB-1次数
	DWORD dwCount2 = 0;       //LSB+1次数
	
	double t = 0.0;
	int nTemp = 0;         //+1 or -1

	DWORD dwCount = 0;        //嵌入数据个数
	dwCount = DWORD(dwImgSize * ratio);
	for( i = 0; i < dwCount; i++)
	{
		dwCurPos = (DWORD)pImgPerm[i];

		//随机LSB Replace过程
		pImg[dwCurPos] = (pImg[dwCurPos] & 0xFE) + pData[i];
	}

}


//..........................................................//
//                    序贯LSB Replace嵌入                   //
//         pImg:图像数据指针, pData:嵌入数据指针            //
//         dwImgSize:图像大小, dwCount:嵌入数据大小         //
//..........................................................//
void CLSBAnalysisDoc::LSBReplaceEmbed2(BYTE* pImg, BYTE* pData,
									DWORD dwImgSize, float ratio)
{
	//判断条件
	if (pImg == NULL || pData == NULL)
		return;
	if( ratio == 0.0)
		return;

//...........................嵌入............................
	DWORD  i = 0;
//	srand((unsigned)time(NULL));
	long nSeed = (unsigned)time(NULL) % 1048576;	

	DWORD dwCount0 = 0;       //在嵌入数据中(非全部图像数据中)LSB 没有改变的次数
	DWORD dwCount1 = 0;       //LSB-1次数
	DWORD dwCount2 = 0;       //LSB+1次数
	
	double t = 0.0;
	int nTemp = 0;         //+1 or -1

	DWORD dwCount = 0;        //嵌入数据个数
	dwCount = DWORD(dwImgSize * ratio);
	for( i = 0; i < dwCount; i++)
	{
		//序贯LSB Replace过程
		pImg[i] = (pImg[i] & 0xFE) + pData[i];
	}
}


//..........................................................//
//                    随机LSB Match提取                     //
//         pImg:图像数据指针,pImgPerm:图像置乱排序指针      //
//            dwImgSize:图像大小, ratio:嵌入率              //
//..........................................................//
BYTE* CLSBAnalysisDoc::LSBMatchExtract(BYTE* pImg, int* pImgPerm, DWORD dwImgSize, float ratio)
{

	ASSERT(dwImgSize != 0);
	ASSERT(pImgPerm != NULL);
	ASSERT(ratio != 0.0);

	DWORD dwCount = DWORD(dwImgSize * ratio);
	ASSERT((dwCount / 8) != 0);

	BYTE* pData = NULL;
	pData = new BYTE[dwCount / 8];
	memset(pData, 0, dwCount / 8 * sizeof(BYTE));
	ASSERT(pData != NULL);

	DWORD i, j;
	DWORD dwCurPos = 0;
	for (i = 0; i < dwCount / 8; i++)
	{
		for (j = 0; j < 8; j++)
		{
			dwCurPos = (DWORD)pImgPerm[i * 8 + j];
			pData[i] += (pImg[dwCurPos] & 1) << j;          //最低位->最高位 置bit
		}
	}

	return pData;

}

//..........................................................//
//                    序贯LSB Match提取                     //
//                    pImg:图像数据指针                     //
//            dwImgSize:图像大小, ratio:嵌入率              //
//..........................................................//
BYTE* CLSBAnalysisDoc::LSBMatchExtract2(BYTE* pImg, DWORD dwImgSize, float ratio)
{

	ASSERT(dwImgSize != 0);
	ASSERT(ratio != 0.0);

	DWORD dwCount = DWORD(dwImgSize * ratio);
	ASSERT((dwCount / 8) != 0);

	BYTE* pData = NULL;
	pData = new BYTE[dwCount / 8];
	memset(pData, 0, dwCount / 8 * sizeof(BYTE));
	ASSERT(pData != NULL);

	DWORD i, j;
	for (i = 0; i < dwCount / 8; i++)
	{
		for (j = 0; j < 8; j++)
		{
			pData[i] += (pImg[i * 8 + j] & 1) << j;          //最低位->最高位 置bit
		}
	}

	return pData;
}


//..........................................................//
//                    读取秘密数据                          //
//              nCount:待读数据, BYTE*:返回值              //
//..........................................................//
BYTE* CLSBAnalysisDoc::ReadPRNData(DWORD dwCount)
{
	ASSERT((dwCount / 8) > 0);
	BYTE*  pLSB  = new BYTE[dwCount];
	BYTE*  pData = new BYTE[dwCount / 8];


//	FILE* fPrn = fopen(PRN_FILE, "rb"); 
//	FILE* fPrn = fopen("E:\\PRN_DATA.dat", "rb"); 
	FILE* fPrn = fopen("E:\\刘学谦自己的成果\\randdata1.dat", "rb"); 

	if(fPrn != NULL)
	{
		fread( pData , 1 , dwCount / 8, fPrn);
		fclose(fPrn);
	}
	else
	{
		AfxMessageBox("读取秘密数据有误",MB_ICONINFORMATION);
		return NULL;
	}

	DWORD i, j, dwIndex;
	for(i = 0 ; i < dwCount / 8 ; i++)
		for(j = 0; j < 8; j++)
		{
			dwIndex = i * 8 + j;
			if( dwIndex > dwCount - 1) break;
			pLSB[dwIndex] = (pData[i]>>j) & 1;        //最低位->最高位取bit
		}
	
	if (pData != NULL) 
	{
		delete []pData;   pData = NULL;
	}
	return pLSB;
}

//..........................................................//
//                    读取秘密数据                          //
//              nCount:待读数据, BYTE*:返回值              //
//..........................................................//
BYTE* CLSBAnalysisDoc::ReadPRNData2(DWORD dwCount)
{
	ASSERT((dwCount / 8) > 0);
	BYTE*  pLSB  = new BYTE[dwCount];
	BYTE*  pData = new BYTE[dwCount / 8];


//	FILE* fPrn = fopen(PRN_FILE, "rb"); 
//	FILE* fPrn = fopen("E:\\PRN_DATA.dat", "rb"); 
	FILE* fPrn = fopen("E:\\刘学谦自己的成果\\randdata2.dat", "rb"); 

	if(fPrn != NULL)
	{
		fread( pData , 1 , dwCount / 8, fPrn);
		fclose(fPrn);
	}
	else
	{
		AfxMessageBox("读取秘密数据有误",MB_ICONINFORMATION);
		return NULL;
	}

	DWORD i, j, dwIndex;
	for(i = 0 ; i < dwCount / 8 ; i++)
		for(j = 0; j < 8; j++)
		{
			dwIndex = i * 8 + j;
			if( dwIndex > dwCount - 1) break;
			pLSB[dwIndex] = (pData[i]>>j) & 1;        //最低位->最高位取bit
		}
	
	if (pData != NULL) 
	{
		delete []pData;   pData = NULL;
	}
	return pLSB;
}


//-------------- 202 lty -------------//
//-----------Copyright 2002-----------//
//----混合同余法产生均匀分布随机数----//


/*-----------------------------------------------------------------------*/
/*    Generate the uniform data in (a,b) , *seed is the initial seed     */
/*-----------------------------------------------------------------------*/

double CLSBAnalysisDoc::uniform(double a,double b,long* seed)
{
	double t;
	*seed = 2045 * (*seed) + 1;
	*seed = *seed - (*seed/1048576) * 1048576; //floor. It's *seed = *seed mod 1048576
	t = (*seed) / 1048576.0;
	t = a + (b-a) * t;
	return t;
}


//....................Begin.....随机嵌入与提取中使用..........................
//              产生0~N-1的一个随机排列                //
//     输入: N (rand()的种子由前面的srand()决定)        //
//     输出: rp[N],需要输入时已开辟空间                //
void CLSBAnalysisDoc::Rand_Perm(int rp[], int N)
{
	int i;
	int *p;

	p = new int[N];  // if(p == NULL)  error();

	for(i=0; i<N; i++)
	{
		p[i] = rand();
	}

	Sort_Qck(p, rp, N);

	delete []p;
}


//................整数快速排序, 从小到大.................//
//                   输入: N, p[N]                       //
//         输出: 排序后的p[N], 及其索引index[N]          //
//      (即排序后的p[i]对应原来p中的index[i]位置)        //
void CLSBAnalysisDoc::Sort_Qck(int p[], int index[], int N)
{
	for(int i=0; i<N; i++)
	{
		index[i] = i;
	}
	QUICKSORT(p, index, 0, N-1);
}

//................对R[s1]到R[t1]快速排序..................//
void CLSBAnalysisDoc::QUICKSORT(int R[], int index[], int s1, int t1)
{
	int i;
	if( s1<t1 )
	{
		i = PARTITION(R, index, s1, t1);
		QUICKSORT(R, index, s1, i-1);
		QUICKSORT(R, index, i+1, t1);
	}
}
//.......................划分过程.........................//
int CLSBAnalysisDoc::PARTITION(int R[], int index[], int l, int h)
{
	int i, j, temp, temp_index;
	i = l; j = h; temp = R[i]; temp_index = index[i];
	do
	{
		while( (R[j]>=temp) && (i<j) )
			j--;
		if( i<j )
		{
			index[i] = index[j];
			R[i++] = R[j];
		}
		while( (R[i]<=temp) && (i<j) )
			i++;
		if( i<j )
		{
			index[j] = index[i];
			R[j--] = R[i];
		}
	}
	while( i != j);
	index[i] = temp_index;
	R[i] = temp;
	return i;
}
//...............................End............................




void CLSBAnalysisDoc::OnDetectHmm() 
{
	//确保打开文件不为空
	ASSERT(m_strPathName != _T(""));

//................得到图像基本信息....................
	DWORD dwHeight = image->GetHeight();           //高
	DWORD dwWidth = image->GetWidth();             //宽
	DWORD dwEffWidth  = image->GetEffWidth();      //实际宽度,对灰度图象为4倍数后的宽度;对彩色图像,为灰度图象宽度的3倍
	DWORD dwImgSize  = dwHeight * dwEffWidth;      //图像数据大小
	DWORD dwColors = image->GetNumColors();        //颜色数
	WORD  wBpp = image->GetBpp();                  //位数


	BYTE* pImg  = NULL;                 //图像数据指针
	pImg = image->GetBits();             

	// HMM 估计LSB替换的嵌入率
	int 	T;
	HMM  	hmm;
	int	N;
	int	M;
	double 	**alpha; 
	double	**beta;
	double	**gamma;
	double theita;
	int	*O;
//	int	c;
	int	seed; /* seed for random number generator */
	int	niter;
	double	logprobinit, logprobfinal;
 

	/* read the observed sequence */
	T = 32;
	O = new int[dwWidth];
	O = O - 1;
	for (DWORD i = 0; i < dwWidth; i++)
	{
		O[i+1] = (int)pImg[i];
	}
	

	/* initialize the hmm model */
	N = 256;
	M = 256;
	seed = hmmgetseed();
	InitHMM2(pImg, dwWidth, dwHeight, &hmm, N, M, seed);
//	InitHMM(&hmm, N, M, seed);

	/* allocate memory */
	alpha = dmatrix(1, T, 1, hmm.N);
	beta = dmatrix(1, T, 1, hmm.N);
	gamma = dmatrix(1, T, 1, hmm.N);

	/* call Baum Welch2 */
	theita=BaumWelch2(&hmm, T, O, alpha, beta, gamma, &niter, 
		&logprobinit, &logprobfinal);


	/* free memory */
//	free_ivector(O, 1, T);
	free_dmatrix(alpha, 1, T, 1, hmm.N);
	free_dmatrix(beta, 1, T, 1, hmm.N);
	free_dmatrix(gamma, 1, T, 1, hmm.N);
	FreeHMM(&hmm);
	if (pImg != NULL)
	{
		delete []pImg;	pImg = NULL;
	}
	if (O != NULL)
	{
		delete []O;	O = NULL;
	}
}





















⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?