📄 rcahelper.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
{
// 如果成功发送, 则更新缓冲偏移字节数和待发总字节数
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;
}
///////////////////////////////////////////
//
// 获得整个屏幕的象素信息
//
// 参数:
//
// pbmi[in,out] -- BITMAPINFO 结构指针, 函数成功调用后会填充这个结构,这个结构反映了象素信息
//
// x, y, w, h; 矩形的左上角座标, 以及宽高. 如果这些参数不合法,将被修整为合法参数
//
// pBits[in,out] -- void 指针, 函数调用成功后,pBits 将被象素值填充. 如果 pBits 为NULL,
// 函数将修改 dwBufferSize 参数, 指明需要多少缓冲存放象素值
//
// dwBufferSize -- [in, out] 指明 pBits 的大小. 如果函数成功调用后, dwBufferSize 将会被修改,
// 指明实际拷贝的象素字节数
// 返回值:
// BOOL 类型, 函数调用成功后, 将返回 TRUE; 失败,将返回 FALSE;
//
HBITMAP
WINAPI GetDCPixel_BMP (
HDC hdc,
int x,
int y,
int w,
int h,
int zw,
int zh,
WORD wBitCount,
VOID ** pBits,
BITMAPINFOHEADER * pbmih, // 当色深为 8 时, 包含颜色表
DWORD * pdwBitmapInfoSize
)
{
int width = 0;
int height;
// 确定 DC 是而效的, 并获得 DC 的宽高(以像素为单位)
width = GetDeviceCaps( hdc, HORZRES);
if( width == 0 )
return NULL;
height = GetDeviceCaps( hdc, VERTRES);
// 修整请求的矩形
x = (x<0)||(x>(width-1)) ? 0 : x;
y = (y<0)||(y>(height-1)) ? 0 : y;
w = (w>(width-x)) || (w<1) ? width - x : w;
h = (h>(height-y)) || (h<1) ? height - y : h;
zw = zw <= 0 ? w : zw;
zh = zh <= 0 ? h : zh;
// 修整请求的色深
if( wBitCount <= 8 )
wBitCount = 8;
else if( wBitCount <=16 )
wBitCount = 16;
else if( wBitCount <= 24 )
wBitCount = 24;
else if( wBitCount >=32 )
wBitCount = 32;
// 计算存储图象所需空间的大小
//DWORD tmp = (((w * wBitCount) +31) & ~31) / 8 * h;
if( pbmih != NULL )
{
if( wBitCount == 8 )
{
if( *pdwBitmapInfoSize < (sizeof(RGBQUAD)*256 + sizeof(BITMAPINFOHEADER) ))
{
return NULL;
}
}
else
{
if( *pdwBitmapInfoSize < sizeof( BITMAPINFOHEADER) )
{
return NULL;
}
}
}
else
{
*pdwBitmapInfoSize = (sizeof(RGBQUAD)*256 + sizeof(BITMAPINFOHEADER) );
return NULL;
}
HBITMAP bmp;
PVOID pTmp = NULL;
BITMAPINFO bmi;
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = zw;
bmi.bmiHeader.biHeight = zh;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = wBitCount;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
// create a DIB section bitmap;
if( wBitCount == 8 )
bmp = CreateDIBSection( hdc, &bmi, DIB_PAL_COLORS, &pTmp, NULL, 0 );
else
bmp = CreateDIBSection( hdc, &bmi, DIB_RGB_COLORS, &pTmp, NULL, 0 );
if( bmp == NULL )
{
return NULL;
}
// set the out param pBits to image buffer pTmp;
*pBits = pTmp;
HDC hdcMem = CreateCompatibleDC( hdc );
if( hdcMem == NULL)
{
DeleteObject(bmp);
return NULL;
}
SelectObject( hdcMem, bmp );
StretchBlt( hdcMem, 0, 0, zw, zh, hdc, x, y, w, h, SRCCOPY );
//BitBlt( hdc, 0, 0,w, h, hdcMem, 0, 0, SRCCOPY );
DIBSECTION ds;
GetObject( bmp, sizeof(ds), (PVOID)&ds );
if( ds.dsBm.bmBitsPixel == 8 )
{
int clrGetNum;
SelectObject( hdcMem, bmp );
clrGetNum = GetDIBColorTable( hdcMem, 0, ds.dsBmih.biClrUsed,
(RGBQUAD*)(sizeof(BITMAPINFOHEADER) +(char*)pbmih ) );
if( 0 == clrGetNum )
{
DeleteDC( hdcMem );
DeleteObject( bmp );
return NULL;
}
}
CopyMemory( (void*)pbmih, &(ds.dsBmih), sizeof(BITMAPINFOHEADER) );
DeleteDC( hdcMem );
return bmp;
}
VOID
WINAPI InitResponseHead(
PRCARESPONSEHEADER prresh,
DWORD dwStatusCode,
DWORD dwSize
)
{
lstrcpy( prresh->rcaID, "RCA" );
prresh->dwStatusCode = dwStatusCode;
prresh->dwTotalBytes = dwSize;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -