// code continued
class CMyApp
{
public:
bool DecodeFile(const char* bmp_file_name, const char* decode_file_name)
{
// load image
CImage img;
int ret = img.Load((LPCTSTR)bmp_file_name);
if(ret == E_FAIL)
{
printf("\7\7\7Error, cannot open image file:%s", bmp_file_name);
return FALSE;
}
// load file
CFile
file;
if(FALSE == file.Open(decode_file_name,CFile::modeWrite|CFile::modeCreate))
{
printf("\7\7\7Error, cannot open source file:%s",decode_file_name);
return FALSE;
}
// extrace data from image
CBitmapBitStream bbs((byte*)img.GetBits(),img.GetPitch(),img.GetWidth(),img.GetHeight());
byte* array_max = bbs.ExtraceHideInformation();
CMemCleaner<byte> mem_auto_deletor(array_max, TRUE);
ret = FALSE;
if(array_max)
{
int actual_size;
int magic_data;
INT_FROM_CHAR_ARRAY(magic_data,array_max);
INT_FROM_CHAR_ARRAY(actual_size,array_max + 4);
if(magic_data == MAGIC_DATA_IN_IMAGE)
{
// store to file
file.Write(array_max + 12, actual_size);
ret = TRUE;
}
else
{
printf("Error, bad format image, cannot decode file!\r\n");
ret = FALSE;
}
}
file.Close();
return ret;
}
public:
boolean EncodeFile( const char* bmp_dest_file, const char* file_to_encode,const char* bmp_src_file = NULL)
{
int work_mode = 0;
// create a new file, without original image file to hide, if 1 means hide in an existing image, and store in a new file
CImage
img0;
int data_length;
// include magic_header(12 bytes)
int ret = E_FAIL;
if(bmp_src_file == NULL)
{
work_mode = 0;
}
else
{
ret = img0.Load((LPCTSTR)bmp_src_file);
if(ret == E_FAIL)
{
work_mode = 0;
}
else
{
work_mode = 1;
}
}
//---------------------------------------------------------------------------------------------
// open source file
CFile file;
if(file.Open(file_to_encode, CFile::modeRead) == FALSE)
{
return FALSE;
}
data_length = file.GetLength()+12;
byte* array = new byte[data_length];
CMemCleaner<byte> deleter(array,TRUE);
if(array == NULL)
{
file.Close();
return FALSE;
}
file.Read(array+12,data_length - 12);
CMagicHeader header;
header.Init(data_length - 12,0);
header.ToByteArray(array);
CDataBitStream dbs(array,data_length);
//---------------------------------------------------------------------------------------------
CImage* pImg = NULL;
if(work_mode == 1)
{
pImg = CloneImage(&img0);
int bit_num = dbs.GetBitNumWhenEncodeInIma
ge(pImg->GetWidth(),pImg->GetHeight());
if (bit_num == 0)
{
printf("Error! Image size too small to hide information");
return FALSE;
}
}
else
{
pImg = dbs.CreateCompatiableImage();
}
CMemCleaner<CImage> deletor2(pImg,FALSE);
CBitmapBitStream bbs(pImg);
bbs.HideInformation(&dbs);
// now data have been encoded to pImg
ret = pImg->Save(bmp_dest_file,Gdiplus::ImageFormatBMP);
if(ret == E_FAIL)
{
printf("Error, failed to store destination file.");
}
else
{
printf("encode finished!\r\n");
}
return TRUE;
}
#ifdef _WIN32
protected:
CImage* CloneImage(CImage* source_image)
{
int width = source_image->GetWidth();
int height = source_image->GetHeight();
int pitch = source_image->GetPitch();
if(source_image->GetBPP() != 24)
{
return NULL;
}
CImage* pImg = new CImage;
// now copy image
if(pitch < 0)
{
pImg->CreateEx(width,height,24,BI_RGB);
//for ( int __kk = 0; __kk < height; _kk++)
//{
//
memcpy(pImg->GetBits() + kk* __kk, source_image->GetBits() +
kk* __kk, MY_ABS(pitch));
//}
memcpy((byte*)(pImg->GetBits()) + pitch*(height-1),(byte*)(source_image->GetBits()) +
pitch* (height-1),MY_ABS(pitch* height));
}
else
{
pImg->CreateEx(width,-height,24,BI_RGB);
memcpy(pImg->GetBits(),source_image->GetBits(),MY_ABS(pitch*height));
}
return pImg;
}
#endif // endif _WIN32
public:
int get_seed()
{
CTime tm = CTime::GetCurrentTime();
int rand_seed = tm.GetHour() * 17931 + tm.GetMinute()*257 + tm.GetSecond()*17;
return rand_seed;
}
void simple_encrypt(byte* actual_array, int actual_size, int rand_seed)
{
#ifdef SW_ENCRYPT
int i = 0;
byte format = (byte)(rand_seed % 256);
byte k = format;
for(i = 0; i < actual_size; i ++)
{
actual_array[i] ^= k;
k --;
if( k == 0)
{
format ++;
k = format;
}
}
#endif
}
};
int main(int argc, char* argv[])
{
int nRetCode = 0;
CMyApp app;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
}
if(argc < 4)
{
printf("Usage: %s -toimage bmp_file source_file\r\n",argv[0]);
printf("
%s -tofile
file
bmp_file\r\n",argv[0]);
printf("
%s -addimage
final_image_file source_bmp_file info_file\r\n",argv[0]);
return 0;
}
if(strcmpi(argv[1],"-toimage") ==0)
{
//return File2Image(argv[2],argv[3]);
app.EncodeFile(argv[2],argv[3],NULL);
}
else if(strcmpi(argv[1],"-tofile") == 0)
{
// return Image2File(argv[2],argv[3]);
app.DecodeFile(argv[3],argv[2]);
}
else if(strcmpi(argv[1],"-addimage")==0)
{
//CImage source_image;
app.EncodeFile(argv[2],argv[4],argv[3]);
}
else if(strcmpi(argv[1],"-totest")==0)
{
for(int i = 1000; i < 1000000; i ++)
{
CImage img;
img.Load("d:\\le-17.bmp");
byte* array = new byte[i+12];
CMagicHeader header;
header.Init(i,0);
header.ToByteArray(array);
// randome create data
for(int j = 0; j < i; j ++)
{
array[12+j] = rand() % 255;
}
CBitmapBitStream bbs(&img);
bbs.HideInformation(array,i+12);
byte* array1 = bbs.ExtraceHideInformation();
if(memcmp(array1,array,i+12) == 0)
{
printf("Pass!");
TRACE("Pass!\r\n");
}
else
{
printf("Fail!");
TRACE("Fail!\r\n");
}
}
}
else
{
printf("Usage: %s -toimage bmp_file source_file\r\n",argv[0]);
printf("
%s -tofile
file
bmp_file\r\n",argv[0]);
printf("
%s -addimage
final_image_file source_bmp_file info_file\r\n",argv[0]);
return 0;
}
return nRetCode;
}
// The one and only application object
CWinApp theApp;
using namespace std;
class CMyApp
{
public:
public:
#ifdef _WIN32
protected:
#endif // endif _WIN32
public:
};
int main(int argc, char* argv[])
{
}
// The one and only application object
CWinApp theApp;
using namespace std;