⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcaclientlibrary.cpp

📁 远程控制软件源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

#include "stdafx.h"


BOOL 
WINAPI 
DecodeFromJPEGBuffer(
 	BYTE *	lpJpgBuffer,
 	DWORD 	dwJpgBufferSize,
 	BYTE**	lppRgbBuffer,
 	DWORD*	lpdwWidth,
 	DWORD*	lpdwHeight,
 	DWORD*	lpdwNumberOfChannels
 	)
 {
 	
	BOOL 	bres;
	IJLERR 	jerr;
	DWORD 	dwWholeImageSize;
	BYTE* 	lpTemp = NULL;

	// Allocate the IJL JPEG_CORE_PROPERTIES structure.
	JPEG_CORE_PROPERTIES jcprops;

	bres = TRUE;

	__try
	{
	// Initialize the Intel(R) JPEG Library.
		jerr = ijlInit(&jcprops);
		if(IJL_OK != jerr)
		{
			bres = FALSE;
			__leave;
		} 	
 		
		// Get information on the JPEG image
		// (i.e., width, height, and channels).

		jcprops.JPGFile = NULL;
		jcprops.JPGBytes = lpJpgBuffer;
		jcprops.JPGSizeBytes = dwJpgBufferSize;
		jerr = ijlRead(&jcprops, IJL_JBUFF_READPARAMS);
		if(IJL_OK != jerr)
		{
			bres = FALSE;
			__leave;
		}
		// Set the JPG color space ... this will always be
		// somewhat of an educated guess at best because JPEG
		// is "color blind" (i.e., nothing in the bit stream
		// tells you what color space the data was encoded from).
		// However, in this example we assume that we are
		// reading JFIF files which means that 3 channel images
		// are in the YCbCr color space and 1 channel images are
		// in the Y color space.
		switch(jcprops.JPGChannels)
		{
		case 1:
			{
				jcprops.JPGColor = IJL_G;
				jcprops.DIBColor = IJL_RGB;
				jcprops.DIBChannels = 3;
				break;
			}
		case 3:
			{
				jcprops.JPGColor = IJL_YCBCR;
				jcprops.DIBColor = IJL_RGB;
				jcprops.DIBChannels = 3;
				break;
			}
		default:
			{
				// This catches everything else, but no
				// color twist will be performed by the IJL.

				jcprops.JPGColor = IJL_OTHER;
				jcprops.DIBColor = IJL_OTHER;
				jcprops.DIBChannels = jcprops.JPGChannels;
				break;
			}
		}
		// Compute size of desired pixel buffer.
		dwWholeImageSize = jcprops.JPGWidth * jcprops.JPGHeight *
			jcprops.DIBChannels;
		// Allocate memory to hold the decompressed image data.
		lpTemp = new BYTE [dwWholeImageSize];
		if(NULL == lpTemp)
		{
			bres = FALSE;
			__leave;
		}
		// Set up the info on the desired DIB properties.
		jcprops.DIBWidth = jcprops.JPGWidth;
		jcprops.DIBHeight = jcprops.JPGHeight;
		jcprops.DIBPadBytes = 0;
		jcprops.DIBBytes = lpTemp;
		// Now get the actual JPEG image data into the pixel buffer.
		jerr = ijlRead(&jcprops, IJL_JBUFF_READWHOLEIMAGE);
		if(IJL_OK != jerr)
		{
			bres = FALSE;
			__leave;
		}
	} // __try
	__finally
	{
		if(FALSE == bres)
		{
			if(NULL != lpTemp)
			{
				delete [] lpTemp;
				lpTemp = NULL;
			}
		}

		// Clean up the Intel(R) JPEG Library.
		ijlFree(&jcprops);
		*lpdwWidth = jcprops.DIBWidth;
		*lpdwHeight = jcprops.DIBHeight;
		*lpdwNumberOfChannels = jcprops.DIBChannels;
		*lppRgbBuffer = lpTemp;

	} // __finally


	return bres;
 } // DecodeFromJPEGBuffer()


 //----------------------------------------------------------
 // An example using the Intel(R) JPEG Library:
 // -- Encode Windows DIB to JPEG buffer.
 //----------------------------------------------------------
 BOOL WINAPI EncodeToJPEGBuffer(
	 BYTE* lpRgbBuffer,
	 DWORD dwWidth,
	 DWORD dwHeight,
	 BYTE** lppJpgBuffer,
	 DWORD* lpdwJpgBufferSize,
	 int	iQuality
)
{
	 BOOL bres;
	 IJLERR jerr;
	 DWORD dwRgbBufferSize;
	 BYTE* lpTemp;

	 // Allocate the IJL JPEG_CORE_PROPERTIES structure.
	 JPEG_CORE_PROPERTIES jcprops;
	 bres = TRUE;
	 __try
	 {
		 // Initialize the Intel(R) JPEG Library.

		 jerr = ijlInit(&jcprops);
		 if(IJL_OK != jerr)
		 {
			 bres = FALSE;
			 __leave;
		 }
		 dwRgbBufferSize = dwWidth * dwHeight * 3;
		 lpTemp = new BYTE [dwRgbBufferSize];
		 if(NULL == lpTemp)
		 {
			 bres = FALSE;
			 __leave;
		 }
		 // Set up information to write from the pixel buffer.
		 jcprops.DIBWidth = dwWidth;
		 jcprops.DIBHeight = dwHeight; // Implies a bottom-up DIB.
		 jcprops.DIBBytes = lpRgbBuffer;
		 jcprops.DIBPadBytes = 0;
		 jcprops.DIBChannels = 3;
		 jcprops.DIBColor = IJL_RGB;
		 jcprops.JPGWidth = dwWidth;
		 jcprops.JPGHeight = dwHeight;
		 jcprops.JPGFile = NULL;
		 jcprops.JPGBytes = lpTemp;
		 jcprops.JPGSizeBytes = dwRgbBufferSize;
		 jcprops.JPGChannels = 3;
		 jcprops.JPGColor = IJL_YCBCR;
		 jcprops.JPGSubsampling = IJL_411; // 4:1:1 subsampling.
		 jcprops.jquality = (iQuality>=0)&&(iQuality<=100) ? iQuality : 50; // Select "good" image quality
		 // Write the actual JPEG image from the pixel buffer.
		 jerr = ijlWrite(&jcprops,IJL_JBUFF_WRITEWHOLEIMAGE);
		 if(IJL_OK != jerr)
		 {
			 bres = FALSE;
			 __leave;
		 }
	 } // __try
	 __finally
	 {
		 if(FALSE == bres)
		 {
			 if(NULL != lpTemp)
			 {
				 delete[] lpTemp;
				 lpTemp = NULL;
			 }
		 }
		 *lppJpgBuffer = lpTemp;
		 *lpdwJpgBufferSize = jcprops.JPGSizeBytes;
		 // Clean up the Intel(R) JPEG Library.
		 ijlFree(&jcprops);
	 }
	 return bres;
 } // EncodeToJPEGBuffer()


////////////////////////////////////////
//
//	SOCKET 异步 IO 帮助函数, 异步模型为 "事件选择模型"
//	
//	参数:
//	SOCKET s:	
//		套接字 s 是一个已成功连接的套接字, 并至少使用 FD_READ 标志作为
//		参数 lNetworkEvents 调用了 WSAEventSelect 成功地将套接字置为异步事件选择模型
//				
//	HANDLE hEvent: 
//		一个用于网络 IO 事件通知的事件句柄. 
//	
//	char * buf:
//		接收数据缓冲
//
//	int	len:
//		接收数据缓冲总长度
//
//	BOOL * bExit:
//		BOOL 变量的指针, 应用程序可以修改这个值. 这个函数调用 WaitForSingleObject 等待 
//		dwMilliseconds 毫秒后, 将检测 bExit 的值, 若为 bExit 为 TRUE, 函数将立即返回.
//		返回时是不管等待是否成功的,或说不论等待结果是 WAIT_TIMEOUT 或者 WAIT_OBJECT_0,
//		都会返回, 只要 bExit 为 TRUE
//	
//
//	DWORD dwMilliseconds:
//		函数将使用这个值作为第二个参数,调用 WaitForSingleObject. 以毫秒为单位
//		INFINITE 为无限等待
//
//	返回值:
//		若第一次调用接收函数时, 连接出现问题, 则返回 0 
//
//		若第一次调用接收函数成功后,以后无论发生任何错误都返回一个整型值,
//		描述已接收了多少数据
//
//		如果返回值与参数 len 相等, 说明成功发送出了所有数据, 若不等,可能是网络错误造成, 
//		也可能是 bExit 被设为 TRUE 后接收操作被强制中断

INT
WINAPI RCARecv_EventSelectIO( 
		SOCKET	s, 
		HANDLE	hEventArray[2],
		char*	buf,
const	int		len
)
{
	if( (buf == NULL) || (len==0) )
		return FALSE;
	
	int					ret;
	DWORD				dwret;
	int					count	= len;
	int					index	= 0;
	WSANETWORKEVENTS	ns;

	while( count > 0 )
	{
		ret = recv( s, &(buf[index]), count, 0 );

		if( ret == SOCKET_ERROR )
		{
			// 如果发送错误,并且错误代码不是"被阻塞", 则返回 FALSE ( 发生了网络错误 )
			if( WSAGetLastError() != WSAEWOULDBLOCK )
				return len - count;

		} else if( ret == 0 )
		{
			return len - count ;

		} else 
		{
			// 如果成功发送, 则更新缓冲偏移字节数和待发总字节数
			index += ret;
			count -= ret;
			continue;
		}

		dwret = WaitForMultipleObjects( 
			2, hEventArray, FALSE, INFINITE );

		switch ( dwret )
		{
		case WAIT_FAILED:
			return len - count;
		
		case WAIT_OBJECT_0:
			break;

		case WAIT_OBJECT_0 + 1:
			return len - count;

		case WAIT_TIMEOUT:
			break;
		}

		ret = WSAEnumNetworkEvents( s, hEventArray[0], &ns );

		if( ret == SOCKET_ERROR )
		{
			return len - count;
		}
		
		if( ns.lNetworkEvents & FD_READ )
		{
			if( ns.iErrorCode[ FD_READ_BIT] != 0 )
			{
				return len - count;
			}
			else
			{
				continue; // 回到循环开始处,再次接收数据(此时,绝对可以接收数据)
			}
		}

		if( ns.lNetworkEvents & FD_CLOSE )
		{
			return len - count;
		}
	}
	
	return len - count;
}




////////////////////////////////////////
//
//	SOCKET 异步 IO 帮助函数, 异步模型 事件选择模型
//	
//	参数:
//	SOCKET s:	
//		套接字 s 是一个已成功连接的套接字, 并至少使用 FD_WRITE 标志作为
//		参数 lNetworkEvents 调用了 WSAEventSelect 成功地将套接字置为异步事件选择模型
//				
//	HANDLE hEvent: 
//		一个用于网络 IO 事件通知的事件句柄. 
//	
//	char * buf:
//		待发数据缓冲
//
//	int	len:
//		待发数据缓冲总长度
//
//	BOOL * bExit:
//		BOOL 变量的指针, 应用程序可以修改这个值. 这个函数调用 WaitForSingleObject 等待 
//		dwMilliseconds 毫秒后, 将检测 bExit 的值, 若为 bExit 为 TRUE, 函数将立即返回.
//		返回时是不管等待是否成功的,或说不论等待结果是 WAIT_TIMEOUT 或者 WAIT_OBJECT_0,
//		都会返回, 只要 bExit 为 TRUE
//	
//
//	DWORD dwMilliseconds:
//		函数将使用这个值作为第二个参数,调用 WaitForSingleObject. 以毫秒为单位
//		INFINITE 为无限等待
//
//	返回值:
//		若第一次调用发送函数时, 连接出现问题, 则返回 0 
//
//		若第一次调用发送函数成功后,以后无论发生任何错误都返回一个整型值,
//		描述已发送了多少数据
//
//		如果返回值与参数 len 相等, 说明成功发送出了所有数据, 若不等,可能是网络错误造成, 
//		也可能是 bExit 被设为 TRUE 后发送操作被强制中断
INT 
WINAPI RCASend_EventSelectIO( 
		SOCKET	s, 
		HANDLE	hEventArray[2],
		char*	buf,
const	int		len
)
{
	if( (buf == NULL) || (len==0) )
		return FALSE;
	
	int					ret;
	int					count	= (int)len;
	int					index	=0;
	DWORD				dwret;
	WSANETWORKEVENTS	ns;

	while( count > 0 )
	{
		
		ret = send( s, &(buf[index]), count, 0 );
			
		if( ret == SOCKET_ERROR )
		{
			// 如果发送错误,并且错误代码不是"被阻塞", 则返回 FALSE ( 发生了网络错误 )
			if( WSAGetLastError() != WSAEWOULDBLOCK )
				return len - count;
		}
		else
		{
			// 如果成功发送, 则更新缓冲偏移字节数和待发总字节数
			cout << ret << endl;

			index += ret;
			count -= ret;
			continue;
		}

		// 到这里,说明没而待发缓冲区可供使用, 在 AsyncEvent IO 模型中, 可以等待事件通知的到来
		// 现在根据 dwMilliseconds 来待待事件通知
		dwret = WaitForMultipleObjects( 
			2,  hEventArray, FALSE, INFINITE );
		switch( dwret )
		{
		case WAIT_FAILED:
		case WAIT_OBJECT_0 + 1:
			return len - count;

		case WAIT_OBJECT_0:
			break;

		case WAIT_TIMEOUT:
			continue;
		}

		ret = WSAEnumNetworkEvents( s, hEventArray[0], &ns );

		if( ns.lNetworkEvents & FD_WRITE )
		{
			if( ns.iErrorCode[ FD_WRITE_BIT] != 0 )
				return (len - count);
			else
				continue; // 回到前边,再次发送数据(此时,绝对可以发送数据)
		}

		if( ret == SOCKET_ERROR )
			return (len - count);
		
		if( ns.lNetworkEvents & FD_CLOSE )
			return (len - count);
	}

	return len - count;
}





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -