📄 screenchattingserverdlg.cpp
字号:
cinfo.in_color_space = JCS_RGB; //Colorspace of input image
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo,
nQuality, //Quality: 0-100 scale
TRUE); //Limit to baseline-JPEG values
jpeg_start_compress(&cinfo, TRUE);
//JSAMPLEs per row in output buffer
nSampsPerRow = cinfo.image_width * cinfo.input_components;
//Allocate array of pixel RGB values
jsmpArray = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo,
JPOOL_IMAGE,
nSampsPerRow,
cinfo.image_height);
if (DibToSamps(hDib,
nSampsPerRow,
cinfo,
jsmpArray,
pcsMsg))
{
//Write the array of scan lines to the JPEG file
(void)jpeg_write_scanlines(&cinfo,
jsmpArray,
cinfo.image_height);
}
jpeg_finish_compress(&cinfo); //Always finish
jpeg_destroy_compress(&cinfo); //Free resources
if (*pcsMsg != "")
return FALSE;
else
return TRUE;
}
////////////////////////////////////////////////////////////////
//This function fills a jsmpArray with the RGB values
//for the CBitmap.
//
//It has been improved to handle all legal bitmap formats.
//
//A jsmpArray is a big array of RGB values, 3 bytes per value.
//
//Note that rows of pixels are processed bottom to top:
//The data in the jsamp array must be arranged top to bottom.
////////////////////////////////////////////////////////////////
BOOL DibToSamps(HANDLE hDib,
int nSampsPerRow,
struct jpeg_compress_struct cinfo,
JSAMPARRAY jsmpPixels,
CString* pcsMsg)
{
//Sanity...
if (hDib == NULL ||
nSampsPerRow <= 0 || pcsMsg == NULL)
{
if (pcsMsg !=NULL)
*pcsMsg="Invalid input data";
return FALSE;
}
int r=0, p=0, q=0, b=0, n=0,
nUnused=0, nBytesWide=0, nUsed=0, nLastBits=0, nLastNibs=0, nCTEntries=0,
nRow=0, nByte=0, nPixel=0;
BYTE bytCTEnt=0;
LPBITMAPINFOHEADER pbBmHdr= (LPBITMAPINFOHEADER)hDib; //The bit count tells you the format of the bitmap: //Decide how many entries will be in the color table (if any)
switch (pbBmHdr->biBitCount)
{
case 1:
nCTEntries = 2; //Monochrome
break;
case 4:
nCTEntries = 16; //16-color
break;
case 8:
nCTEntries = 256; //256-color
break;
case 16:
case 24:
case 32:
nCTEntries = 0; //No color table needed
break;
default:
*pcsMsg = "Invalid bitmap bit count";
return FALSE; //Unsupported format
}
//Point to the color table and pixels
DWORD dwCTab = (DWORD)pbBmHdr + pbBmHdr->biSize;
LPRGBQUAD pCTab = (LPRGBQUAD)(dwCTab);
LPSTR lpBits = (LPSTR)pbBmHdr +
(WORD)pbBmHdr->biSize +
(WORD)(nCTEntries * sizeof(RGBQUAD));
//Different formats for the image bits
LPBYTE lpPixels = (LPBYTE) lpBits;
RGBQUAD* pRgbQs = (RGBQUAD*)lpBits;
WORD* wPixels = (WORD*) lpBits;
//Set up the jsamps according to the bitmap's format.
//Note that rows are processed bottom to top, because
//that's how bitmaps are created.
switch (pbBmHdr->biBitCount)
{
case 1:
nUsed = (pbBmHdr->biWidth + 7) / 8;
nUnused = (((nUsed + 3) / 4) * 4) - nUsed;
nBytesWide = nUsed + nUnused;
nLastBits = 8 - ((nUsed * 8) - pbBmHdr->biWidth);
for (r=0; r < pbBmHdr->biHeight; r++)
{
for (p=0,q=0; p < nUsed; p++)
{
nRow=(pbBmHdr->biHeight-r-1) * nBytesWide;
nByte = nRow + p;
int nBUsed = (p <(nUsed-1)) ? 8 : nLastBits;
for(b=0;b<nBUsed;b++)
{
bytCTEnt = lpPixels[nByte] << b;
bytCTEnt = bytCTEnt >> 7;
jsmpPixels[r][q+0] = pCTab[bytCTEnt].rgbRed;
jsmpPixels[r][q+1] = pCTab[bytCTEnt].rgbGreen;
jsmpPixels[r][q+2] = pCTab[bytCTEnt].rgbBlue;
q += 3;
}
}
}
break;
case 4:
nUsed = (pbBmHdr->biWidth + 1) / 2;
nUnused = (((nUsed + 3) / 4) * 4) - nUsed;
nBytesWide = nUsed + nUnused;
nLastNibs = 2 - ((nUsed * 2) - pbBmHdr->biWidth);
for (r=0; r < pbBmHdr->biHeight;r++)
{
for (p=0,q=0; p < nUsed;p++)
{
nRow=(pbBmHdr->biHeight-r-1) * nBytesWide;
nByte = nRow + p;
int nNibbles = (p < nUsed - 1) ?
2 : nLastNibs;
for(n=0;n < nNibbles;n++)
{
bytCTEnt = lpPixels[nByte] << (n*4);
bytCTEnt = bytCTEnt >> (4-(n*4));
jsmpPixels[r][q+0] = pCTab[bytCTEnt].rgbRed;
jsmpPixels[r][q+1] = pCTab[bytCTEnt].rgbGreen;
jsmpPixels[r][q+2] = pCTab[bytCTEnt].rgbBlue;
q += 3;
}
// }
}
}
break;
default:
case 8: //Each byte is a pointer to a pixel color
nUnused = (((pbBmHdr->biWidth + 3) / 4) * 4) -
pbBmHdr->biWidth;
for (r=0;r < pbBmHdr->biHeight; r++)
{
for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3)
{
nRow = (pbBmHdr->biHeight-r-1) * (pbBmHdr->biWidth + nUnused);
nPixel = nRow + p;
jsmpPixels[r][q+0] = pCTab[lpPixels[nPixel]].rgbRed;
jsmpPixels[r][q+1] = pCTab[lpPixels[nPixel]].rgbGreen;
jsmpPixels[r][q+2] = pCTab[lpPixels[nPixel]].rgbBlue;
}
}
break;
case 16: //Hi-color (16 bits per pixel)
for (r=0;r < pbBmHdr->biHeight; r++)
{
for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3)
{
nRow = (pbBmHdr->biHeight-r-1) * pbBmHdr->biWidth;
nPixel = nRow + p;
RGBQUAD quad = QuadFromWord(wPixels[nPixel]);
jsmpPixels[r][q+0] = quad.rgbRed;
jsmpPixels[r][q+1] = quad.rgbGreen;
jsmpPixels[r][q+2] = quad.rgbBlue;
}
}
break;
case 24:
nBytesWide = (pbBmHdr->biWidth*3);
nUnused = (((nBytesWide + 3) / 4) * 4) -
nBytesWide;
nBytesWide += nUnused;
for (r=0;r<pbBmHdr->biHeight;r++)
{
for (p=0,q=0;p < (nBytesWide-nUnused); p+=3,q+=3)
{
nRow = (pbBmHdr->biHeight-r-1) * nBytesWide;
nPixel = nRow + p;
jsmpPixels[r][q+0] = lpPixels[nPixel+2]; //Red
jsmpPixels[r][q+1] = lpPixels[nPixel+1]; //Green
jsmpPixels[r][q+2] = lpPixels[nPixel+0]; //Blue
}
}
break;
case 32:
for (r=0; r < pbBmHdr->biHeight; r++)
{
for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3)
{
nRow = (pbBmHdr->biHeight-r-1) *
pbBmHdr->biWidth;
nPixel = nRow + p;
jsmpPixels[r][q+0] = pRgbQs[nPixel].rgbRed;
jsmpPixels[r][q+1] = pRgbQs[nPixel].rgbGreen;
jsmpPixels[r][q+2] = pRgbQs[nPixel].rgbBlue;
}
}
break;
} //end switch
return TRUE;
}
////////////////////////////////////////
//This function turns a 16-bit pixel
//into an RGBQUAD value.
////////////////////////////////////////
RGBQUAD QuadFromWord(WORD b16)
{
BYTE bytVals[] =
{
0, 16, 24, 32, 40, 48, 56, 64,
72, 80, 88, 96, 104,112,120,128,
136,144,152,160,168,176,184,192,
200,208,216,224,232,240,248,255
};
WORD wR = b16;
WORD wG = b16;
WORD wB = b16;
wR <<= 1; wR >>= 11;
wG <<= 6; wG >>= 11;
wB <<= 11; wB >>= 11;
RGBQUAD rgb;
rgb.rgbReserved = 0;
rgb.rgbBlue = bytVals[wB];
rgb.rgbGreen = bytVals[wG];
rgb.rgbRed = bytVals[wR];
return rgb;
}
/*
* Initialize destination
* before any data is actually written.
*/
METHODDEF(void)
jpeg_mem_dest_init (j_compress_ptr cinfo)
{
/* Set up data pointer */
// datasink_dest_mgr * dest = (datasink_dest_mgr * ) cinfo->dest;
data_dest_mgr * dest = (data_dest_mgr * ) cinfo->dest;
/* Allocate the output buffer --- it will be released when done with image */
dest->buffer = (JOCTET *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
JPEG_WORK_BUFFER_SIZE * SIZEOF(JOCTET));
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = JPEG_WORK_BUFFER_SIZE;
}
/*
* Flush the output buffer --- called whenever buffer is full.
*
* If this procedure gets called, we have a buffer overrun condition -
* We now send the data to the DataSink
*/
METHODDEF(boolean)
jpeg_mem_dest_empty_output_buffer (j_compress_ptr cinfo)
{
data_dest_mgr * dest = (data_dest_mgr *) cinfo->dest;
memcpy(g_pScreenChattingServerDlg->m_pBuffer+g_pScreenChattingServerDlg->m_nCurPos,dest->buffer,JPEG_WORK_BUFFER_SIZE);
g_pScreenChattingServerDlg->m_nCurPos+=JPEG_WORK_BUFFER_SIZE;
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = JPEG_WORK_BUFFER_SIZE;
return TRUE;
}
/*
* Terminate source --- called by jpeg_finish_compress
* after all data has been written.
*
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
* application must deal with any cleanup that should happen even
* for error exit.
*/
METHODDEF(void)
jpeg_mem_dest_term (j_compress_ptr cinfo)
{
data_dest_mgr * dest = (data_dest_mgr *) cinfo->dest;
size_t datacount = JPEG_WORK_BUFFER_SIZE - dest->pub.free_in_buffer;
/* Write any data remaining in the buffer */
if (datacount>0)
{
memcpy(g_pScreenChattingServerDlg->m_pBuffer+g_pScreenChattingServerDlg->m_nCurPos,dest->buffer,datacount);
g_pScreenChattingServerDlg->m_nCurPos+=datacount;
}
}
/*
* Prepare for ouput. This routine tells the jpeg library where to find
* the output buffer & sets up the function pointers the library needs.
*
*/
GLOBAL(void)
jpeg_mem_dest(j_compress_ptr cinfo,JOCTET * pData,int FileSize)
{
// datasink_dest_mgr * dest;
data_dest_mgr * dest;
if (cinfo->dest == NULL)
{ /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
sizeof(data_dest_mgr));
}
dest = (data_dest_mgr *) cinfo->dest;
dest->pub.init_destination = jpeg_mem_dest_init;
dest->pub.empty_output_buffer = jpeg_mem_dest_empty_output_buffer;
dest->pub.term_destination = jpeg_mem_dest_term;
}
void CScreenChattingServerDlg::OnTcp()
{
// TODO: Add your control notification handler code here
if (m_curMethod==UDP)
{
m_curMethod=TCP;
((CButton *)GetDlgItem(IDR_TCP))->SetCheck(1);
}
}
void CScreenChattingServerDlg::OnUdp()
{
// TODO: Add your control notification handler code here
if (m_curMethod==TCP)
{
m_curMethod=UDP;
((CButton *)GetDlgItem(IDR_UDP))->SetCheck(1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -