RCAHelper.cpp
上传用户:hyz2004817
上传日期:2022-03-30
资源大小:226k
文件大小:14k
源码类别:

远程控制编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. BOOL 
  3. WINAPI 
  4. DecodeFromJPEGBuffer(
  5.   BYTE * lpJpgBuffer,
  6.   DWORD  dwJpgBufferSize,
  7.   BYTE** lppRgbBuffer,
  8.   DWORD* lpdwWidth,
  9.   DWORD* lpdwHeight,
  10.   DWORD* lpdwNumberOfChannels
  11.   )
  12.  {
  13.  
  14. BOOL  bres;
  15. IJLERR  jerr;
  16. DWORD  dwWholeImageSize;
  17. BYTE*  lpTemp = NULL;
  18. // Allocate the IJL JPEG_CORE_PROPERTIES structure.
  19. JPEG_CORE_PROPERTIES jcprops;
  20. bres = TRUE;
  21. __try
  22. {
  23. // Initialize the Intel(R) JPEG Library.
  24. jerr = ijlInit(&jcprops);
  25. if(IJL_OK != jerr)
  26. {
  27. bres = FALSE;
  28. __leave;
  29.  
  30. // Get information on the JPEG image
  31. // (i.e., width, height, and channels).
  32. jcprops.JPGFile = NULL;
  33. jcprops.JPGBytes = lpJpgBuffer;
  34. jcprops.JPGSizeBytes = dwJpgBufferSize;
  35. jerr = ijlRead(&jcprops, IJL_JBUFF_READPARAMS);
  36. if(IJL_OK != jerr)
  37. {
  38. bres = FALSE;
  39. __leave;
  40. }
  41. // Set the JPG color space ... this will always be
  42. // somewhat of an educated guess at best because JPEG
  43. // is "color blind" (i.e., nothing in the bit stream
  44. // tells you what color space the data was encoded from).
  45. // However, in this example we assume that we are
  46. // reading JFIF files which means that 3 channel images
  47. // are in the YCbCr color space and 1 channel images are
  48. // in the Y color space.
  49. switch(jcprops.JPGChannels)
  50. {
  51. case 1:
  52. {
  53. jcprops.JPGColor = IJL_G;
  54. jcprops.DIBColor = IJL_RGB;
  55. jcprops.DIBChannels = 3;
  56. break;
  57. }
  58. case 3:
  59. {
  60. jcprops.JPGColor = IJL_YCBCR;
  61. jcprops.DIBColor = IJL_RGB;
  62. jcprops.DIBChannels = 3;
  63. break;
  64. }
  65. default:
  66. {
  67. // This catches everything else, but no
  68. // color twist will be performed by the IJL.
  69. jcprops.JPGColor = IJL_OTHER;
  70. jcprops.DIBColor = IJL_OTHER;
  71. jcprops.DIBChannels = jcprops.JPGChannels;
  72. break;
  73. }
  74. }
  75. // Compute size of desired pixel buffer.
  76. dwWholeImageSize = jcprops.JPGWidth * jcprops.JPGHeight *
  77. jcprops.DIBChannels;
  78. // Allocate memory to hold the decompressed image data.
  79. lpTemp = new BYTE [dwWholeImageSize];
  80. if(NULL == lpTemp)
  81. {
  82. bres = FALSE;
  83. __leave;
  84. }
  85. // Set up the info on the desired DIB properties.
  86. jcprops.DIBWidth = jcprops.JPGWidth;
  87. jcprops.DIBHeight = jcprops.JPGHeight;
  88. jcprops.DIBPadBytes = 0;
  89. jcprops.DIBBytes = lpTemp;
  90. // Now get the actual JPEG image data into the pixel buffer.
  91. jerr = ijlRead(&jcprops, IJL_JBUFF_READWHOLEIMAGE);
  92. if(IJL_OK != jerr)
  93. {
  94. bres = FALSE;
  95. __leave;
  96. }
  97. } // __try
  98. __finally
  99. {
  100. if(FALSE == bres)
  101. {
  102. if(NULL != lpTemp)
  103. {
  104. delete [] lpTemp;
  105. lpTemp = NULL;
  106. }
  107. }
  108. // Clean up the Intel(R) JPEG Library.
  109. ijlFree(&jcprops);
  110. *lpdwWidth = jcprops.DIBWidth;
  111. *lpdwHeight = jcprops.DIBHeight;
  112. *lpdwNumberOfChannels = jcprops.DIBChannels;
  113. *lppRgbBuffer = lpTemp;
  114. } // __finally
  115. return bres;
  116.  } // DecodeFromJPEGBuffer()
  117.  //----------------------------------------------------------
  118.  // An example using the Intel(R) JPEG Library:
  119.  // -- Encode Windows DIB to JPEG buffer.
  120.  //----------------------------------------------------------
  121.  BOOL WINAPI EncodeToJPEGBuffer(
  122.  BYTE* lpRgbBuffer,
  123.  DWORD dwWidth,
  124.  DWORD dwHeight,
  125.  BYTE** lppJpgBuffer,
  126.  DWORD* lpdwJpgBufferSize,
  127.  int iQuality
  128. )
  129. {
  130.  BOOL bres;
  131.  IJLERR jerr;
  132.  DWORD dwRgbBufferSize;
  133.  BYTE* lpTemp;
  134.  // Allocate the IJL JPEG_CORE_PROPERTIES structure.
  135.  JPEG_CORE_PROPERTIES jcprops;
  136.  bres = TRUE;
  137.  __try
  138.  {
  139.  // Initialize the Intel(R) JPEG Library.
  140.  jerr = ijlInit(&jcprops);
  141.  if(IJL_OK != jerr)
  142.  {
  143.  bres = FALSE;
  144.  __leave;
  145.  }
  146.  dwRgbBufferSize = dwWidth * dwHeight * 3;
  147.  lpTemp = new BYTE [dwRgbBufferSize];
  148.  if(NULL == lpTemp)
  149.  {
  150.  bres = FALSE;
  151.  __leave;
  152.  }
  153.  // Set up information to write from the pixel buffer.
  154.  jcprops.DIBWidth = dwWidth;
  155.  jcprops.DIBHeight = dwHeight; // Implies a bottom-up DIB.
  156.  jcprops.DIBBytes = lpRgbBuffer;
  157.  jcprops.DIBPadBytes = 0;
  158.  jcprops.DIBChannels = 3;
  159.  jcprops.DIBColor = IJL_RGB;
  160.  jcprops.JPGWidth = dwWidth;
  161.  jcprops.JPGHeight = dwHeight;
  162.  jcprops.JPGFile = NULL;
  163.  jcprops.JPGBytes = lpTemp;
  164.  jcprops.JPGSizeBytes = dwRgbBufferSize;
  165.  jcprops.JPGChannels = 3;
  166.  jcprops.JPGColor = IJL_YCBCR;
  167.  jcprops.JPGSubsampling = IJL_411; // 4:1:1 subsampling.
  168.  jcprops.jquality = (iQuality>=0)&&(iQuality<=100) ? iQuality : 50; // Select "good" image quality
  169.  // Write the actual JPEG image from the pixel buffer.
  170.  jerr = ijlWrite(&jcprops,IJL_JBUFF_WRITEWHOLEIMAGE);
  171.  if(IJL_OK != jerr)
  172.  {
  173.  bres = FALSE;
  174.  __leave;
  175.  }
  176.  } // __try
  177.  __finally
  178.  {
  179.  if(FALSE == bres)
  180.  {
  181.  if(NULL != lpTemp)
  182.  {
  183.  delete[] lpTemp;
  184.  lpTemp = NULL;
  185.  }
  186.  }
  187.  *lppJpgBuffer = lpTemp;
  188.  *lpdwJpgBufferSize = jcprops.JPGSizeBytes;
  189.  // Clean up the Intel(R) JPEG Library.
  190.  ijlFree(&jcprops);
  191.  }
  192.  return bres;
  193.  } // EncodeToJPEGBuffer()
  194. ////////////////////////////////////////
  195. //
  196. // SOCKET 异步 IO 帮助函数, 异步模型为 "事件选择模型"
  197. //
  198. // 参数:
  199. // SOCKET s:
  200. // 套接字 s 是一个已成功连接的套接字, 并至少使用 FD_READ 标志作为
  201. // 参数 lNetworkEvents 调用了 WSAEventSelect 成功地将套接字置为异步事件选择模型
  202. //
  203. // HANDLE hEvent: 
  204. // 一个用于网络 IO 事件通知的事件句柄. 
  205. //
  206. // char * buf:
  207. // 接收数据缓冲
  208. //
  209. // int len:
  210. // 接收数据缓冲总长度
  211. //
  212. // BOOL * bExit:
  213. // BOOL 变量的指针, 应用程序可以修改这个值. 这个函数调用 WaitForSingleObject 等待 
  214. // dwMilliseconds 毫秒后, 将检测 bExit 的值, 若为 bExit 为 TRUE, 函数将立即返回.
  215. // 返回时是不管等待是否成功的,或说不论等待结果是 WAIT_TIMEOUT 或者 WAIT_OBJECT_0,
  216. // 都会返回, 只要 bExit 为 TRUE
  217. //
  218. //
  219. // DWORD dwMilliseconds:
  220. // 函数将使用这个值作为第二个参数,调用 WaitForSingleObject. 以毫秒为单位
  221. // INFINITE 为无限等待
  222. //
  223. // 返回值:
  224. // 若第一次调用接收函数时, 连接出现问题, 则返回 0 
  225. //
  226. // 若第一次调用接收函数成功后,以后无论发生任何错误都返回一个整型值,
  227. // 描述已接收了多少数据
  228. //
  229. // 如果返回值与参数 len 相等, 说明成功发送出了所有数据, 若不等,可能是网络错误造成, 
  230. // 也可能是 bExit 被设为 TRUE 后接收操作被强制中断
  231. INT
  232. WINAPI RCARecv_EventSelectIO( 
  233. SOCKET s, 
  234. HANDLE hEventArray[2],
  235. char* buf,
  236. const int len
  237. )
  238. {
  239. if( (buf == NULL) || (len==0) )
  240. return FALSE;
  241. int ret;
  242. DWORD dwret;
  243. int count = len;
  244. int index = 0;
  245. WSANETWORKEVENTS ns;
  246. while( count > 0 )
  247. {
  248. ret = recv( s, &(buf[index]), count, 0 );
  249. if( ret == SOCKET_ERROR )
  250. {
  251. // 如果发送错误,并且错误代码不是"被阻塞", 则返回 FALSE ( 发生了网络错误 )
  252. if( WSAGetLastError() != WSAEWOULDBLOCK )
  253. return len - count;
  254. } else if( ret == 0 )
  255. {
  256. return len - count ;
  257. } else 
  258. {
  259. // 如果成功发送, 则更新缓冲偏移字节数和待发总字节数
  260. index += ret;
  261. count -= ret;
  262. continue;
  263. }
  264. dwret = WaitForMultipleObjects( 
  265. 2, hEventArray, FALSE, INFINITE );
  266. switch ( dwret )
  267. {
  268. case WAIT_FAILED:
  269. return len - count;
  270. case WAIT_OBJECT_0:
  271. break;
  272. case WAIT_OBJECT_0 + 1:
  273. return len - count;
  274. case WAIT_TIMEOUT:
  275. break;
  276. }
  277. ret = WSAEnumNetworkEvents( s, hEventArray[0], &ns );
  278. if( ret == SOCKET_ERROR )
  279. {
  280. return len - count;
  281. }
  282. if( ns.lNetworkEvents & FD_READ )
  283. {
  284. if( ns.iErrorCode[ FD_READ_BIT] != 0 )
  285. {
  286. return len - count;
  287. }
  288. else
  289. {
  290. continue; // 回到循环开始处,再次接收数据(此时,绝对可以接收数据)
  291. }
  292. }
  293. if( ns.lNetworkEvents & FD_CLOSE )
  294. {
  295. return len - count;
  296. }
  297. }
  298. return len - count;
  299. }
  300. ////////////////////////////////////////
  301. //
  302. // SOCKET 异步 IO 帮助函数, 异步模型 事件选择模型
  303. //
  304. // 参数:
  305. // SOCKET s:
  306. // 套接字 s 是一个已成功连接的套接字, 并至少使用 FD_WRITE 标志作为
  307. // 参数 lNetworkEvents 调用了 WSAEventSelect 成功地将套接字置为异步事件选择模型
  308. //
  309. // HANDLE hEvent: 
  310. // 一个用于网络 IO 事件通知的事件句柄. 
  311. //
  312. // char * buf:
  313. // 待发数据缓冲
  314. //
  315. // int len:
  316. // 待发数据缓冲总长度
  317. //
  318. // BOOL * bExit:
  319. // BOOL 变量的指针, 应用程序可以修改这个值. 这个函数调用 WaitForSingleObject 等待 
  320. // dwMilliseconds 毫秒后, 将检测 bExit 的值, 若为 bExit 为 TRUE, 函数将立即返回.
  321. // 返回时是不管等待是否成功的,或说不论等待结果是 WAIT_TIMEOUT 或者 WAIT_OBJECT_0,
  322. // 都会返回, 只要 bExit 为 TRUE
  323. //
  324. //
  325. // DWORD dwMilliseconds:
  326. // 函数将使用这个值作为第二个参数,调用 WaitForSingleObject. 以毫秒为单位
  327. // INFINITE 为无限等待
  328. //
  329. // 返回值:
  330. // 若第一次调用发送函数时, 连接出现问题, 则返回 0 
  331. //
  332. // 若第一次调用发送函数成功后,以后无论发生任何错误都返回一个整型值,
  333. // 描述已发送了多少数据
  334. //
  335. // 如果返回值与参数 len 相等, 说明成功发送出了所有数据, 若不等,可能是网络错误造成, 
  336. // 也可能是 bExit 被设为 TRUE 后发送操作被强制中断
  337. INT 
  338. WINAPI RCASend_EventSelectIO( 
  339. SOCKET s, 
  340. HANDLE hEventArray[2],
  341. char* buf,
  342. const int len
  343. )
  344. {
  345. if( (buf == NULL) || (len==0) )
  346. return FALSE;
  347. int ret;
  348. int count = (int)len;
  349. int index =0;
  350. DWORD dwret;
  351. WSANETWORKEVENTS ns;
  352. while( count > 0 )
  353. {
  354. ret = send( s, &(buf[index]), count, 0 );
  355. if( ret == SOCKET_ERROR )
  356. {
  357. // 如果发送错误,并且错误代码不是"被阻塞", 则返回 FALSE ( 发生了网络错误 )
  358. if( WSAGetLastError() != WSAEWOULDBLOCK )
  359. return len - count;
  360. }
  361. else
  362. {
  363. // 如果成功发送, 则更新缓冲偏移字节数和待发总字节数
  364. index += ret;
  365. count -= ret;
  366. continue;
  367. }
  368. // 到这里,说明没而待发缓冲区可供使用, 在 AsyncEvent IO 模型中, 可以等待事件通知的到来
  369. // 现在根据 dwMilliseconds 来待待事件通知
  370. dwret = WaitForMultipleObjects( 
  371. 2,  hEventArray, FALSE, INFINITE );
  372. switch( dwret )
  373. {
  374. case WAIT_FAILED:
  375. case WAIT_OBJECT_0 + 1:
  376. return len - count;
  377. case WAIT_OBJECT_0:
  378. break;
  379. case WAIT_TIMEOUT:
  380. continue;
  381. }
  382. ret = WSAEnumNetworkEvents( s, hEventArray[0], &ns );
  383. if( ns.lNetworkEvents & FD_WRITE )
  384. {
  385. if( ns.iErrorCode[ FD_WRITE_BIT] != 0 )
  386. return (len - count);
  387. else
  388. continue; // 回到前边,再次发送数据(此时,绝对可以发送数据)
  389. }
  390. if( ret == SOCKET_ERROR )
  391. return (len - count);
  392. if( ns.lNetworkEvents & FD_CLOSE )
  393. return (len - count);
  394. }
  395. return len - count;
  396. }
  397. ///////////////////////////////////////////
  398. //
  399. // 获得整个屏幕的象素信息
  400. //
  401. // 参数: 
  402. //
  403. // pbmi[in,out] -- BITMAPINFO 结构指针, 函数成功调用后会填充这个结构,这个结构反映了象素信息
  404. //
  405. // x, y, w, h;  矩形的左上角座标, 以及宽高. 如果这些参数不合法,将被修整为合法参数
  406. //
  407. // pBits[in,out] -- void 指针, 函数调用成功后,pBits 将被象素值填充. 如果 pBits 为NULL,
  408. // 函数将修改 dwBufferSize 参数, 指明需要多少缓冲存放象素值
  409. //
  410. //  dwBufferSize -- [in, out] 指明 pBits 的大小. 如果函数成功调用后, dwBufferSize 将会被修改, 
  411. // 指明实际拷贝的象素字节数
  412. // 返回值:
  413. //  BOOL 类型, 函数调用成功后, 将返回 TRUE; 失败,将返回 FALSE;
  414. // 
  415. HBITMAP 
  416. WINAPI GetDCPixel_BMP (
  417. HDC hdc,
  418. int  x,
  419. int  y,
  420. int  w,
  421. int  h,
  422. int zw,
  423. int zh,
  424. WORD wBitCount,
  425. VOID ** pBits,
  426. BITMAPINFOHEADER * pbmih, // 当色深为 8 时, 包含颜色表
  427. DWORD * pdwBitmapInfoSize
  428. )
  429. {
  430. int width = 0;
  431. int height;
  432. // 确定 DC 是而效的, 并获得 DC 的宽高(以像素为单位)
  433. width = GetDeviceCaps( hdc, HORZRES);
  434. if( width == 0 )
  435. return NULL;
  436. height = GetDeviceCaps( hdc, VERTRES);
  437. // 修整请求的矩形
  438. x = (x<0)||(x>(width-1)) ? 0 : x;
  439. y = (y<0)||(y>(height-1)) ? 0 : y;
  440. w = (w>(width-x)) || (w<1) ?  width - x : w;
  441. h = (h>(height-y)) || (h<1) ?  height - y : h;
  442. zw = zw <= 0 ? w : zw;
  443. zh = zh <= 0 ? h : zh;
  444. // 修整请求的色深
  445. if( wBitCount <= 8 )
  446. wBitCount = 8;
  447. else if( wBitCount <=16 )
  448. wBitCount = 16;
  449. else if( wBitCount <= 24 )
  450. wBitCount = 24;
  451. else if( wBitCount >=32 )
  452. wBitCount = 32;
  453. // 计算存储图象所需空间的大小
  454. //DWORD tmp = (((w * wBitCount) +31) & ~31) / 8 * h;
  455. if( pbmih != NULL )
  456. {
  457. if( wBitCount == 8 )
  458. {
  459. if( *pdwBitmapInfoSize < (sizeof(RGBQUAD)*256 + sizeof(BITMAPINFOHEADER) ))
  460. {
  461. return NULL;
  462. }
  463. else 
  464. {
  465. if( *pdwBitmapInfoSize < sizeof( BITMAPINFOHEADER) )
  466. {
  467. return NULL;
  468. }
  469. }
  470. else
  471. {
  472. *pdwBitmapInfoSize = (sizeof(RGBQUAD)*256 + sizeof(BITMAPINFOHEADER) );
  473. return NULL;
  474. }
  475. HBITMAP bmp;
  476. PVOID pTmp = NULL;
  477. BITMAPINFO bmi;
  478. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  479. bmi.bmiHeader.biWidth = zw;
  480. bmi.bmiHeader.biHeight = zh;
  481. bmi.bmiHeader.biPlanes = 1;
  482. bmi.bmiHeader.biBitCount = wBitCount;
  483. bmi.bmiHeader.biCompression = BI_RGB;
  484. bmi.bmiHeader.biSizeImage = 0;
  485. bmi.bmiHeader.biXPelsPerMeter = 0;
  486. bmi.bmiHeader.biYPelsPerMeter = 0;
  487. bmi.bmiHeader.biClrUsed = 0;
  488. bmi.bmiHeader.biClrImportant = 0;
  489. // create a DIB section bitmap;
  490. if( wBitCount == 8 )
  491. bmp = CreateDIBSection( hdc, &bmi, DIB_PAL_COLORS, &pTmp, NULL, 0 );
  492. else
  493. bmp = CreateDIBSection( hdc, &bmi, DIB_RGB_COLORS, &pTmp, NULL, 0 );
  494. if( bmp == NULL )
  495. {
  496. return NULL;
  497. }
  498. // set the out param pBits to image buffer pTmp;
  499. *pBits = pTmp;
  500. HDC hdcMem = CreateCompatibleDC( hdc );
  501. if( hdcMem == NULL)
  502. {
  503. DeleteObject(bmp);
  504. return NULL;
  505. }
  506. SelectObject( hdcMem, bmp );
  507. StretchBlt( hdcMem, 0, 0, zw, zh, hdc, x, y, w, h, SRCCOPY );
  508. //BitBlt( hdc, 0, 0,w, h, hdcMem, 0, 0, SRCCOPY );
  509. DIBSECTION ds;
  510. GetObject( bmp, sizeof(ds), (PVOID)&ds );
  511. if( ds.dsBm.bmBitsPixel == 8 )
  512. {
  513. int clrGetNum;
  514. SelectObject( hdcMem, bmp );
  515. clrGetNum = GetDIBColorTable( hdcMem, 0, ds.dsBmih.biClrUsed, 
  516. (RGBQUAD*)(sizeof(BITMAPINFOHEADER) +(char*)pbmih ) ); 
  517. if(  0 == clrGetNum )
  518. {
  519. DeleteDC( hdcMem );
  520. DeleteObject( bmp );
  521. return NULL;
  522. }
  523. }
  524. CopyMemory( (void*)pbmih, &(ds.dsBmih), sizeof(BITMAPINFOHEADER) );
  525. DeleteDC( hdcMem );
  526. return bmp;
  527. }
  528. VOID
  529. WINAPI InitResponseHead(
  530. PRCARESPONSEHEADER prresh,
  531. DWORD dwStatusCode,
  532. DWORD dwSize
  533. )
  534. {
  535. lstrcpy( prresh->rcaID, "RCA" );
  536. prresh->dwStatusCode = dwStatusCode;
  537. prresh->dwTotalBytes = dwSize;
  538. }