📄 ftdib.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 + -