#include "InfoHidden.h"
int main(int argc, char **argv)
{
BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfoHeader;
size_t nInfoSize = 0;
BYTE binaryInifo[256] = {'\0'};
FILE *fp = NULL;
Block block;
if (argc != 3)
{
printf("usage:%s bitmap info", argv[0]);
return -1;
}
fp = fopen(argv[1], "rb+");
if (NULL == fp)
{
printf("%s\n", strerror(errno));
return -1;
}
if (!readBMPFileHeader(fp, &bmpFileHeader))
{
if (bmpFileHeader.bfType != 0X4D42)
{
printf("不是bmp格式的位图\n");
goto end;
}
}
if (!readBMPInfoHeader(fp, &bmpInfoHeader))
{
if (bmpInfoHeader.biBitCount < 24)
{
printf("需要24位色或以上的位图\n");
goto end;
}
if ((bmpInfoHeader.biSize/12) < (nInfoSize/3))
{
printf("位图不能存放当前的信息。能存放的最大信息量是:%d\n", bmpInfoHeader.biSize/4);
goto end;
}
}
/*隐藏数据*/
if (hiddenInfo(fp, argv[2]))
{
goto end;
}
printf("信息隐藏成功!\n");
/*测试获取隐藏的数据*/
fclose(fp);
fp = fopen(argv[1], "rb");
if (NULL == fp)
{
printf("%s\n", strerror(errno));
return -1;
}
if (!readBMPFileHeader(fp, &bmpFileHeader))
{
if (bmpFileHeader.bfType != 0X4D42)
{
printf("不是bmp格式的位图\n");
goto end;
}
}
if (!readBMPInfoHeader(fp, &bmpInfoHeader))
{
if (bmpInfoHeader.biBitCount < 24)
{
printf("需要24位色或以上的位图\n");
goto end;
}
if ((bmpInfoHeader.biSize/12) < (nInfoSize/3))
{
printf("位图不能存放当前的信息。能存放的最大信息量是:%d\n", bmpInfoHeader.biSize/4);
goto end;
}
}
/*解析数据*/
analysisInfo(fp, binaryInifo);
printf("解析出来的数据是:%s\n", binaryInifo);
end:
fclose(fp);
fp = NULL;
return 0;
}
/*****************************************************************
*函数功能:读取bmp文件头
*传入参数:fp bmp文件句柄
*传出参数:bmpFileHeader 文件头指针
*返 回 值:成功返回0,否则-1
*****************************************************************/
int readBMPFileHeader( FILE *fp, BITMAPFILEHEADER *bmpFileHeader )
{
size_t nBlock;
if (NULL == fp)
{
printf("指针不能为NULL\n");
return -1;
}
nBlock = fread(bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
if (nBlock != 1)
{
printf("读取数据失败:%s", strerror(errno));
return -1;
}
return 0;
}
/*****************************************************************
*函数功能:读取bmp信息头
*传入参数:fp bmp文件句柄
*传出参数:bmpInfoHeader 信息头指针
*返 回 值:成功返回0,否则-1
*****************************************************************/
int readBMPInfoHeader( FILE *fp, BITMAPINFOHEADER *bmpInfoHeader )
{
size_t nBlock;
if (NULL == fp)
{
printf("指针不能为NULL\n");
return -1;
}
nBlock = fread(bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
if (nBlock != 1)
{
printf("读取数据失败:%s", strerror(errno));
return -1;
}
return 0;
}
/*****************************************************************
*函数功能:信息隐藏
*传入参数:fp bmp文件句柄
* info 待隐藏的数据
*传出参数:
*返 回 值:成功返回0,否则-1
*****************************************************************/
int hiddenInfo( FILE *fp, BYTE *info )
{
Block block;
size_t nInfoSize = 0;
size_t index;
if (NULL == fp)
{
printf("指针不能为NULL!");
return -1;
}
nInfoSize = strlen(info);
for (index = 0;index < nInfoSize / 3; ++index)
{
if (getBlock(fp, &block))
{
return -1;
}
/*printBlock(&block);*/
hiddenBytes(&block, info[index * 3], info[index * 3 + 1], info[index * 3 + 2]);
if (setBlock(fp, &block))
{
return -1;
}
memset(&block, 0, sizeof(Block));
}
if (index * 3 < nInfoSize)
{
/*memset(&block, 0, sizeof(Block));*/
if (getBlock(fp, &block))
{
return -1;
}
printBlock(&block);
if ((index * 3 + 1) < nInfoSize)
{
hiddenBytes(&block, info[index *3 ], info[index * 3 + 1], 0);
if (setBlock(fp, &block))
{
return -1;
}
}
else
{
hiddenBytes(&block, info[index * 3], 0, 0);
if (setBlock(fp, &block))
{
return -1;
}
}
}
/*如果恰好是3的倍数,则补0表示结束*/
else
{
if (getBlock(fp, &block))
{
return -1;
}
hiddenBytes(&block, 0 , 0, 0);
if (setBlock(fp, &block))
{
return -1;
}
}
return 0;
}
/*****************************************************************
*函数功能:解析隐藏数据
*传入参数:fp bmp文件句柄
*传出参数:info 解析出来的数据
*返 回 值:成功返回0,否则-1
*****************************************************************/
int analysisInfo( FILE *fp, BYTE *info )
{
Block block;
BYTE a = 0;
BYTE b = 0;
BYTE c = 0;
size_t index = 0;
if (NULL == fp)
{
printf("指针不能为NULL!\n");
return -1;
}
while (1)
{
if (!getBlock(fp, &block))
{
analysisBlock(&block, &a, &b, &c);
info[index] = a;
info[index + 1] = b;
info[index + 2] = c;
if (0==a || 0==b || 0==c)
{
break;
}
index = index + 3;
a = 0;
b = 0;
c = 0;
}
memset(&block, 0, sizeof(Block));
}
return 0;
}
/*****************************************************************
*函数功能:获取数据块
*传入参数:fp 文件句柄
*传出参数:block 数据块指针
*返 回 值:成功返回0,否则-1
*****************************************************************/
int getBlock( FILE *fp, Block *block )
{
size_t nBlock;
if (NULL == fp || NULL == block)
{
printf("指针不能为NULL\n");
return -1;
}
nBlock = fread(block, sizeof(Block), 1, fp);
if (nBlock != 1)
{
printf("读取数据失败:%s\n", strerror(errno));
return -1;
}
return 0;
}
/*****************************************************************
*函数功能:写入数据块
*传入参数:fp 文件句柄
* block 待写入的数据块指针
*传出参数:
*返 回 值:成功返回0,否则-1
*****************************************************************/
int setBlock( FILE *fp, Block *block )
{
size_t nBlock;
long nOffset;
if (NULL == fp || NULL == block)
{
printf("指针不能为NULL\n");
return -1;
}
/*取sizeof(Block)的负数*/
nOffset = ~sizeof(Block) + 1;
/*将文件指针后退sizeof(Block)个字节*/
if (fseek(fp, nOffset, SEEK_CUR))
{
printf("文件指针定位出错.%s\n", strerror(errno));
return -1;
}
nBlock = fwrite(block, sizeof(Block), 1, fp);
if (nBlock != 1)
{
printf("写入数据失败:%s\n", strerror(errno));
return -1;
}
return 0;
}
void printBlock( Block *block )
{
int i;
for (i = 0; i < 4; ++i)
{
printRGB(&(block->rgbBlock[i]));
}
printf("\n");
}
int printRGB( RGBPix *rgbPix )
{
if (NULL == rgbPix)
{
printf("指针不能为NULL\n");
return -1;
}
printf("(%u,%u
- 1
- 2
前往页