Pretty useless program but check it out anyway

Should compile on windows and linux

bmp.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <cstdlib>
#include <stdio.h>
#include <iostream>
#include <fstream>
using namespace std;
// This is for non-windows OS */
#ifdef _WIN32
  #include <windows.h>
  #undef LoadBitmap
  #undef GetPixel
#else
  #define BYTE unsigned char
  #define WORD unsigned short
  #define DWORD unsigned int
  #define LONG long

  #pragma pack(push,2)
typedef struct tagBITMAPFILEHEADER {
	WORD	bfType;
	DWORD	bfSize;
	WORD	bfReserved1;
	WORD	bfReserved2;
	DWORD	bfOffBits;
} BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
#pragma pack(pop)
typedef struct tagBITMAPINFOHEADER{
	DWORD	biSize;
	LONG	biWidth;
	LONG	biHeight;
	WORD	biPlanes;
	WORD	biBitCount;
	DWORD	biCompression;
	DWORD	biSizeImage;
	LONG	biXPelsPerMeter;
	LONG	biYPelsPerMeter;
	DWORD	biClrUsed;
	DWORD	biClrImportant;
} BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;

typedef struct tagRGBQUAD {
	BYTE	rgbBlue;
	BYTE	rgbGreen;
	BYTE	rgbRed;
	BYTE	rgbReserved;
} RGBQUAD,*LPRGBQUAD;

typedef struct tagBITMAPINFO {
	BITMAPINFOHEADER bmiHeader;
	RGBQUAD bmiColors[1];
} BITMAPINFO,*LPBITMAPINFO,*PBITMAPINFO;

#endif


//  bit masks:    hex     binary
#define R_CLR       0xFE // 11111110
#define G_CLR       0xFE // 11111110
#define B_CLR       0xFC // 11111100  

#define RG_M1       0x01 // 00000001
#define RG_M2       0x02 // 00000010
#define  B_M3       0x0C // 00001100
#define RG_M4       0x10 // 00010000
#define RG_M5       0x20 // 00100000
#define  B_M6       0xC0 // 11000000

#define RG_DE       0x01 // 00000001 
#define  B_DE       0x03 // 00000011 

#define BI_RGB        0
#define BI_RLE8       1
#define BI_RLE4       2
#define BI_BITFIELDS  3
#define BI_JPEG       4
#define BI_PNG        5

#define SIGNATURE     "665"
#define IMG_BEGIN     ((strlen(SIGNATURE)*6)+24)


struct PIXEL // not used
{
BYTE r,g,b;
};

/* I'll try to implement this later*/
class CPicture
{

public:
virtual int   LoadImage(const char *_fn)=0;
virtual int   SaveImage(const char *_fn=0)=0;
virtual long  GetHidingCapacity()=0; 
virtual PIXEL GetPixel(int x,int y)=0;
};



class BMP
{
      

char *location;             // pvz: C:\folder\any.bmp
int  bpp;                   // 24  

int width,height,pitch;
BYTE* p_start;
public:

BITMAPFILEHEADER bmfh;      // failo info
BITMAPINFOHEADER bmih;      // bmp info 
RGBQUAD          *colors;   // spalvu palete
BYTE             *bitmap;   // tik pikseliai
 
BITMAPINFO *pbmi;           // tik piesimui 
public:
  BMP(const char *_fn);  
  BMP();   
      
 short LoadImage(const char *_fn); 
 short SaveImage(const char *_fn=0);   
  void Hide(BMP &_bmp);

   int HideFile(const char *_fn);
   int GetFileFromImage(const char *_fn);
  long GetHidingCapacity(); 

 PIXEL GetPixel(int,int); 
 PIXEL GetPixel(int);  
  void PutPixel(PIXEL,int);
  void PutPixel(PIXEL,int,int);
    
  void FileHeaderInfo();
  void InfoHeaderInfo();
  #ifdef _WIN32
  void WinPaint(HDC,int,int);
  #endif
  
private:
void Encode(BYTE *&_where,BYTE *_buff,int _size);
void Decode(BYTE *_where,BYTE *&_buff,int _size);      
      
      
};



bmp.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
#include "bmp.h"


/*
* CONSTRUCTORS
*/
BMP::BMP(const char *_fn)
{
location =new char;          
     LoadImage(_fn);
}
BMP::BMP()
{
location =new char;          
}
/*
*
* Does all kinds of crap to load a bitmap
* Returns:
*    1        Could not open file
*          
*/
short BMP::LoadImage(const char *_fn)
{  
  strcpy( location,_fn);
     
  long e=0,r=0; 
  
  fstream file(_fn,ios::in|ios::binary);
  if(!file.is_open()) return 1;
  file.seekg(0,ios::end);
  e=file.tellg();
  file.seekg(0,ios::beg);

  file.read((char*)&bmfh,sizeof(bmfh));
  file.seekg(sizeof(bmfh),ios::beg);
  file.read((char*)&bmih,sizeof(bmih));
  
  bpp=bmih.biBitCount;
  p_start=bitmap;
  height=bmih.biHeight;
  width=bmih.biWidth*(bpp/8);

  pitch = ((bmih.biWidth * bpp) + 31) / 32 * 4;

	if (bpp==24) pbmi=(BITMAPINFO*)new char [sizeof(BITMAPINFO)];
	else
   	  {
		cerr <<"This is a "<<bpp<<" bit bitmap. Only 24-bit bitmaps are supported"<<endl; cin.get(); exit(2);
	  }

     pbmi->bmiHeader=bmih; //MessageBox(0,"no crash!!!...?","",64);
     pbmi->bmiHeader.biHeight=-height;    
     bitmap= new BYTE[bmih.biSizeImage];

   /* if bitmap is upside down, read it backwards */
    file.seekg(bmfh.bfOffBits,ios::beg);
   	if (bmih.biHeight>0)
		for (int i=height-1;i>=0;i--)
			file.read ((char*)bitmap+width*i,width);
   else /* normal way */
   file.read((char*)bitmap,bmih.biSizeImage); 
    p_start=bitmap; // del sito susikto sudo turejau 3 dieanas kankinimosi
   file.close();

    if(height > 0)
     {
       p_start+= pitch * (height -1);
       pitch = -pitch;
     } 
  else
  height = -height;  
}


/*
*  Gets a pixel from a 24-bit bitmap
* Returns:
          PIXEL (struct)
* Takes:
*        int,int    X,Y coords
*          or
*        int        linear address
*
* NOTE: it's a 1 minute job. no quarantee that these functions work
*/
PIXEL BMP::GetPixel(int _row,int _col)
{  
    PIXEL tmp;  
    memcpy(&tmp,p_start+((_row*pitch) + _col),3);
    return tmp;
}
PIXEL BMP::GetPixel(int _la)
{  
    PIXEL tmp;  
    int _row=_la/height;
    int _col=_la-(_row*width);
    memcpy(&tmp,(p_start+(_row*pitch) + _col),3);
    return tmp;
}

void BMP::PutPixel(PIXEL _pix,int _la)
{
    int _row=_la/height;
    int _col=_la-(_row*width);
    memcpy(p_start+((_row*pitch) + _col),&_pix,3);


}

/*
*  Returns how much information may be hideen in a bitmap (in bytes)
*
* FIXME/CHECK: I can't quarantee that these function  works correctly
*/
long BMP::GetHidingCapacity()
{
     
  return (bmih.biSizeImage)/6;

}

/*
*  Reads file and hides it inside a 24-bit bitmap
* Return codes:
*     0       Success         
*     1       Could not create file
*     2       File is too big to fit into bitmap
*     3       File is empty or failed to get file size
*/
int BMP::HideFile(const char *_fn)
{

  long s=0;                    // file size
  long c=GetHidingCapacity();  // how much can we hide to bitmap
  BYTE *buff;                  // buffer that holds file to hide
  
  fstream file(_fn,ios::in | ios::binary);
    if(!file.is_open()) return 1;
    /* get file size */
  file.seekg(0,ios::end);
  s=file.tellg();
  file.seekg(0,ios::beg); 
     
    if(s>c) return 2;
    if(s<1) return 3;
  buff=new BYTE[s];
  file.read((char*)buff,s);
  file.close();

 /* encode file size */
   BYTE *mb=new BYTE[4]; 
   memcpy(mb,&s,4);
   Encode(bitmap,mb,4);  

BYTE *e_start=bitmap+(4*6);
     Encode(e_start,(BYTE*)SIGNATURE,sizeof(SIGNATURE));
     e_start=bitmap+IMG_BEGIN;
 /* encode file to bitmap */
   Encode(e_start,buff,s);

  delete[] buff;
  delete[] mb;
  return 0;  
}



/*
*  Gets a hidden file from image
* Return codes:
*     0       Success         
*     1       Could not create file
*     2       Invalid file size
*     3       Signature not found
*/
int BMP::GetFileFromImage(const char *_fn)
{
  BYTE *buff;
  unsigned int    s;  // file size
    
  fstream file(_fn,ios::out|ios::binary);
  if(!file.is_open()) return 1;
  
  /* get size of file in the bitmap */
  BYTE *sz=new BYTE[4];   
  Decode(bitmap,sz,4);
  memcpy(&s,sz,4);
  
  if(s>GetHidingCapacity()) return 2;
     BYTE *d_start=bitmap+(4*6);
  
  BYTE *signature=new BYTE[strlen(SIGNATURE)];
  Decode(d_start,signature,strlen(SIGNATURE));
  if(strcmp((const char*)signature,SIGNATURE)!=0) return 3;
  
  d_start=bitmap+IMG_BEGIN;
   buff=new BYTE[s];
   Decode(d_start,buff,s);
   file.write((char*)buff,s);
   delete[] buff;
   delete[] sz;
   return 0;      

    
}





void BMP::Decode(BYTE *_where,BYTE *&_buff,int _size)
{
memset(_buff,0,_size);   
int i=0,j=0;
while(j<_size)
  {
    
    _buff[j]|= (   _where[i] & RG_DE ) <<0; // *******X
    _buff[j]|= ( _where[i+1] & RG_DE ) <<1; // ******X*
    _buff[j]|= ( _where[i+2] &  B_DE ) <<2; // ****XX**
                                                   
    _buff[j]|= ( _where[i+3] & RG_DE ) <<4; // ***X****
    _buff[j]|= ( _where[i+4] & RG_DE ) <<5; // **X*****
    _buff[j]|= ( _where[i+5] &  B_DE ) <<6; // XX******
    
      i+=6,j++;
  }

}

void BMP::Encode(BYTE *&_where,BYTE *_buff,int _size)
{
int i=0,j=0;
while(j<_size)
  {

    /* clear last 1 or 2 bits */
      _where[i]&=R_CLR;
    _where[i+1]&=G_CLR;
    _where[i+2]&=B_CLR;
    
    _where[i+3]&=R_CLR;
    _where[i+4]&=G_CLR;
    _where[i+5]&=B_CLR;
    
//                                           bits accessed from _buff[j]
      _where[i]|=(( _buff[j] & RG_M1 ) ) >>0; // X*******
    _where[i+1]|=(( _buff[j] & RG_M2 ) ) >>1; // *X******
    _where[i+2]|=(( _buff[j] &  B_M3 ) ) >>2; // **XX****
    
    _where[i+3]|=(( _buff[j] & RG_M4 ) ) >>4; // ****X***
    _where[i+4]|=(( _buff[j] & RG_M5 ) ) >>5; // *****X**
    _where[i+5]|=(( _buff[j] &  B_M6 ) ) >>6; // ******XX
    
    i+=6,j++;
        
  }

}




/*
* Saves bitmap to file
* if no file name given (default parameter _fn=0) then overwrites origiunal file
*   Return codes:
*        0        Success
*        1        Could not open file
*        2        Failed to write to file 
*/
short BMP::SaveImage(const char *_fn)
{
   fstream file;
   if(_fn==0)
       file.open(location,ios::out|ios::binary);
   else
       file.open(_fn,ios::out | ios::binary);
   if(!file.is_open()) return 1;
   if(height>0)bmih.biHeight=-height;
   
   file.write((char*)&bmfh,sizeof(BITMAPFILEHEADER));    
   file.write((char*)&bmih,sizeof(BITMAPINFOHEADER)); 
   file.write((char*)colors,sizeof(RGBQUAD)*bmih.biClrUsed);
   file.write((char*)bitmap,bmih.biSizeImage);
   if(file.fail()) return 2;     
   file.close(); 
   return 0;    
}



void BMP::FileHeaderInfo()
{
cout <<"\nFile header\n------------------------------\n";
     cout <<"File type:             "<<bmfh.bfType<<endl;
     cout <<"File size:             "<<bmfh.bfSize<<endl;
     cout <<"Reserved1:             "<<bmfh.bfReserved1<<endl;
     cout <<"Reserved2:             "<<bmfh.bfReserved2<<endl;          
     cout <<"Offset bits:           "<<bmfh.bfOffBits<<endl;
     
}    

void BMP::InfoHeaderInfo()
{    

cout <<"\nInfo header\n------------------------------\n";
     cout <<"struct req. size:        "<<bmih.biSize<<endl;
     cout <<"Width:                   "<<bmih.biWidth<<endl;
     cout <<"Height:                  "<<bmih.biHeight<<endl;
     cout <<"Planes (==1):            "<<bmih.biPlanes<<endl;
     cout <<"Bits per pixel:          "<<bmih.biBitCount<<endl;
     cout <<"Compression:             "<<bmih.biCompression<<endl;
     cout <<"     Type:               ";
            if(bmih.biCompression==BI_RGB)       cout <<" none"<<endl;
            if(bmih.biCompression==BI_RLE8)      cout <<" RLE 8 bpp "<<endl;
            if(bmih.biCompression==BI_RLE4)      cout <<" RLE 4 bpp "<<endl;
            if(bmih.biCompression==BI_BITFIELDS) cout <<" 24 bpp bitfields "<<endl;      
            if(bmih.biCompression==BI_JPEG)      cout <<"jpeg inside bmp? What a hell...? "<<endl;   
            if(bmih.biCompression==BI_PNG)       cout <<"jpng inside bmp? What a hell...? "<<endl;                                     
     cout <<"Image size:              "<<bmih.biSizeImage<<endl;
     cout <<"pixels per meter X:      "<<bmih.biXPelsPerMeter<<endl;
     cout <<"pixels per meter Y:      "<<bmih.biYPelsPerMeter<<endl;     
     cout <<"Colors used:             "<<bmih.biClrUsed<<endl;     
     cout <<"Important colors:        "<<bmih.biClrImportant<<endl;      
}


#ifdef _WIN32
/*
* A fast function to paint bitmap on windows (much faster than SetPixel)
*
*/
void BMP::WinPaint (HDC hdc,int x=0,int y=0)
{  

  SetDIBitsToDevice (hdc,x,y,width,height,0,0,0,height,(LPVOID)bitmap,pbmi,0);
  
}
#endif 
Didn't compile on VC++.
er... What errors did you get?

1>------ Build started: Project: bmp, Configuration: Debug Win32 ------
1>Compiling...
1>bmp.cpp
1>c:\users\alan\documents\sdl\bmp\bmp\bmp.h(70) : warning C4005: 'BI_RGB' : macro redefinition
1>        c:\program files\microsoft sdks\windows\v6.0a\include\wingdi.h(775) : see previous definition of 'BI_RGB'
1>c:\users\alan\documents\sdl\bmp\bmp\bmp.h(71) : warning C4005: 'BI_RLE8' : macro redefinition
1>        c:\program files\microsoft sdks\windows\v6.0a\include\wingdi.h(776) : see previous definition of 'BI_RLE8'
1>c:\users\alan\documents\sdl\bmp\bmp\bmp.h(72) : warning C4005: 'BI_RLE4' : macro redefinition
1>        c:\program files\microsoft sdks\windows\v6.0a\include\wingdi.h(777) : see previous definition of 'BI_RLE4'
1>c:\users\alan\documents\sdl\bmp\bmp\bmp.h(73) : warning C4005: 'BI_BITFIELDS' : macro redefinition
1>        c:\program files\microsoft sdks\windows\v6.0a\include\wingdi.h(778) : see previous definition of 'BI_BITFIELDS'
1>c:\users\alan\documents\sdl\bmp\bmp\bmp.h(74) : warning C4005: 'BI_JPEG' : macro redefinition
1>        c:\program files\microsoft sdks\windows\v6.0a\include\wingdi.h(779) : see previous definition of 'BI_JPEG'
1>c:\users\alan\documents\sdl\bmp\bmp\bmp.h(75) : warning C4005: 'BI_PNG' : macro redefinition
1>        c:\program files\microsoft sdks\windows\v6.0a\include\wingdi.h(780) : see previous definition of 'BI_PNG'
1>c:\users\alan\documents\sdl\bmp\bmp\bmp.cpp(25) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\string.h(74) : see declaration of 'strcpy'
1>c:\users\alan\documents\sdl\bmp\bmp\bmp.cpp(190) : warning C4018: '>' : signed/unsigned mismatch
1>c:\users\alan\documents\sdl\bmp\bmp\bmp.cpp(73) : warning C4715: 'BMP::LoadImageW' : not all control paths return a value
1>Compiling manifest to resources...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
1>Copyright (C) Microsoft Corporation.  All rights reserved.
1>Linking...
1>MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
1>C:\Users\alan\Documents\SDL\bmp\Debug\bmp.exe : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://c:\Users\alan\Documents\SDL\bmp\bmp\Debug\BuildLog.htm"
1>bmp - 2 error(s), 9 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
main.cpp


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "bmp.h"

int ret;
char choice;
string filepath,imagepath,savepath,secret;
BMP bmp;
int main()
{


    
    
    cout <<"========== File2Image ==========\n"<<endl;
    cout <<"Only 24-bit uncompressed bitmaps are supported!"<<endl<<endl;
    cout <<"Press:"<<endl;
    cout <<"   0  -- Quit "<<endl;    
    cout <<"   1  -- Hide file "<<endl;
    cout <<"   2  -- Get file from an image "<<endl ;   
    
    cin >>choice;
    
    cout <<"Enter path of the image file: ";
    cin >>imagepath;   
    
    bmp.LoadImage(imagepath.c_str());  // load image 
    
    if (choice=='0') return 0;        
    if(choice=='1')
      {
     /* show some information about bitmap */
      //  bmp.FileHeaderInfo();
      //  bmp.InfoHeaderInfo();
          cout <<"\n    You can hide up to "<<bmp.GetHidingCapacity()/1024<<" KB of information in this image"<<endl;           
        cout <<"Enter path of the file you want to hide: ";        
        cin >>filepath;  
                  
    
        
 
      
 
        switch(bmp.HideFile(filepath.c_str()))
          {
            case 0: cout <<"File is successfully encoded into picture"<<endl;                   break;                        
            case 1: cout <<"Error: Could not create file for for information ecoding."<<endl;   break;
            case 2: cout <<"Error: File is too big to fit to picture."<<endl;                   break;
            case 3: cout <<"Error: File is empty or could not get file size."<<endl;            break;                                
           default: cout <<"Unknown error"<<endl;                                               break;                                 
          }      
                                    
        switch(bmp.SaveImage(imagepath.c_str()))
          {
            case 0:     cout <<"File saved successfuly."<<endl;            break;                                
            case 1:     cout <<"Error: Could not open file."<<endl;        break;
            case 2:     cout <<"Error: Could not write to file."<<endl;    break;                                
          } 
      }    
    else
      {    
         cout <<"Enter path where to save the secret file: ";
         cin >>secret;                              
         switch(bmp.GetFileFromImage(secret.c_str()))
           {
             case 0:   cout <<"Completed successfully"<<endl;           break;
             case 1:   cout <<"Error: Could not open an image"<<endl;   break;
             case 2:   cout <<"Error: File size is invalid"<<endl;      break;
             case 3:   cout <<"Error: Signature not found"<<endl;      break;                                                     
           }                                         
      }
     #ifdef _WIN32
     system("pause");
     #else
     system("wait"); // Does "wait" does the same as "pause" on windows?
     #endif
    return 0;
}


#pragma pack(push,2)
You suck.
I never did figure out the pragma directive...
@helios: what's wrong?
#pragma isn't portable. It's behavior is compiler-dependent.
Topic archived. No new replies allowed.