DIB.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. // DIB.cpp
  2. #include "stdafx.h"
  3. #include "DIB.h"
  4. CDib::CDib()
  5. {
  6. m_pDib = NULL;
  7. m_pWordData = NULL;
  8. m_pFile = NULL;
  9. m_pOldDibShow = NULL;
  10. }
  11. CDib::~CDib()
  12. {
  13. if( m_pDib != NULL )
  14. delete [] m_pDib;
  15. if( m_pWordData != NULL )
  16. delete [] m_pWordData;
  17. if (m_pFile != NULL)
  18. delete [] m_pFile;
  19. if (m_pOldDibShow != NULL)
  20. delete [] m_pOldDibShow;
  21. }
  22. BOOL CDib::Load( const char *pszFilename )
  23. {
  24. CFile cf;
  25. if( !cf.Open( pszFilename, CFile::modeRead ) )
  26. return( FALSE );
  27. DWORD dwDibSize;
  28. dwDibSize =
  29. cf.GetLength() - sizeof( BITMAPFILEHEADER );
  30. unsigned char *pDib;
  31. pDib = new unsigned char [dwDibSize];
  32. if( pDib == NULL )
  33. return( FALSE );
  34. BITMAPFILEHEADER BFH;
  35. try{
  36. if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
  37. != sizeof( BITMAPFILEHEADER ) ||
  38. BFH.bfType != 'MB' ||
  39. cf.Read( pDib, dwDibSize ) != dwDibSize ){
  40. delete [] pDib;
  41. return( FALSE );
  42. }
  43. }
  44. catch( CFileException *e ){
  45. e->Delete();
  46. delete [] pDib;
  47. return( FALSE );
  48. }
  49. cf.Close();
  50. if( m_pDib != NULL )
  51. delete m_pDib;
  52. if (BFH.bfReserved1 != 0) //含有隐藏信息,保存其大小
  53. {
  54. if (BFH.bfReserved2 == 0)
  55. embfile_size = BFH.bfReserved1;
  56. else
  57. embfile_size = BFH.bfReserved1 + 65535;
  58. }
  59. m_pDib = pDib;
  60. m_dwDibSize = dwDibSize;
  61. m_pBIH = (BITMAPINFOHEADER *) m_pDib;
  62. m_pPalette =
  63. (RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
  64. m_nPaletteEntries = 1 << m_pBIH->biBitCount;
  65. if( m_pBIH->biBitCount > 8 )
  66. m_nPaletteEntries = 0;
  67. else if( m_pBIH->biClrUsed != 0 )
  68. m_nPaletteEntries = m_pBIH->biClrUsed;
  69. m_pDibBits =
  70. &m_pDib[sizeof(BITMAPINFOHEADER)+
  71. m_nPaletteEntries*sizeof(RGBQUAD)];
  72. if( m_Palette.GetSafeHandle() != NULL )
  73. m_Palette.DeleteObject();
  74. if( m_nPaletteEntries != 0 ){
  75. LOGPALETTE *pLogPal = (LOGPALETTE *) new char
  76. [sizeof(LOGPALETTE)+
  77. m_nPaletteEntries*sizeof(PALETTEENTRY)];
  78. if( pLogPal != NULL ){
  79. pLogPal->palVersion = 0x300;
  80. pLogPal->palNumEntries = m_nPaletteEntries;
  81. for( int i=0; i<m_nPaletteEntries; i++ ){
  82. pLogPal->palPalEntry[i].peRed =
  83. m_pPalette[i].rgbRed;
  84. pLogPal->palPalEntry[i].peGreen =
  85. m_pPalette[i].rgbGreen;
  86. pLogPal->palPalEntry[i].peBlue =
  87. m_pPalette[i].rgbBlue;
  88. }
  89. m_Palette.CreatePalette( pLogPal );
  90. delete [] pLogPal;
  91. }
  92. }
  93. m_BitCount = 24; //24位位图
  94. p = m_pDibBits; //指向位图数据的指针,用来执行处理操作用
  95. bitmap_size = m_dwDibSize - (m_pDibBits - m_pDib);//真正的位图数据的大小(即除头结构外)
  96. tag = BFH.bfReserved1;
  97. return( TRUE );
  98. }
  99. BOOL CDib::Save( const char *pszFilename ) //保存含有隐藏信息的bmp
  100. {
  101. if( m_pDib == NULL )
  102. return( FALSE );
  103. CFile cf;
  104. if( !cf.Open( pszFilename,
  105. CFile::modeCreate | CFile::modeWrite ) )
  106. return( FALSE );
  107. try{
  108. BITMAPFILEHEADER BFH;
  109. memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
  110. BFH.bfType = 'MB';
  111. BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
  112. BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
  113. sizeof( BITMAPINFOHEADER ) +
  114. m_nPaletteEntries * sizeof( RGBQUAD );
  115. if (embfile_size <= 65535) //由于bfReserved1是unsigned short型的,大小可能不能满足要求,可能要用到reserved2
  116. BFH.bfReserved1 = embfile_size;
  117. else
  118. {
  119. BFH.bfReserved1 = embfile_size - 65535;
  120. BFH.bfReserved2 = 1; //标记
  121. }
  122. cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
  123. cf.Write( m_pDib, m_dwDibSize );
  124. }
  125. catch( CFileException *e ){
  126. e->Delete();
  127. return( FALSE );
  128. }
  129. return( TRUE );
  130. }
  131. BOOL CDib::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight, int Style )
  132. {
  133. if( m_pDib == NULL )
  134. return( FALSE );
  135. long vWidth = m_pBIH->biWidth;
  136. if( nWidth == -1 )
  137. nWidth = m_pBIH->biWidth;
  138. if( nHeight == -1 )
  139. nHeight = m_pBIH->biHeight;
  140. if (Style)
  141. {
  142. StretchDIBits( pDC->m_hDC, nX, nY,
  143. nWidth, nHeight,
  144. 0, 0,
  145. m_pBIH->biWidth, m_pBIH->biHeight,
  146. m_pDibBits,
  147. (BITMAPINFO *) m_pBIH,
  148. BI_RGB, SRCCOPY );
  149. }
  150. else
  151. {
  152. SetDIBitsToDevice( pDC->m_hDC, nX, nY,
  153. m_pBIH->biWidth, m_pBIH->biHeight,
  154. 0, 0,
  155. 0, m_pBIH->biHeight,
  156. m_pDibBits,
  157. (BITMAPINFO *) m_pBIH,
  158. BI_RGB);
  159. }
  160. return( TRUE );
  161. }
  162. BOOL CDib::LoadEmbFile(const char * pszFilename)
  163. {
  164. CFile cf;
  165. if( !cf.Open( pszFilename, CFile::modeRead ) )
  166. return( FALSE );
  167. DWORD dwFileSize;
  168. dwFileSize = cf.GetLength();
  169. embfile_size = dwFileSize;
  170. unsigned char *pFile;
  171. pFile = new unsigned char [dwFileSize];
  172. cf.Read( pFile, dwFileSize ); //将文件中内容读入数组,解下来就开始嵌入操作
  173. m_pFile = pFile;
  174. q = pFile; //记录下位置
  175. return true;
  176. }
  177. void CDib::Embed()//嵌入
  178. {
  179. unsigned char bmdata;//bitmap data
  180. unsigned char efdata;//embeddedfile data
  181. int t = 7;
  182. int x[8];
  183. int s[8];
  184. int last_bit; //记录字节最低位本来的bit
  185. for(UINT i1 = 0, i2 = 0; i1 <= bitmap_size - 1, i2 <= embfile_size - 1; i1++)
  186. {
  187. bmdata = *p;
  188. int j = 0;
  189. for ( j = 0; j <= 7; j++) //计算各bit位
  190. {
  191. x[j] = bmdata & 1;
  192. bmdata >>= 1;
  193. }
  194. last_bit = x[0];
  195. x[0] = x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7];
  196. if (t == 7) //宿主图片每走过八个字节,计算一次s[]
  197. {
  198. efdata = *q;
  199. for (j = 0; j <= 7; j++)
  200. {
  201. s[j] = efdata & 1;
  202. efdata >>= 1;
  203. }
  204. }
  205. x[0] ^= s[t];//隐藏信息
  206. if (last_bit == 0) //嵌入隐藏信息
  207. {
  208. *p |= x[0];
  209. }
  210. else
  211. {
  212. *p &= 254 + x[0];
  213. }
  214. p++;
  215. t--;
  216. if (t == -1) //需要计算一次s[]
  217. {
  218. t = 7;
  219. q++;
  220. i2++;
  221. }
  222. }
  223. }
  224. void CDib::Pick()//提取
  225. {
  226. m_pFile = new unsigned char [embfile_size];
  227. unsigned char *q = m_pFile;
  228. unsigned char bmdata;//bitmap data
  229. int x[8];
  230. int s[8];
  231. int t = 7;
  232. for (UINT i1 = 0, i2 = 0; i1 <= bitmap_size - 1, i2 <= embfile_size - 1; i1++)
  233. {
  234. bmdata = *p;
  235. for (int j = 0; j <= 7; j++) //计算各bit位
  236. {
  237. x[j] = bmdata & 1;
  238. bmdata >>= 1;
  239. }
  240. s[t] = x[0] ^ x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7];
  241. t--;
  242. if (t == -1) //s[7]到s[0]组成一个字节
  243. {
  244. *q = s[7] * 128 + s[6] * 64 + s[5] * 32 + s[4] * 16 +
  245. s[3] * 8 + s[2] * 4 + s[1] * 2 + s[0];
  246. t = 7;
  247. i2++;
  248. q++;
  249. }
  250. p++;
  251. }
  252. }
  253. void CDib::SavePicked( const char *pszFilename )
  254. {
  255. CFile cf;
  256. cf.Open( pszFilename, CFile::modeCreate | CFile::modeWrite );
  257. cf.Write( m_pFile, embfile_size );
  258. }
  259. void CDib::BackUpDib()
  260. {
  261. m_pOldDibShow = new unsigned char [bitmap_size];
  262. ::CopyMemory(m_pOldDibShow, m_pDibBits, bitmap_size); //将原始的数据单独保存以便对比显示
  263. }
  264. BOOL CDib::DrawContrast(CDC *pDC, int rect_width, int rect_height)
  265. { //看原图,如果容纳得下两个图,则不要压缩,否则要压缩
  266. if (m_pOldDibShow == NULL)
  267. return FALSE;
  268. if (rect_width >= 2*m_pBIH->biWidth + 30 && rect_height >= m_pBIH->biHeight)
  269. {
  270. StretchDIBits( pDC->m_hDC, 0, 0,
  271. m_pBIH->biWidth, m_pBIH->biHeight,
  272. 0, 0,
  273. m_pBIH->biWidth, m_pBIH->biHeight,
  274. m_pOldDibShow,
  275. (BITMAPINFO *) m_pBIH,
  276. BI_RGB, SRCCOPY ); // 原图
  277. StretchDIBits( pDC->m_hDC, m_pBIH->biWidth+30, 0,
  278. m_pBIH->biWidth, m_pBIH->biHeight,
  279. 0, 0,
  280. m_pBIH->biWidth, m_pBIH->biHeight,
  281. m_pDibBits,
  282. (BITMAPINFO *) m_pBIH,
  283. BI_RGB, SRCCOPY ); // 嵌入隐藏信息的图
  284. }
  285. else
  286. {
  287. int scale_i = m_pBIH->biWidth * 5 / (rect_width*2);
  288. int scale_j = m_pBIH->biHeight / rect_height;
  289. if (scale_i < scale_j)
  290. scale_i = scale_j;
  291. StretchDIBits( pDC->m_hDC, 0, 0,
  292. m_pBIH->biWidth / scale_i, m_pBIH->biHeight / scale_i,
  293. 0, 0,
  294. m_pBIH->biWidth, m_pBIH->biHeight,
  295. m_pOldDibShow,
  296. (BITMAPINFO *) m_pBIH,
  297. BI_RGB, SRCCOPY ); // 原图
  298. StretchDIBits( pDC->m_hDC, m_pBIH->biWidth / scale_i+30, 0,
  299. m_pBIH->biWidth / scale_i, m_pBIH->biHeight / scale_i,
  300. 0, 0,
  301. m_pBIH->biWidth, m_pBIH->biHeight,
  302. m_pDibBits,
  303. (BITMAPINFO *) m_pBIH,
  304. BI_RGB, SRCCOPY ); // 嵌入隐藏信息的图
  305. }
  306. return TRUE;
  307. }