RGB2YUV

#define RGB2YUV_SHIFT 16
#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
#define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5))
#define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
#define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5))
#define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5))
#define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5))
#define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5))
#define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
#define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5))

void rgb24toyuv400(const unsigned char *src, unsigned char *ydst, unsigned char *udst,
	unsigned char *vdst,unsigned int width, unsigned int height,unsigned int lumStride,
	unsigned int chromStride, unsigned int srcStride)
{
	unsigned int y;

	for(y=0; y<height; y++)
	{
		unsigned int i;
		for(i=0; i<height; i++)
		{
			unsigned int b= src[3*i+0];
			unsigned int g= src[3*i+1];
			unsigned int r= src[3*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;

			ydst[i] 	= Y;
		}

		ydst += lumStride;
		src  += srcStride;
	}
}

void rgb24toyuv411(const unsigned char *src, unsigned char *ydst, unsigned char *udst,
	unsigned char *vdst,unsigned int width, unsigned int height,unsigned int lumStride,
	unsigned int chromStride, unsigned int srcStride)
{
	unsigned int y;
	const unsigned int chromWidth = width>>1;

	y=0;
	for(; y<height; y+=2)
	{
		unsigned int i;
		for(i=0; i<chromWidth; i++)
		{
			unsigned int b= src[6*i+0];
			unsigned int g= src[6*i+1];
			unsigned int r= src[6*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
			unsigned int V  =  ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;
			unsigned int U  =  ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;

			udst[i] 	= U;
			vdst[i] 	= V;
			ydst[2*i] 	= Y;

			b= src[6*i+3];
			g= src[6*i+4];
			r= src[6*i+5];

			Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
			ydst[2*i+1] 	= Y;
		}
		ydst += lumStride;
		src  += srcStride;

		for(i=0; i<chromWidth; i++)
		{
			unsigned int b= src[6*i+0];
			unsigned int g= src[6*i+1];
			unsigned int r= src[6*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;

			ydst[2*i] 	= Y;

			b= src[6*i+3];
			g= src[6*i+4];
			r= src[6*i+5];

			Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
			ydst[2*i+1] 	= Y;
		}
		udst += chromStride;
		vdst += chromStride;
		ydst += lumStride;
		src  += srcStride;
	}
}

void rgb24toyuv420(const unsigned char *src, unsigned char *ydst, unsigned char *udst,
	unsigned char *vdst,unsigned int width, unsigned int height,unsigned int lumStride,
	unsigned int chromStride, unsigned int srcStride)
{
	unsigned int y;
	const unsigned int chromWidth = width>>1;

	y=0;
	for(; y<height; y+=2)
	{
		unsigned int i;
		for(i=0; i<chromWidth; i++)
		{
			unsigned int b= src[6*i+0];
			unsigned int g= src[6*i+1];
			unsigned int r= src[6*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
			unsigned int U  =  ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;

			udst[i] 	= U;
			ydst[2*i] 	= Y;

			b= src[6*i+3];
			g= src[6*i+4];
			r= src[6*i+5];

			Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
			ydst[2*i+1] 	= Y;
		}
		ydst += lumStride;
		src  += srcStride;

		for(i=0; i<chromWidth; i++)
		{
			unsigned int b= src[6*i+0];
			unsigned int g= src[6*i+1];
			unsigned int r= src[6*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
			unsigned int V  =  ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;

			vdst[i] 	= V;
			ydst[2*i] 	= Y;

			b= src[6*i+3];
			g= src[6*i+4];
			r= src[6*i+5];

			Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
			ydst[2*i+1] 	= Y;
		}
		udst += chromStride;
		vdst += chromStride;
		ydst += lumStride;
		src  += srcStride;
	}
}

void rgb24toyuv422(const unsigned char *src, unsigned char *ydst, unsigned char *udst,
	unsigned char *vdst,unsigned int width, unsigned int height,unsigned int lumStride,
	unsigned int chromStride, unsigned int srcStride)
{
	unsigned int y;
	const unsigned int chromWidth = width>>1;

	for(y=0; y<height; y++)
	{
		unsigned int i;
		for(i=0; i<chromWidth; i++)
		{
			unsigned int b= src[6*i+0];
			unsigned int g= src[6*i+1];
			unsigned int r= src[6*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
			unsigned int V  =  ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;
			unsigned int U  =  ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;

			udst[i] 	= U;
			vdst[i] 	= V;
			ydst[2*i] 	= Y;

			b= src[6*i+3];
			g= src[6*i+4];
			r= src[6*i+5];

			Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
			ydst[2*i+1] 	= Y;
		}
		udst += chromStride;
		vdst += chromStride;
		ydst += lumStride;
		src  += srcStride;
	}
}

void rgb24toyuv444(const unsigned char *src, unsigned char *ydst, unsigned char *udst,
	unsigned char *vdst,unsigned int width, unsigned int height,unsigned int lumStride,
	unsigned int chromStride, unsigned int srcStride)
{
	unsigned int y;
	const unsigned int chromWidth = width;

	for(y=0; y<height; y++)
	{
		unsigned int i;
		for(i=0; i<chromWidth; i++)
		{
			unsigned int b= src[3*i+0];
			unsigned int g= src[3*i+1];
			unsigned int r= src[3*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
			unsigned int V  =  ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;
			unsigned int U  =  ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;

			udst[i] 	= U;
			vdst[i] 	= V;
			ydst[i] 	= Y;
		}

		udst += chromStride;
		vdst += chromStride;
		ydst += lumStride;
		src  += srcStride;
	}
}

int HeadStand(unsigned char *pBuf,int pWidth,int pHeight)
{
	unsigned char *tBuf;
	int i;

	if ((tBuf = (unsigned char *)malloc(pWidth*pHeight*3)) == NULL)
		return -1;
	for (i=0;i<pHeight/2;i++)
	{
		memcpy(tBuf,pBuf+i*pWidth*3,pWidth*3);
		memcpy(pBuf+i*pWidth*3,pBuf+(pHeight-i-1)*pWidth*3,pWidth*3);
		memcpy(pBuf+(pHeight-i-1)*pWidth*3,tBuf,pWidth*3);
	}
	free(tBuf);
	return 0;
}


void CBmp2yuvDlg::OnConvert() 
{
	// TODO: Add your control notification handler code here
	CString tPathName;
	CString tDesDir;
	char    tDesPathName[100];
	FILE *fp;
	unsigned char *rgbBuf,*ty,*tu,*tv;
	int with=0,height=0,iSizeImage = 0;
	BITMAPFILEHEADER bitmap;
	BITMAPINFOHEADER bitmapHeader;
	char tStr1[100],tStr2[100];
	int i,StrLen,SelYUVFormat;
	CString FileName;
	CComboBox *pComboBox;
	int ySize,uSize,vSize;

	//检测输入是不是合法
	GetDlgItemText(IDC_SOURCEDIR,tPathName);
	if(tPathName.IsEmpty() != 0)
		return;

	GetDlgItemText(IDC_DESDIR,tDesDir);
	if(tDesDir.IsEmpty() != 0)
		return;
	GetDlgItemText(IDC_DESFILENAME,FileName);
	if(FileName.IsEmpty() != 0)
		return;

	fp = fopen(tPathName,"r");
	if(fp == NULL)
		return;

	//得到要转化的yuv格式
	pComboBox = (CComboBox *)GetDlgItem(IDC_YUVFORMAT);
	SelYUVFormat = pComboBox->GetCurSel();

	//得到bitmap头部信息,包括文件头和bitmap头
	memset(&(bitmap),0,sizeof(bitmap));
	memset(&(bitmapHeader),0,sizeof(bitmapHeader));
	fread(&bitmap,sizeof(char),sizeof(bitmap),fp);
	fread(&bitmapHeader,sizeof(char),sizeof(bitmapHeader),fp);

	//分配空间
	with = bitmapHeader.biWidth;
	height = bitmapHeader.biHeight;
	if((with%2 != 0) || (height%2 != 0))
	{
		AfxMessageBox("图像的分辨率必须是偶数!",MB_OK,-1);
		return;
	}
//	iSizeImage = bitmapHeader.biSizeImage;
	iSizeImage = with*height*3;
	switch(SelYUVFormat)
	{
	case YUV400:
		rgbBuf = (unsigned char *)malloc(iSizeImage);
	    if(rgbBuf == NULL)
	    	return;
		ySize = iSizeImage/3;
		ty = (unsigned char *)malloc(ySize);
	    if(ty == NULL)
	    	return;
		uSize = 0;
    	tu = (unsigned char *)malloc(uSize);
    	if(tu == NULL)
	    	return;
		vSize = 0;
    	tv = (unsigned char *)malloc(vSize);
    	if(tv == NULL)
	    	return;
    	fseek(fp,bitmap.bfOffBits,SEEK_SET);

    	fread(rgbBuf,sizeof(char),iSizeImage,fp);

    	HeadStand(rgbBuf,with,height);

    	rgb24toyuv400(rgbBuf,ty,tu,tv,with,height,with,0,with*3);

		break;
	case YUV411:
		rgbBuf = (unsigned char *)malloc(iSizeImage);
	    if(rgbBuf == NULL)
	    	return;
		ySize = iSizeImage/3;
		ty = (unsigned char *)malloc(ySize);
	    if(ty == NULL)
	    	return;
		uSize = iSizeImage/12;
    	tu = (unsigned char *)malloc(uSize);
    	if(tu == NULL)
	    	return;
		vSize = iSizeImage/12;
    	tv = (unsigned char *)malloc(vSize);
    	if(tv == NULL)
	    	return;
    	fseek(fp,bitmap.bfOffBits,SEEK_SET);

    	fread(rgbBuf,sizeof(char),iSizeImage,fp);

    	HeadStand(rgbBuf,with,height);

    	rgb24toyuv411(rgbBuf,ty,tu,tv,with,height,with,with/4,with*3);

		break;
	case YUV420:
		rgbBuf = (unsigned char *)malloc(iSizeImage);
	    if(rgbBuf == NULL)
	    	return;
		ySize = iSizeImage/3;
		ty = (unsigned char *)malloc(ySize);
	    if(ty == NULL)
	    	return;
		uSize = iSizeImage/12;
    	tu = (unsigned char *)malloc(uSize);
    	if(tu == NULL)
	    	return;
		vSize = iSizeImage/12;
    	tv = (unsigned char *)malloc(vSize);
    	if(tv == NULL)
	    	return;
    	fseek(fp,bitmap.bfOffBits,SEEK_SET);

    	fread(rgbBuf,sizeof(char),iSizeImage,fp);

    	HeadStand(rgbBuf,with,height);

    	rgb24toyuv420(rgbBuf,ty,tu,tv,with,height,with,with/4,with*3);

		break;	
	case YUV422:
		rgbBuf = (unsigned char *)malloc(iSizeImage);
	    if(rgbBuf == NULL)
	    	return;
		ySize = iSizeImage/3;
		ty = (unsigned char *)malloc(ySize);
	    if(ty == NULL)
	    	return;
		uSize = iSizeImage/6;
    	tu = (unsigned char *)malloc(uSize);
    	if(tu == NULL)
	    	return;
		vSize = iSizeImage/6;
    	tv = (unsigned char *)malloc(vSize);
    	if(tv == NULL)
	    	return;
    	fseek(fp,bitmap.bfOffBits,SEEK_SET);

    	fread(rgbBuf,sizeof(char),iSizeImage,fp);

    	HeadStand(rgbBuf,with,height);

    	rgb24toyuv422(rgbBuf,ty,tu,tv,with,height,with,with/2,with*3);

		break;
	case YUV444:
		rgbBuf = (unsigned char *)malloc(iSizeImage);
	    if(rgbBuf == NULL)
	    	return;
		ySize = iSizeImage/3;
		ty = (unsigned char *)malloc(ySize);
	    if(ty == NULL)
	    	return;
		uSize = iSizeImage/3;
    	tu = (unsigned char *)malloc(uSize);
    	if(tu == NULL)
	    	return;
		vSize = iSizeImage/3;
    	tv = (unsigned char *)malloc(vSize);
    	if(tv == NULL)
	    	return;
    	fseek(fp,bitmap.bfOffBits,SEEK_SET);

    	fread(rgbBuf,sizeof(char),iSizeImage,fp);

    	HeadStand(rgbBuf,with,height);

    	rgb24toyuv444(rgbBuf,ty,tu,tv,with,height,with,with,with*3);

		break;
	default:
		break;
	}

	fclose(fp);

	StrLen = tDesDir.GetLength();
	for(i = 0; i < StrLen;i++)
		tStr1[i] = tDesDir.GetAt(i);
	tStr1[i] = 0;
	StrLen = FileName.GetLength();
	for(i = 0; i < StrLen;i++)
		tStr2[i] = FileName.GetAt(i);
	tStr2[i] = 0;
	sprintf(tDesPathName,"%s\\%s.yuv",tStr1,tStr2);

	fp = fopen(tDesPathName,"w");
	if(fp == NULL)
		return;

	fwrite(ty,sizeof(char),ySize,fp);
	fwrite(tu,sizeof(char),uSize,fp);
	fwrite(tv,sizeof(char),vSize,fp);

	fclose(fp);

	free(rgbBuf);
	free(ty);
	free(tu);
	free(tv);

	AfxMessageBox("转化完成!",MB_OK,-1);
	
}

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值