MfcAppView.cpp
上传用户:cjw5120
上传日期:2022-05-11
资源大小:5032k
文件大小:17k
源码类别:

网络截获/分析

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////////////////////
  2. // mfcappView.cpp : implementation of the CMfcappView class
  3. //
  4. //
  5. // Note  : GIF code removed 9/23/97 pending Unisys licensing. 
  6. //
  7. //
  8. // This code copyright 1997 Chris Losinger, unless otherwise noted
  9. //
  10. // CHRISDL@PAGESZ.NET
  11. //
  12. // PLEASE!!! Tell me of any bugs you find!!!
  13. //
  14. // This code contains examples of using my JpegFile class, how to
  15. // read and write 1,4,8 and 24-bit BMPs 
  16. //
  17. // I find that this code works well for my purposes. Feel free to 
  18. // use it in your own code, but I can't assume any responsibility
  19. // if this code fails to do what you expect.
  20. //
  21. // If you find any problems with this code, feel free to contact 
  22. // me for help.
  23. //
  24. // 24-bit to 8-bit color quantization code modified from Dennis Lee's
  25. // DL1Quant. His source is available at ...
  26. //
  27. // MfcAppView.cpp : implementation of the CMfcAppView class
  28. //
  29. #include "stdafx.h"
  30. #include "MfcApp.h"
  31. #include <math.h>
  32. #include "MfcAppDoc.h"
  33. #include "MfcAppView.h"
  34. #include "JpegFile.h"
  35. #include "BMPDlg.h"
  36. #include "BMPFile.h"
  37. #include "QuantDlg.h"
  38. #include "dl1quant.h"
  39. #ifdef _DEBUG
  40. #define new DEBUG_NEW
  41. #undef THIS_FILE
  42. static char THIS_FILE[] = __FILE__;
  43. #endif
  44. /////////////////////////////////////////////////////////////////////////////
  45. // CMfcAppView
  46. IMPLEMENT_DYNCREATE(CMfcAppView, CView)
  47. BEGIN_MESSAGE_MAP(CMfcAppView, CView)
  48. //{{AFX_MSG_MAP(CMfcAppView)
  49. ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
  50. ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
  51. ON_COMMAND(ID_FILE_SAVECOLORMAPPEDBMP, OnFileSavecolormappedbmp)
  52. ON_COMMAND(ID_FILE_SAVEGRAYAS, OnFileSavegrayas)
  53. ON_COMMAND(ID_FILE_GETDIMENSIONSJPG, OnFileGetdimensionsjpg)
  54. ON_COMMAND(ID_PLAY, OnPlay)
  55. ON_COMMAND(ID_STOP, OnStop)
  56. ON_COMMAND(ID_PAUSE, OnPause)
  57. ON_UPDATE_COMMAND_UI_RANGE(ID_PAUSE,ID_PAUSE, OnPause)
  58. // ON_COMMAND_RANGE(ID_PAUSE, ID_PAUSE, OnViewPause)
  59. //}}AFX_MSG_MAP
  60. END_MESSAGE_MAP()
  61. /////////////////////////////////////////////////////////////////////////////
  62. // CMfcAppView construction/destruction
  63. CMfcAppView::CMfcAppView()
  64. {
  65. // we keep a single global image in memory
  66. m_buf=NULL; // where we keep our image data
  67. m_width=0; // image dimensions
  68. m_height=0;
  69. m_widthDW=0;
  70. m_bPause = false;
  71. }
  72. CMfcAppView::~CMfcAppView()
  73. {
  74. // clean up
  75. if (m_buf!=NULL) {
  76. delete [] m_buf;
  77. m_buf=NULL;
  78. }
  79. }
  80. BOOL CMfcAppView::PreCreateWindow(CREATESTRUCT& cs)
  81. {
  82. // TODO: Modify the Window class or styles here by modifying
  83. //  the CREATESTRUCT cs
  84. return CView::PreCreateWindow(cs);
  85. }
  86. /////////////////////////////////////////////////////////////////////////////
  87. // CMfcAppView drawing
  88. void CMfcAppView::OnDraw(CDC* pDC)
  89. {
  90. CMfcAppDoc* pDoc = GetDocument();
  91. ASSERT_VALID(pDoc);
  92. // draw the BMP we have in memory
  93. DrawBMP();
  94. }
  95. /////////////////////////////////////////////////////////////////////////////
  96. // CMfcAppView diagnostics
  97. #ifdef _DEBUG
  98. void CMfcAppView::AssertValid() const
  99. {
  100. CView::AssertValid();
  101. }
  102. void CMfcAppView::Dump(CDumpContext& dc) const
  103. {
  104. CView::Dump(dc);
  105. }
  106. CMfcAppDoc* CMfcAppView::GetDocument() // non-debug version is inline
  107. {
  108. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMfcAppDoc)));
  109. return (CMfcAppDoc*)m_pDocument;
  110. }
  111. #endif //_DEBUG
  112. /////////////////////////////////////////////////////////////////////////////
  113. // CMfcAppView message handlers
  114. void CMfcAppView::OnFileOpen() 
  115. {
  116. CString fileName;
  117. CString filt="JPG File (*.JPG)|*.JPG|BMP (*.BMP)|*.BMP|All files (*.*)|*.*||";
  118.     
  119.     // OPENFILENAME - so i can get to its Help page easily
  120. CFileDialog fileDlg(TRUE,"*.JPG","*.JPG",NULL,filt,this);
  121. fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
  122. fileDlg.m_ofn.lpstrTitle="File to load";
  123. if (fileDlg.DoModal()==IDOK) {
  124. AfxGetApp()->DoWaitCursor(1);
  125. fileName=fileDlg.GetPathName();
  126. CString ext=fileName.Right(4);
  127. if (!ext.CompareNoCase(".JPG"))
  128. LoadJPG(fileName);
  129. if (!ext.CompareNoCase(".BMP"))
  130. LoadBMP(fileName);
  131. AfxGetApp()->DoWaitCursor(-1);
  132. }            
  133. // force a redraw
  134. Invalidate(TRUE);
  135. }
  136. void CMfcAppView::OnFileSaveAs() 
  137. {
  138. CString fileName;
  139. CString filt="JPG File (*.JPG)|*.JPG|BMP (*.BMP)|*.BMP|All files (*.*)|*.*||";
  140.     
  141.     // OPENFILENAME - so i can get to its Help page easily
  142. CFileDialog fileDlg(FALSE,"*.JPG","*.JPG",NULL,filt,this);
  143. fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
  144. fileDlg.m_ofn.lpstrTitle="File to save as";
  145. if (fileDlg.DoModal()==IDOK) {
  146. AfxGetApp()->DoWaitCursor(1);
  147. fileName=fileDlg.GetPathName();
  148. CString ext=fileName.Right(4);
  149. if (!ext.CompareNoCase(".JPG"))
  150. SaveJPG(fileName,TRUE);
  151. if (!ext.CompareNoCase(".BMP"))
  152. SaveBMP24(fileName);
  153. AfxGetApp()->DoWaitCursor(-1);
  154. }      
  155. }
  156. void CMfcAppView::OnFileSavecolormappedbmp() 
  157. {
  158. if (m_buf==NULL) {
  159. AfxMessageBox("No Image!");
  160. return;
  161. }
  162. ////////////////////////////////////////////////////////////////////////
  163. // get the filename
  164. CString fileName;
  165. CString filt="BMP (*.BMP)|*.BMP|All files (*.*)|*.*||";
  166.     
  167.     // OPENFILENAME - so i can get to its Help page easily
  168. CFileDialog fileDlg(FALSE,"*.BMP","*.BMP",NULL,filt,this);
  169. fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
  170. fileDlg.m_ofn.lpstrTitle="File to save as";
  171. if (fileDlg.DoModal()!=IDOK)
  172. return;
  173. fileName=fileDlg.GetPathName();
  174. ////////////////////////////////////////////////////////////////////////
  175. // fetch bits per pixel
  176. CBMPDlg theDlg;
  177. if (theDlg.DoModal()!=IDOK)
  178. return;
  179. int bitsperpixel = theDlg.m_bits;
  180. AfxGetApp()->DoWaitCursor(1);
  181. ////////////////////////////////////////////////////////////////////////
  182. // prepare for color-mapping
  183. // our palette
  184. RGBQUAD colormap[256];
  185. // num colors
  186. int colors = (int)pow(2,bitsperpixel);
  187. BYTE *colorMappedBuffer = NULL;
  188. // if we can use the color quantizer, we will
  189. if (bitsperpixel==8) {
  190. CQuantDlg theDlg;
  191. if (theDlg.DoModal()!=IDOK) {
  192. return;
  193. }
  194. // color or grayscale?
  195. if (theDlg.m_color) {
  196. // color !
  197. // allocate a buffer to colormap to
  198. colorMappedBuffer = (BYTE *)  new BYTE[m_width* m_height];
  199. if (colorMappedBuffer==NULL) {
  200. AfxMessageBox("Memory Error in OnSaveColormappedbmp!");
  201. return;
  202. }
  203. BYTE tmpPal[3][256];
  204. // colormap it 
  205. // generates an 8-bit color-mapped image into colorMappedBuffer
  206. if (!dl1quant(m_buf, 
  207. colorMappedBuffer, // buffers
  208. m_width,
  209. m_height,
  210. theDlg.m_quantColors,
  211. TRUE,
  212. tmpPal)) { // palette
  213. AfxMessageBox("Quantization error");
  214. delete [] colorMappedBuffer;
  215. return;
  216. }
  217. // copy our palette
  218. for (UINT col=0;col<256;col++) {
  219. if (col>theDlg.m_quantColors) {
  220. colormap[col].rgbRed=0;
  221. colormap[col].rgbBlue=0;
  222. colormap[col].rgbGreen=0;
  223. } else {
  224. colormap[col].rgbRed=tmpPal[0][col];
  225. colormap[col].rgbGreen=tmpPal[1][col];
  226. colormap[col].rgbBlue=tmpPal[2][col];
  227. }
  228. }
  229. } else {
  230. // gray :(
  231. // convert to 8-bit colormapped grayscale
  232. colorMappedBuffer = MakeColormappedGrayscale(m_buf, // RGB
  233. (UINT)m_width, // pixels
  234. (UINT)m_height, 
  235. (UINT)m_width * 3, // bytes
  236. (UINT)colors, // colors
  237. colormap); // palette
  238. }
  239. } else { // bitsperpixel!=8
  240. // based on bitsperpixel, create a colormapped image
  241. colorMappedBuffer = MakeColormappedGrayscale(m_buf, 
  242. (UINT)m_width, 
  243. (UINT)m_height, 
  244. (UINT)m_width * 3, 
  245. (UINT)colors,
  246. colormap);
  247. }
  248. ////////////////////////////////////////////////////////////////////////
  249. // finally, save the thing
  250. if (colorMappedBuffer!=NULL) {
  251. // write the BMP using our colormapped image (one byte per pixel, packed),
  252. // number of bits, number of total colors and a colormap
  253. // pixel values must be in the range [0...colors-1]
  254. BMPFile theBmpFile;
  255. theBmpFile.SaveBMP(fileName, // path
  256. colorMappedBuffer, // image
  257. m_width, // pixels
  258. m_height,
  259. bitsperpixel, // 1,4,8
  260. colors, // num colors
  261. colormap); // palette
  262. if (theBmpFile.m_errorText!="OK") {
  263. AfxMessageBox(theBmpFile.m_errorText, MB_ICONSTOP);
  264. }else {
  265. // load what we just saved
  266. LoadBMP(fileName);
  267. Invalidate(TRUE);
  268. }
  269. // toss our buffer...
  270. delete [] colorMappedBuffer;
  271. } else {
  272. AfxMessageBox("Failed to allocate space for RGB buffer");
  273. }
  274. AfxGetApp()->DoWaitCursor(-1);
  275. }
  276. void CMfcAppView::OnFileSavegrayas() 
  277. {
  278. // note, because i'm lazy, most image data in this app
  279. // is handled as 24-bit images. this makes the DIB
  280. // conversion easier. 1,4,8, 15/16 and 32 bit DIBs are
  281. // significantly more difficult to handle.
  282. CString fileName;
  283. CString filt="JPG File (*.JPG)|*.JPG|All files (*.*)|*.*||";
  284.     
  285.     // OPENFILENAME - so i can get to its Help page easily
  286. CFileDialog fileDlg(FALSE,"*.JPG","*.JPG",NULL,filt,this);
  287. fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
  288. fileDlg.m_ofn.lpstrTitle="File to save as grayscale";
  289. if (fileDlg.DoModal()==IDOK) {
  290. fileName=fileDlg.GetPathName();
  291. AfxGetApp()->DoWaitCursor(1);
  292. CString ext;
  293. ext=fileName.Right(4);
  294. if (!ext.CompareNoCase(".JPG"))
  295. SaveJPG(fileName,FALSE);
  296. AfxGetApp()->DoWaitCursor(-1);
  297. }
  298. }
  299. void CMfcAppView::DrawBMP()
  300. {
  301. // if we don't have an image, get out of here
  302. if (m_buf==NULL) return;
  303. CDC *theDC = GetDC();
  304. if (theDC!=NULL) {
  305. CRect clientRect;
  306. GetClientRect(clientRect);
  307. // Center It
  308. int left = max(clientRect.left, ((clientRect.Width() - (int)m_width) / 2));
  309. int top = max(clientRect.top, ((clientRect.Height() - (int)m_height) / 2));
  310. // a 24-bit DIB is DWORD-aligned, vertically flipped and 
  311. // has Red and Blue bytes swapped. we already did the 
  312. // RGB->BGR and the flip when we read the images, now do
  313. // the DWORD-align
  314. BYTE *tmp;
  315. // DWORD-align for display
  316. tmp = JpegFile::MakeDwordAlignedBuf(m_buf,
  317.  m_width,
  318.  m_height,
  319.  &m_widthDW);
  320. // set up a DIB 
  321. BITMAPINFOHEADER bmiHeader;
  322. bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  323. bmiHeader.biWidth = m_width;
  324. bmiHeader.biHeight = m_height;
  325. bmiHeader.biPlanes = 1;
  326. bmiHeader.biBitCount = 24;
  327. bmiHeader.biCompression = BI_RGB;
  328. bmiHeader.biSizeImage = 0;
  329. bmiHeader.biXPelsPerMeter = 0;
  330. bmiHeader.biYPelsPerMeter = 0;
  331. bmiHeader.biClrUsed = 0;
  332. bmiHeader.biClrImportant = 0;
  333. // now blast it to the CDC passed in.
  334. // lines returns the number of lines actually displayed
  335. int lines = StretchDIBits(theDC->m_hDC,
  336. left, top,
  337. bmiHeader.biWidth,
  338. bmiHeader.biHeight,
  339. 0,0,
  340. bmiHeader.biWidth,
  341. bmiHeader.biHeight,
  342. tmp,
  343. (LPBITMAPINFO)&bmiHeader,
  344. DIB_RGB_COLORS,
  345. SRCCOPY);
  346. delete [] tmp;
  347. CString info;
  348. info.Format("(%d x %d)", m_width, m_height);
  349. theDC->SetBkMode(TRANSPARENT);
  350. theDC->SetTextColor(RGB(0,0,0));
  351. theDC->TextOut(10,5, info);
  352. ReleaseDC(theDC);
  353. }
  354. }
  355. ////////////////////////////////////////////////////////////////////////////
  356. // read a JPG to our global buffer
  357. //
  358. void CMfcAppView::LoadJPG(CString fileName)
  359. {
  360. // m_buf is the global buffer
  361. if (m_buf!=NULL) {
  362. delete [] m_buf;
  363. m_buf=NULL;
  364. }
  365. // read to buffer tmp
  366. m_buf=JpegFile::JpegFileToRGB(fileName, &m_width, &m_height);
  367. //////////////////////
  368. // set up for display
  369. // do this before DWORD-alignment!!!
  370. // this works on packed (not DWORD-aligned) buffers
  371. // swap red and blue for display
  372. JpegFile::BGRFromRGB(m_buf, m_width, m_height);
  373. // vertical flip for display
  374. JpegFile::VertFlipBuf(m_buf, m_width * 3, m_height);
  375. }
  376. ////////////////////////////////////////////////////////////////////////////
  377. // read a BMP to our global buffer
  378. //
  379. void CMfcAppView::LoadBMP(CString fileName)
  380. {
  381. if (m_buf!=NULL) {
  382. delete [] m_buf;
  383. }
  384. BMPFile theBmpFile;
  385. m_buf=theBmpFile.LoadBMP(fileName, &m_width, &m_height);
  386. if ((m_buf==NULL) || (theBmpFile.m_errorText!="OK")) 
  387. {
  388. AfxMessageBox(theBmpFile.m_errorText);
  389. m_buf=NULL;
  390. return;
  391. }
  392. //////////////////////
  393. // set up for display
  394. // do this before DWORD-alignment!!!
  395. // this works on packed (not DWORD-aligned) buffers
  396. // swap red and blue for display
  397. JpegFile::BGRFromRGB(m_buf, m_width, m_height);
  398. // vertical flip for display
  399. JpegFile::VertFlipBuf(m_buf, m_width * 3, m_height);
  400. }
  401. ////////////////////////////////////////////////////////////////////////////
  402. // save functions are generally more complex than reading functions.
  403. // there are many more decisions to be made for writing than for reading.
  404. ////////////////////////////////////////////////////////////////////////////
  405. // save a JPG
  406. void CMfcAppView::SaveJPG(CString fileName, BOOL color)
  407. {
  408. // note, because i'm lazy, most image data in this app
  409. // is handled as 24-bit images. this makes the DIB
  410. // conversion easier. 1,4,8, 15/16 and 32 bit DIBs are
  411. // significantly more difficult to handle.
  412. if (m_buf==NULL) {
  413. AfxMessageBox("No Image!");
  414. return;
  415. }
  416. // we vertical flip for display. undo that.
  417. JpegFile::VertFlipBuf(m_buf, m_width * 3, m_height);
  418. // we swap red and blue for display, undo that.
  419. JpegFile::BGRFromRGB(m_buf, m_width, m_height);
  420. // save RGB packed buffer to JPG
  421. BOOL ok=JpegFile::RGBToJpegFile(fileName, 
  422. m_buf,
  423. m_width,
  424. m_height,
  425. color, 
  426. 75); // quality value 1-100.
  427. if (!ok) {
  428. AfxMessageBox("Write Error");
  429. } else {
  430. // load what we just saved
  431. LoadJPG(fileName);
  432. Invalidate(TRUE);
  433. }
  434. }
  435. ////////////////////////////////////////////////////////////////////////////
  436. //
  437. // use the BMPFile class to write a 24-bit BMP file
  438. //
  439. void CMfcAppView::SaveBMP24(CString filename)
  440. {
  441. // note, because i'm lazy, most image data in this app
  442. // is handled as 24-bit images. this makes the DIB
  443. // conversion easier. 1,4,8, 15/16 and 32 bit DIBs are
  444. // significantly more difficult to handle.
  445. if (m_buf==NULL) {
  446. AfxMessageBox("No Image!");
  447. return;
  448. }
  449. // image in m_buf is already BGR and vertically flipped, so we don't need
  450. // to do that for this function.
  451. // i really should make an RGB to BMP fn.
  452. BMPFile theBmpFile;
  453. theBmpFile.SaveBMP(filename,
  454. m_buf,
  455. m_width,
  456. m_height);
  457. if (theBmpFile.m_errorText!="OK") 
  458. AfxMessageBox(theBmpFile.m_errorText, MB_ICONSTOP);
  459. else {
  460. // load what we just saved
  461. LoadBMP(filename);
  462. Invalidate(TRUE);
  463. }
  464. }
  465. // get JPG dimensions
  466. void CMfcAppView::OnFileGetdimensionsjpg() 
  467. {
  468. CString fileName;
  469. CString filt="JPG File (*.JPG)|*.JPG|All files (*.*)|*.*||";
  470.     
  471.     // OPENFILENAME - so i can get to its Help page easily
  472. CFileDialog fileDlg(TRUE,"*.JPG","*.JPG",NULL,filt,this);
  473. fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
  474. fileDlg.m_ofn.lpstrTitle="File to examine";
  475. if (fileDlg.DoModal()==IDOK) {
  476. fileName=fileDlg.GetPathName();
  477. UINT width, height;
  478. if (JpegFile::GetJPGDimensions(fileName,
  479. &width,
  480. &height)) {
  481. char buf[200];
  482. sprintf(buf,"%d %d",width,height);
  483. AfxMessageBox(buf);
  484. } else
  485. AfxMessageBox("JPEG Error");
  486. }            
  487. }
  488. ////////////////////////////////////////////////////////////////////////
  489. // instead of creating a good palette for the colormapped images
  490. // this just graymaps them.
  491. //
  492. BYTE * CMfcAppView::MakeColormappedGrayscale(BYTE *inBuf,
  493.   UINT inWidth,
  494.   UINT inHeight,
  495.   UINT inWidthBytes,
  496.   UINT colors,
  497.   RGBQUAD* colormap)
  498. {
  499. ////////////////////////////////////////////////////////////////////////
  500. // allocate a buffer to colormap
  501. BYTE *tmp = (BYTE *)  new BYTE[inWidth * inHeight];
  502. if (tmp==NULL)
  503. return NULL;
  504. // force our image to use a stupid gray scale
  505. UINT color;
  506. for (color = 0;color < colors; color++) {
  507. colormap[color].rgbRed = color * 256 / colors;
  508. colormap[color].rgbGreen = color * 256 / colors;
  509. colormap[color].rgbBlue = color * 256 / colors;
  510. }
  511. UINT col, row;
  512. for (row =0; row < inHeight; row++) {
  513. for (col=0;col <inWidth; col++) {
  514. BYTE inRed, inBlue, inGreen;
  515. // src pixel
  516. long in_offset = row * inWidthBytes + col * 3;
  517. inRed = *(inBuf + in_offset + 0);
  518. inGreen = *(inBuf + in_offset + 1);
  519. inBlue = *(inBuf + in_offset + 2);
  520. // luminance
  521. int lum = (int)(.299 * (double)(inRed) + 
  522. .587 * (double)(inGreen) + 
  523. .114 * (double)(inBlue));
  524. // force luminance value into our range of colors
  525. lum = colors * lum / 256;
  526. // dest pixel
  527. long out_offset = row * inWidth + col;
  528. *(tmp+out_offset) = (BYTE)lum;
  529. }
  530. }
  531. return tmp;
  532. }
  533. void CMfcAppView::OnPlay() 
  534. {
  535. }
  536. void CMfcAppView::OnStop() 
  537. {
  538. }
  539. void CMfcAppView::OnPause() 
  540. {
  541.     if(m_bPause) 
  542. m_bPause = FALSE;
  543. else
  544. m_bPause = TRUE;
  545. }
  546. void CMfcAppView::OnPause(CCmdUI* pCmdUI) 
  547. {
  548. if (m_bPause)
  549.   pCmdUI->SetCheck(pCmdUI->m_nID == ID_PAUSE);
  550. else
  551.   pCmdUI->SetCheck(pCmdUI->m_nID == 0);
  552. }
  553. /*
  554. void CMfcAppView::OnViewPause(UINT nID)
  555. {
  556.     if(m_bPause) 
  557. m_bPause = FALSE;
  558. else
  559. m_bPause = TRUE;
  560. OnInitialUpdate();
  561. }
  562. */