?? rcaclientlibrary.cpp
字號:
#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 + -