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

📄 ftdib.cpp

📁 基于LSB的信息隐藏技术——MFC——编译已经通过运行正常
💻 CPP
字号:
// FTDib.cpp: implementation of the FTDib class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "LSB.h"
#include "FTDib.h"

#define BI_RLE8       1L
#define BI_RLE4       2L
#define WIDTHBYTES(bits)  (((bits)+31)/32*4)
//#define OFN_OVERWRITEPROMPT          0x00000002
//#define OFN_HIDEREADONLY             0x00000004

typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned char BYTE;

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

FTDib::FTDib()
{
	size = 0;
	pDib = NULL;
	m_pBitmapFileHeader = new BitmapFileHeader;//文件头
	m_pBitmapInfoHeader = new BitmapInfoHeader;//信息头
	m_pBitmapInfo = (BitmapInfo*)m_pBitmapInfoHeader;
}

FTDib::~FTDib()
{
	delete m_pBitmapFileHeader;
	delete m_pBitmapInfoHeader;
	if(pDib)
	{
	delete pDib;
	}
}
//---------------------------------------------
//  载入图像到内存
//---------------------------------------------
void FTDib::LoadFile(CString dibFileName)
{
	CFile dibFile(dibFileName, CFile::modeRead);//读取位图文件	

	dibFile.Read((char*)m_pBitmapFileHeader,sizeof(BitmapFileHeader));//读入文件头
    dibFile.Read((char*)m_pBitmapInfoHeader,sizeof(BitmapInfoHeader));//读入信息头

	if(m_pBitmapFileHeader->bfType == 0x4d42)
	{   
		//读入图像信息
		size = m_pBitmapFileHeader->bfSize - sizeof(BitmapFileHeader) - sizeof(BitmapInfoHeader);
		pDib = new BYTE[size];
		dibFile.Read((char*)pDib,size);
		dibFile.Close();

		
		
		m_pRGB = (RGB_Element*)(pDib);
		m_numberOfColors = GetNumberOfColors();
		if(m_pBitmapInfoHeader->biColors != 0){m_pBitmapInfoHeader->biColors = m_numberOfColors;}
		DWORD colorTableSize = m_numberOfColors * sizeof(RGB_Element);
		m_pData = pDib + colorTableSize;

		if(m_pRGB == (RGB_Element*)m_pData)//没有颜色表
		{
			m_pRGB = NULL;
		}
		m_pBitmapInfoHeader->biDataSize = GetSize();
		m_valid = true;
		::AfxMessageBox("图像载入成功!请选择要嵌入的文本文件!");
	}
	else
	{
		m_valid = false;
		::AfxMessageBox("出错了!该图像不是bmp格式");
	}
	
}
//---------------------------------------------
//  检查图片格式
//---------------------------------------------
bool FTDib::IsValid()
{
	return m_valid;
}

//---------------------------------------------
//   取得图片名称或路径
//---------------------------------------------
char * FTDib::GetFileName()
{
	return m_fileName;
}

//---------------------------------------------
//  取得图像宽度和高度
//---------------------------------------------
unsigned int FTDib::GetWidth()
{
	return (unsigned int)m_pBitmapInfoHeader->biWidth;
}

unsigned int FTDib::GetHeight()
{
	return (unsigned int)m_pBitmapInfoHeader->biHeight;
}

//---------------------------------------------
//  取得图像数据区大小
//---------------------------------------------
DWORD FTDib::GetSize()
{
	if(m_pBitmapInfoHeader->biDataSize != 0)
	{
		return m_pBitmapInfoHeader->biDataSize;
	}
	else
	{
		DWORD height = (DWORD)GetHeight();
		DWORD width  = (DWORD)GetWidth();
		return height * width;
	}
}

//---------------------------------------------
//  取得图像宽度
//---------------------------------------------
DWORD FTDib::GetDibWidthBytes()
{
	byBitCount = m_pBitmapInfoHeader->biBitPerPixel;
	long nWidth = m_pBitmapInfoHeader->biWidth;

	dwWidthBytes = (DWORD)m_pBitmapInfoHeader->biWidth;
	switch(dwWidthBytes)
	{
	case 1:
		dwWidthBytes = (nWidth + 7)/8;
	case 2:
		dwWidthBytes = (nWidth + 1)/2;
	case 24:
		dwWidthBytes = 3*nWidth;
	}

	while((dwWidthBytes&3) != 0){++dwWidthBytes;}

	return dwWidthBytes;
}
//---------------------------------------------
//  取得图像颜色数 
//---------------------------------------------
unsigned int FTDib::GetNumberOfColors()
{
	int numberOfColors;

	if((m_pBitmapInfoHeader->biColors == 0)&&(m_pBitmapInfoHeader->biBitPerPixel < 9))
	{
		switch(m_pBitmapInfoHeader->biBitPerPixel)
		{
		case 1:
			numberOfColors = 2;break;
		case 4:
			numberOfColors = 16;break;
		case 8:
			numberOfColors = 256;
		}
	}
	else
	{
	numberOfColors = (int)m_pBitmapInfoHeader->biColors;
	}
	return numberOfColors;
}
//---------------------------------------------
//  取得图像数据区指针
//---------------------------------------------
BYTE *FTDib::GetData()
{
	return m_pData;
}

BYTE *FTDib::GetData2()
{
	if(GetRGB())
	{
		m_pData2 = m_pData;
	}
	return m_pData2;
}

//---------------------------------------------
//  取得图像颜色表指针
//---------------------------------------------
RGB_Element * FTDib::GetRGB()
{
	return m_pRGB;
}

//---------------------------------------------
//  取得图像信息指针
//---------------------------------------------
BitmapInfo * FTDib::GetInfo()
{
	return m_pBitmapInfo;
}

//---------------------------------------------
//  调色板大小
//---------------------------------------------
WORD FTDib::PaletteSize(BYTE *lpDib)
{
	return (DIBNumColors(lpDib) * sizeof(RGB_Element));
}

//---------------------------------------------
//  取得图像颜色数
//---------------------------------------------
WORD FTDib::DIBNumColors(BYTE *lpDib)
{
	WORD wBitCount;
	wBitCount = ((BitmapInfoHeader*)lpDib)->biBitPerPixel;
	switch(wBitCount)
	{
	case 1:
		return 2;
	case 4:
		return 16;
	case 8:
		return 256;
	default:
		return 0;
	}
}

//---------------------------------------------
//  保存文件
//---------------------------------------------
void FTDib::SaveFile(CString filename)
{
	CFile dibFile;

	dibFile.Open(filename,  CFile::modeCreate | CFile::modeWrite);
	
	dibFile.Write((char*)m_pBitmapFileHeader,sizeof(BitmapFileHeader));
	dibFile.Write((char*)m_pBitmapInfoHeader,sizeof(BitmapInfoHeader));
	dibFile.Write((char*)pDib,size);

	dibFile.Close();
}
//---------------------------------------------
//  基于LSB的信息隐藏
//---------------------------------------------
int  FTDib::LSBCoder(CString textFileName)
{
    CFile textFile;
	textFile.Open(textFileName,CFile::modeRead);
	DWORD textFileLength = textFile.GetLength();//计算隐藏文件长度

	//判断位图是否够存储隐藏的信息
	DWORD colorTableSize = m_numberOfColors * sizeof(RGB_Element);
	if((size - colorTableSize)<textFileLength*8)
	{
		return -1; //不够隐藏
	}


	BYTE* pTextFile = new BYTE[textFileLength+1];

	textFile.SeekToBegin();//文件指针指向隐藏文件开头
	textFile.Read((char*)pTextFile,textFileLength);
	textFile.Close();

    BYTE textData;
	for(int i=0,k=0; i<textFileLength; ++i)
	{
		for(int j=0; j<8; ++j)
		{
			textData = pTextFile[i]>>j;
			textData = textData&0x01;
		    if(textData==0)
			{
				pDib[k+32] = pDib[k+32]&0xfe;
			}
			else
			{
				pDib[k+32] = pDib[k+32]|0x01;
			}
			++k;
		}
	}

	//在前四个字节中写入text文件数据长度
	DWORD length;
	for(int m=0; m<32; ++m)
	{
		length = textFileLength>>m;
		length = length&0x00000001;
		if(length==0)
		{
			pDib[m] = pDib[m]&0x1e;
		}
		else
		{
			pDib[m] = pDib[m]|0x01;
		}
	}

	return 0;

	
}

//---------------------------------------------
//  基于LSB的信息提取
//---------------------------------------------
void  FTDib::LSBDecoder(CString textFileName)
{
	DWORD length = 0x00000000;
	BYTE bit;
	//获取text文件长度
	for(int i=0; i<32; ++i)
	{
		bit = pDib[i]&0x01;
		if(bit==0)
		{
			length = length&0x7fffffff;
		}
		else
		{
			length = length|0x80000000;
		}
		if (i<31)	
			length = length>>1;
	}

    //开始提取
	BYTE* pTextFile = new BYTE[length];
	BYTE textData;
	for(int q=0,k=0; q<length*8; ++q)
	{
		if(q && q%8==0){++k;}
		textData = pDib[q+32]&0x01;
		if(textData==0)
		{
			pTextFile[k] = pTextFile[k]&0x7f;
		}
		else
		{
			pTextFile[k] = pTextFile[k]|0x80;
		}
		if (q%8 != 7) 
			pTextFile[k] = pTextFile[k]>>1;
	}


	CFile textFile;
	textFile.Open(textFileName,CFile::modeCreate | CFile::modeWrite);
	textFile.Write((char*)pTextFile,length);
	textFile.Close();
	delete pTextFile;
}




⌨️ 快捷键说明

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