#include <windows.h>
#include <malloc.h>
#include <string>
using namespace std;
#define clip(min, x, max) x=(x < min) ? min : (x > max) ? max : x
//
// Construction/Destruction
//
CUYVY2BMP::CUYVY2BMP(int width, int height)
{
m_nWidth = width;
m_nHeight = height;
}
CUYVY2BMP::~CUYVY2BMP()
{
}
///accessor
int CUYVY2BMP::GetHeight()
{
return m_nHeight;
}
int CUYVY2BMP::GetWidth()
{
return m_nWidth;
}
void CUYVY2BMP::MakeConversionTable()
{
for (long j = 0; j < 256; ++j)
{
table_UYVY2rgb.YtoR[j] = table_UYVY2rgb.YtoG[j]
= table_UYVY2rgb.YtoB[j] = (unsigned short)(j << 7);
table_UYVY2rgb.VtoR[j] = j * 180; //180=1.402*128
table_UYVY2rgb.VtoG[j] = j * 91;
table_UYVY2rgb.UtoG[j] = j * 44; //0.3437 = 44/128
table_UYVY2rgb.UtoB[j] = j * 226; //1.772 = 226/128
}
}
BOOL CUYVY2BMP::UYVY2BMP(BYTE* pDst, BYTE *pSrc)
{
long m = 0;
long k = 0;
int n=m_nWidth/2;
int dec=m_nWidth*4;
int tmpR0 = 0;
int tmpG0 = 0;
int tmpB0 = 0;
int tmpR1 = 0;
int tmpG1 = 0;
int tmpB1 = 0;
MakeConversionTable();
k=(m_nHeight-1)*m_nWidth<<1; //k指向最后一行
for( int i=m_nHeight-1;i>-1;i--)
{
for(int j=0;j<n;j++)
{
tmpR0 = (table_UYVY2rgb.YtoR[pSrc[k + 1]] + table_UYVY2rgb.VtoR[pSrc[k + 2]] - 22906) >> 7;
tmpG0 = (table_UYVY2rgb.YtoG[pSrc[k + 1]] - table_UYVY2rgb.VtoG[pSrc[k + 2]] - table_UYVY2rgb.UtoG[pSrc[k + 0]] + 17264) >> 7;
tmpB0 = (table_UYVY2rgb.YtoB[pSrc[k + 1]] + table_UYVY2rgb.UtoB[pSrc[k + 0]] - 28928) >> 7;
tmpR1 = (table_UYVY2rgb.YtoR[pSrc[k + 3]] + table_UYVY2rgb.VtoR[pSrc[k + 2]] - 22906) >> 7;
tmpG1 = (table_UYVY2rgb.YtoG[pSrc[k + 3]] - table_UYVY2rgb.VtoG[pSrc[k + 2]] - table_UYVY2rgb.UtoG[pSrc[k + 0]] + 17264) >> 7;
tmpB1 = (table_UYVY2rgb.YtoB[pSrc[k + 3]] + table_UYVY2rgb.UtoB[pSrc[k + 0]] - 28928) >> 7;
clip(0, tmpR0, 255);
clip(0, tmpG0, 255);
clip(0, tmpB0, 255);
clip(0, tmpR1, 255);
clip(0, tmpG1, 255);
clip(0, tmpB1, 255);
pDst[m + 0] = tmpB0;
pDst[m + 1] = tmpG0;
pDst[m + 2] = tmpR0;
pDst[m + 3] = tmpB1;
pDst[m + 4] = tmpG1;
pDst[m + 5] = tmpR1;
k += 4;
m += 6;
}
k=k-dec;
}
return 1;
}
BOOL CUYVY2BMP::WriteBMPFile(LPSTR BMPFilename, BYTE *pRGBBuf, int iBitCount)
{
long RGB_SIZE = m_nWidth * m_nHeight * 3;
if(iBitCount == 24)
{
FILE *fp;
long count=0;
BITMAPFILEHEADER bmpHeader;
BITMAPINFO bmpInfo;
if( (fp = fopen( BMPFilename, "wb")) == NULL )
{
printf( "Can not create BMP file: %s\n", BMPFilename );
return FALSE;
}
bmpHeader.bfType = 'MB';
bmpHeader.bfSize = RGB_SIZE + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpHeader.bfReserved1 = 0;
bmpHeader.bfReserved2 = 0;
bmpHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = m_nWidth;
bmpInfo.bmiHeader.biHeight = m_nHeight;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = RGB_SIZE;
bmpInfo.bmiHeader.biXPelsPerMeter = 0;
bmpInfo.bmiHeader.biYPelsPerMeter = 0;
bmpInfo.bmiHeader.biClrUsed = 0;
bmpInfo.bmiHeader.biClrImportant = 0;
if ((count=fwrite(&bmpHeader, 1, sizeof(BITMAPFILEHEADER), fp)) != sizeof(BITMAPFILEHEADER))
printf( "write BMP file header failed: count=%d\n", count);
if ((count=fwrite(&(bmpInfo.bmiHeader), 1, sizeof(BITMAPINFOHEADER), fp)) != sizeof(BITMAPINFOHEADER))
printf( "Read BMP file info failed: count=%d\n", count);
if ((count=fwrite(pRGBBuf, 1, RGB_SIZE, fp)) != RGB_SIZE)
printf( "write BMP file data failed: count=%d\n", count);
fclose(fp);
return TRUE;
}
else
return FALSE;
}
int main()
{
CUYVY2BMP test(352 ,288);
FILE *pFYUV;
int errno=0;
int n=test.GetWidth()/2;
//123为yuv视频文件名
if((pFYUV=fopen("123","rb"))==NULL)
{
return -1;
}
BYTE * pSrcBuf=(BYTE *)malloc(test.GetHeight()*test.GetWidth()*2);
BYTE * pDstBuf=(BYTE *)malloc(test.GetHeight()*test.GetWidth()*3);
fread(pSrcBuf,1,test.GetHeight()*test.GetWidth()*2,pFYUV);
test.UYVY2BMP(pDstBuf,pSrcBuf);
test.WriteBMPFile("402.bmp",pDstBuf,24);
return 0;
}