Beispiel #1
0
bool CJpegEncoder::Encode(const BYTE* dib)
{
	m_bbuff = m_bwidth = 0;

	BITMAPINFO* bi = (BITMAPINFO*)dib;

	int bpp = bi->bmiHeader.biBitCount;

	if(bpp != 16 && bpp != 24 && bpp != 32) // 16 & 24 not tested!!! there may be some alignment problems when the row size is not 4*something in bytes
		return false;

	m_w = bi->bmiHeader.biWidth;
	m_h = abs(bi->bmiHeader.biHeight);
	m_p = new BYTE[m_w*m_h*4];

	const BYTE* src = dib + sizeof(bi->bmiHeader);
	if(bi->bmiHeader.biBitCount <= 8)
	{
		if(bi->bmiHeader.biClrUsed) src += bi->bmiHeader.biClrUsed * sizeof(bi->bmiColors[0]);
		else src += (1 << bi->bmiHeader.biBitCount) * sizeof(bi->bmiColors[0]);
	}

	int srcpitch = m_w*(bpp>>3);
	int dstpitch = m_w*4;

	BitBltFromRGBToRGB(
		m_w, m_h, 
		m_p, dstpitch, 32, 
		(BYTE*)src + srcpitch*(m_h-1), -srcpitch, bpp);

	BYTE* p = m_p;
	for(BYTE* e = p + m_h*dstpitch; p < e; p += 4)
	{
		int r = p[2], g = p[1], b = p[0];

		p[0] = (BYTE)min(max(0.2990*r+0.5870*g+0.1140*b, 0), 255) - 128;
		p[1] = (BYTE)min(max(-0.1687*r-0.3313*g+0.5000*b + 128, 0), 255) - 128;
		p[2] = (BYTE)min(max(0.5000*r-0.4187*g-0.0813*b + 128, 0), 255) - 128;
	}

	if(quanttbl[0][0] == 16)
	{
		for(int i = 0; i < countof(quanttbl); i++)
			for(int j = 0; j < countof(quanttbl[0]); j++)
				quanttbl[i][j] >>= 2; // the default quantization table contains a little too large values
	}

	WriteSOI();
	WriteDQT();
	WriteSOF0();
	WriteDHT();
	WriteSOS();
	WriteEOI();

	delete [] m_p;

	return true;
}
Beispiel #2
0
/////////////////////////////////////////////////////////////////////////////
// Convert YUV411 to JPEG photo file
static int YUV2Jpg(PBYTE in_Y,PBYTE in_U,PBYTE in_V,int width,int height,int quality,int nStride,PBYTE pOut,DWORD *pnOutSize)
{
	PBYTE pYBuf,pUBuf,pVBuf;
	int nYLen = nStride  * height;
	int nUVLen = nStride  * height / 4;
	int	nDataLen;
	JPEGINFO JpgInfo;
	memset(&JpgInfo, 0, sizeof(JPEGINFO));
	JpgInfo.bytenew = 0;
	JpgInfo.bytepos = 7;
	pYBuf = (PBYTE)malloc(nYLen);
	memcpy(pYBuf,in_Y,nYLen);
	pUBuf = (PBYTE)malloc(nYLen);
	pVBuf = (PBYTE)malloc(nYLen);
	
	ProcessUV(pUBuf,in_U,width,height,nStride);
	ProcessUV(pVBuf,in_V,width,height,nStride);
	//	GetDataFromSource(pYBuf,pUBuf,pVBuf,in_Y,in_U,in_V,width);
	DivBuff(pYBuf,width,height,nStride,DCTSIZE,DCTSIZE);
	DivBuff(pUBuf,width,height,nStride,DCTSIZE,DCTSIZE);
	DivBuff(pVBuf,width,height,nStride,DCTSIZE,DCTSIZE);
	quality = QualityScaling(quality);
	SetQuantTable(std_Y_QT,JpgInfo.YQT, quality); // 设置Y量化表
	SetQuantTable(std_UV_QT,JpgInfo.UVQT,quality); // 设置UV量化表
	
	InitQTForAANDCT(&JpgInfo);            // 初始化AA&N需要的量化表
	JpgInfo.pVLITAB=JpgInfo.VLI_TAB + 2048;                             // 设置VLI_TAB的别名
	BuildVLITable(&JpgInfo);            // 计算VLI表   
	
	
	nDataLen = 0;
	// 写入各段
	nDataLen = WriteSOI(pOut,nDataLen); 
	nDataLen = WriteAPP0(pOut,nDataLen);
	nDataLen = WriteDQT(&JpgInfo,pOut,nDataLen);
	nDataLen = WriteSOF(pOut,nDataLen,width,height);
	nDataLen = WriteDHT(pOut,nDataLen);
	nDataLen = WriteSOS(pOut,nDataLen);
	
	// 计算Y/UV信号的交直分量的huffman表,这里使用标准的huffman表,并不是计算得出,缺点是文件略长,但是速度快
	BuildSTDHuffTab(STD_DC_Y_NRCODES,STD_DC_Y_VALUES,JpgInfo.STD_DC_Y_HT);
	BuildSTDHuffTab(STD_AC_Y_NRCODES,STD_AC_Y_VALUES,JpgInfo.STD_AC_Y_HT);
	BuildSTDHuffTab(STD_DC_UV_NRCODES,STD_DC_UV_VALUES,JpgInfo.STD_DC_UV_HT);
	BuildSTDHuffTab(STD_AC_UV_NRCODES,STD_AC_UV_VALUES,JpgInfo.STD_AC_UV_HT);
	
	// 处理单元数据
	nDataLen = ProcessData(&JpgInfo,pYBuf,pUBuf,pVBuf,width,height,pOut,nDataLen);  
	nDataLen = WriteEOI(pOut,nDataLen);
	
	free(pYBuf);
	free(pUBuf);
	free(pVBuf);
	*pnOutSize = nDataLen;
	return 0;
}