lsbanalysisdoc.cpp
来自「信息隐藏中用于数字隐写的常用算法:LSB替换LSB匹配,包括随机的和排序的,以及」· C++ 代码 · 共 1,714 行 · 第 1/4 页
CPP
1,714 行
// LSBAnalysisDoc.cpp : implementation of the CLSBAnalysisDoc class
//
#include "stdafx.h"
#include "LSBAnalysis.h"
#include "LSBAnalysisDoc.h"
#include "RatioDlg.h"
#include "xxxxx.h"
#include <math.h>
#include "../cximage/ximage.h"
#include "../cximage/xfile.h"
#include "steg_detect/StatTest.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CLSBAnalysisDoc
IMPLEMENT_DYNCREATE(CLSBAnalysisDoc, CDocument)
BEGIN_MESSAGE_MAP(CLSBAnalysisDoc, CDocument)
//{{AFX_MSG_MAP(CLSBAnalysisDoc)
ON_COMMAND(ID_EMBED_LSBMATCH, OnEmbedLsbmatch)
ON_COMMAND(ID_EMBED_LSBMATCH2, OnEmbedLsbmatch2)
ON_COMMAND(ID_EXTRACT_LSBMATCH, OnExtractLsbmatch)
ON_COMMAND(ID_EXTRACT_LSBMATCH2, OnExtractLsbmatch2)
ON_COMMAND(ID_EMBED_LSBMATCH3, OnEmbedLsbmatch3)
ON_COMMAND(ID_EMBED_LSBMATCH4, OnEmbedLsbmatch4)
ON_COMMAND(ID_EMBED_LSBREPLACE, OnEmbedLsbreplace)
ON_COMMAND(ID_EMBED_LSBREPLACE2, OnEmbedLsbreplace2)
ON_COMMAND(ID_DETECT_HMM, OnDetectHmm)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLSBAnalysisDoc construction/destruction
CLSBAnalysisDoc::CLSBAnalysisDoc()
{
// TODO: add one-time construction code here
image = 0;
m_bModified = FALSE;
nImgType = 0;
m_strPathName = _T("");
}
CLSBAnalysisDoc::~CLSBAnalysisDoc()
{
if (image) delete image;
}
BOOL CLSBAnalysisDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CLSBAnalysisDoc serialization
void CLSBAnalysisDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CLSBAnalysisDoc diagnostics
#ifdef _DEBUG
void CLSBAnalysisDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CLSBAnalysisDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CLSBAnalysisDoc commands
CString CLSBAnalysisDoc::FindExtension(const CString& name)
{
int len = name.GetLength();
int i;
for (i = len-1; i >= 0; i--){
if (name[i] == '.'){
return name.Mid(i+1);
}
}
return CString("");
}
//////////////////////////////////////////////////////////////////////////////
int CLSBAnalysisDoc::FindType(const CString& ext)
{
int type = 0;
if (ext == "bmp") type = CXIMAGE_FORMAT_BMP;
#if CXIMAGE_SUPPORT_JPG
else if (ext=="jpg"||ext=="jpeg") type = CXIMAGE_FORMAT_JPG;
#endif
#if CXIMAGE_SUPPORT_GIF
else if (ext == "gif") type = CXIMAGE_FORMAT_GIF;
#endif
#if CXIMAGE_SUPPORT_PNG
else if (ext == "png") type = CXIMAGE_FORMAT_PNG;
#endif
#if CXIMAGE_SUPPORT_MNG
else if (ext=="mng"||ext=="jng") type = CXIMAGE_FORMAT_MNG;
#endif
#if CXIMAGE_SUPPORT_ICO
else if (ext == "ico") type = CXIMAGE_FORMAT_ICO;
#endif
#if CXIMAGE_SUPPORT_TIF
else if (ext=="tiff"||ext=="tif") type = CXIMAGE_FORMAT_TIF;
#endif
#if CXIMAGE_SUPPORT_TGA
else if (ext=="tga") type = CXIMAGE_FORMAT_TGA;
#endif
#if CXIMAGE_SUPPORT_PCX
else if (ext=="pcx") type = CXIMAGE_FORMAT_PCX;
#endif
#if CXIMAGE_SUPPORT_WBMP
else if (ext=="wbmp") type = CXIMAGE_FORMAT_WBMP;
#endif
#if CXIMAGE_SUPPORT_WMF
else if (ext=="wmf"||ext=="emf") type = CXIMAGE_FORMAT_WMF;
#endif
#if CXIMAGE_SUPPORT_J2K
else if (ext=="j2k"||ext=="jp2") type = CXIMAGE_FORMAT_J2K;
#endif
#if CXIMAGE_SUPPORT_JBG
else if (ext=="jbg") type = CXIMAGE_FORMAT_JBG;
#endif
#if CXIMAGE_SUPPORT_JP2
else if (ext=="jp2"||ext=="j2k") type = CXIMAGE_FORMAT_JP2;
#endif
#if CXIMAGE_SUPPORT_JPC
else if (ext=="jpc"||ext=="j2c") type = CXIMAGE_FORMAT_JPC;
#endif
#if CXIMAGE_SUPPORT_PGX
else if (ext=="pgx") type = CXIMAGE_FORMAT_PGX;
#endif
#if CXIMAGE_SUPPORT_RAS
else if (ext=="ras") type = CXIMAGE_FORMAT_RAS;
#endif
#if CXIMAGE_SUPPORT_PNM
else if (ext=="pnm"||ext=="pgm"||ext=="ppm") type = CXIMAGE_FORMAT_PNM;
#endif
else type = CXIMAGE_FORMAT_UNKNOWN;
return type;
}
/////////////////////////////////////////////////////////////////////////////
// CLSBAnalysisDoc commands
BOOL CLSBAnalysisDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
// if (!CDocument::OnOpenDocument(lpszPathName))
// return FALSE;
m_strPathName = CString(lpszPathName);
CString ext(FindExtension(m_strPathName));
ext.MakeLower();
if (ext == "") return FALSE;
nImgType = FindType(ext);
image = new CxImage(m_strPathName, nImgType);
if (!image->IsValid()){
AfxMessageBox(image->GetLastError());
delete image;
image = NULL;
return FALSE;
}
UpdateAllViews(NULL,WM_USER_NEWIMAGE);
//multiple images (TIFF/ICO)
if (image->GetNumFrames()>1){
CString s;
s.Format("File with %d images. Read all?",image->GetNumFrames());
if (AfxMessageBox(s,MB_OKCANCEL)==IDOK){
int j; // points to the document name
for(j=strlen(m_strPathName)-1;j>=0;j--){
if (m_strPathName[j]=='\\'){ j++; break; }
}
// create the documents for the other images
for(int i=1;i<image->GetNumFrames();i++){
CLSBAnalysisDoc *NewDoc=(CLSBAnalysisDoc*)((CLSBAnalysisApp*)AfxGetApp())->LSBAnalysisTemplate->OpenDocumentFile(NULL);
if (NewDoc) {
CxImage *newImage = new CxImage();
newImage->SetFrame(i);
newImage->Load(m_strPathName, nImgType);
NewDoc->image = newImage;
CString s;
s.Format("%s (%d)",m_strPathName.Mid(j),i+1);
NewDoc->SetTitle(s);
NewDoc->UpdateAllViews(NULL,WM_USER_NEWIMAGE);
}
}
}
}
return TRUE;
}
BOOL CLSBAnalysisDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
CString filename(lpszPathName);
CString ext(FindExtension(filename));
ext.MakeLower();
if (ext == "") return FALSE;
int type = FindType(ext);
if (type == CXIMAGE_FORMAT_UNKNOWN) return FALSE;
bool retval;
retval = image->Save(filename, type);
if (retval) return TRUE;
AfxMessageBox(image->GetLastError());
return FALSE;
// return CDocument::OnSaveDocument(lpszPathName);
}
//////////////////////////////////////////////////////////////////////////////
BOOL CLSBAnalysisDoc::DoSave(LPCTSTR pszPathName, BOOL bReplace /*=TRUE*/)
{
if (!image) return FALSE;
CString newName = pszPathName;
BOOL bModified = IsModified();
BOOL bSaveAs = FALSE;
if (newName.IsEmpty()) bSaveAs = TRUE;
else if (!theApp.GetWritableType(image->GetType())) bSaveAs = TRUE;
if (bSaveAs){
newName = m_strPathName;
if (bReplace && newName.IsEmpty()){
newName = m_strTitle;
int iBad = newName.FindOneOf(_T("#%;/\\")); // dubious filename
if (iBad != -1) //newName.ReleaseBuffer(iBad);
newName = "UntitledImage";
// append the default suffix if there is one
if (image->GetType()) newName += theApp.GetExtFromType(image->GetType()).Mid(1,4);
}
int nDocType = image->GetType();
if (!theApp.PromptForFileName(newName,
bReplace ? AFX_IDS_SAVEFILE : AFX_IDS_SAVEFILECOPY,
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, FALSE, &nDocType))
{
return FALSE; // don't even try to save
}
}
BeginWaitCursor();
if (!OnSaveDocument(newName)){
if (pszPathName == NULL){
// be sure to delete the file
TRY
{
CFile::Remove(newName);
}
CATCH_ALL(e)
{
TRACE0("Warning: failed to delete file after failed SaveAs\n");
}
END_CATCH_ALL
}
EndWaitCursor();
return FALSE;
}
EndWaitCursor();
if (bReplace) {
// Reset the title and change the document name
SetPathName(newName, TRUE);
ASSERT(m_strPathName == newName); // must be set
}
else // SaveCopyAs
{
SetModifiedFlag(bModified);
}
return TRUE; // success
}
//..........................................................//
// 单文件随机LSB Match嵌入 //
//..........................................................//
void CLSBAnalysisDoc::OnEmbedLsbmatch()
{
//确保打开文件不为空
ASSERT(m_strPathName != _T(""));
//................得到嵌入率和密码..................
CRatioDlg RatioDlg;
float fRatio;
int nSeed;
if(RatioDlg.DoModal()==IDOK)
{
fRatio = RatioDlg.m_fRatio;
nSeed = RatioDlg.m_key;
}
else
{
fRatio = 1.0;
nSeed = 12;
}
//................得到图像基本信息....................
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();
BYTE* pData = NULL; //待嵌入数据指针
pData = ReadPRNData(dwImgSize);
if (pData == NULL)
return;
//.................得到图像置乱的排序...................
int* m_pImgPerm = NULL;
m_pImgPerm = new int[dwImgSize];
memset(m_pImgPerm, 0, dwImgSize * sizeof(int));
srand(nSeed);
// srand( (unsigned)time( NULL ) );
Rand_Perm(m_pImgPerm, dwImgSize);
//.................随机LSB Match嵌入....................
LSBMatchEmbed(pImg, pData, m_pImgPerm, dwImgSize, fRatio);
//.................另存为新的图像文件...................
CString m_strPrefix = _T("");
m_strPrefix.Format("_Random_%d", int(fRatio * 100));
char cDrive[_MAX_DRIVE]; //驱动器名字符串
char cDir [_MAX_DIR]; //子路径字符串
char cFname[_MAX_FNAME]; //纯文件名字符串
char cExt [_MAX_EXT]; //后缀名字符串
char cPath [_MAX_DRIVE + _MAX_DIR]; //全路径名字符串
//从文件全名中分割得到驱动名和子路径
_splitpath((LPCTSTR)m_strPathName, cDrive, cDir, cFname, cExt);
strcpy(cPath, cDrive);
strcat(cPath, cDir);
CString m_strSaveName = (CString)cPath + (CString)cFname + m_strPrefix + (CString)cExt;
memcpy(image->info.pImage, pImg, dwHeight * dwEffWidth);
image->Save(m_strSaveName, nImgType);
// m_bModified = TRUE;
// UpdateAllViews(NULL, WM_USER_NEWIMAGE);
if (pData != NULL)
{ delete []pData; pData = NULL; }
if (m_pImgPerm != NULL)
{ delete []m_pImgPerm; m_pImgPerm = NULL; }
}
//..........................................................//
// 单文件序贯LSB Match嵌入 //
//..........................................................//
void CLSBAnalysisDoc::OnEmbedLsbmatch2()
{
//确保打开文件不为空
ASSERT(m_strPathName != _T(""));
//...........得到嵌入率和密码,密码作为种子数..................
CRatioDlg RatioDlg;
float fRatio;
int nSeed;
//得到嵌入率和密码
if(RatioDlg.DoModal()==IDOK)
{
fRatio = RatioDlg.m_fRatio;
nSeed = RatioDlg.m_key;
}
else
{
fRatio = 1.0;
nSeed = 12;
}
//.................得到图像基本信息..........................
DWORD dwHeight = image->GetHeight(); //高
DWORD dwWidth = image->GetWidth(); //宽
DWORD dwEffWidth = image->GetEffWidth(); //实际宽度
DWORD dwImgSize = dwHeight * dwEffWidth; //图像数据大小
DWORD dwColors = image->GetNumColors(); //颜色数
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?