在黑客中国上找到的,运行调试后,可以使用,代码如下:
// Y2R.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <fcntl.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#define BYTE unsigned char
#define BOOL bool
#define DWORD unsigned long
#define FALSE 0
#define TRUE 1
BYTE *pYUVBuf, *pRGBBuf;
//#define YUV_SIZE 84480L+21120+21120
//#define RGB_SIZE IMAGE_WIDTH*IMAGE_HEIGHT*3L
//#define YUVFilename "c:\\pict.yuv"
//#define BMPFilename "c:\\pict.bmp"
/*
#define YUV_SIZE 1536L
#define IMAGE_WIDTH 32L
#define IMAGE_HEIGHT 32L
#define RGB_SIZE IMAGE_WIDTH*IMAGE_HEIGHT*3L
#define YUVFilename "gta10.bin"
#define BMPFilename "pp0.bmp"
*/
long U[256], V[256], Y1[256], Y2[256];
DWORD IMAGE_WIDTH=1;
DWORD IMAGE_HEIGHT=1;
DWORD YUV_SIZE=0;
DWORD RGB_SIZE=0;
char YUVFilename[MAX_PATH];
char BMPFilename[MAX_PATH];
void MakeConversionTable()
{
long i;
for (i=0; i<256; i++)
{
V[i] = 15938*i-2221300;
U[i] = 20238*i-2771300;
Y1[i] = 11644*i;
Y2[i] = 19837*i-311710;
}
}
BOOL YUV420ToRGB (DWORD width,
DWORD height,
BYTE *pYUVBuf,
BYTE *pRGBBuf
)
{
unsigned char *pY, *pU, *pV, *pUbase, *pVbase;
DWORD i, j;
unsigned char *pR, *pG, *pB;
// check if width and height is both in unit of 16 pixels
if ((width % 16) || (height % 16))
return FALSE;
pY = pYUVBuf;
pU = pUbase = pYUVBuf + width*height;
pV = pVbase = pUbase + width*height/4;
for (i=0; i<height; i++)
{
pB = pRGBBuf+RGB_SIZE-3*width*(i+1);
pG = pRGBBuf+RGB_SIZE-3*width*(i+1)+1;
pR = pRGBBuf+RGB_SIZE-3*width*(i+1)+2;
for (j=0; j<width; j+=2)
{
*pR = max (0, min (255, (V[*pV] + Y1[*pY])/10000) ); //R value
*pB = max (0, min (255, (U[*pU] + Y1[*pY])/10000) ); //B value
*pG = max (0, min (255, (Y2[*pY] - 5094*(*pR) - 1942*(*pB))/10000) ); //G value
pR += 3;
pB += 3;
pG += 3;
pY++;
*pR = max (0, min (255, (V[*pV] + Y1[*pY])/10000) ); //R value
*pB = max (0, min (255, (U[*pU] + Y1[*pY])/10000) ); //B value
*pG = max (0, min (255, (Y2[*pY] - 5094*(*pR) - 1942*(*pB))/10000) ); //G value
pR += 3;
pB += 3;
pG += 3;
pY++;
pU++;
pV++;
}
if ((i % 2 == 0))
{
pU = pU-(width >> 1);
pV = pV-(width >> 1);
}
}
return TRUE;
}
BOOL AllocateBuffers()
{
pYUVBuf = (BYTE *)new char [YUV_SIZE];
pRGBBuf = (BYTE *)new char [RGB_SIZE];
if (pYUVBuf && pRGBBuf)
return TRUE;
else
return FALSE;
}
void FreeBuffers()
{
if (pYUVBuf) delete pYUVBuf;
if (pRGBBuf) delete pRGBBuf;
pYUVBuf = pRGBBuf = NULL;
}
BOOL ReadYUVFile()
{
int fp;
DWORD count=0;
if( (fp = _open( YUVFilename, _O_RDONLY|_O_BINARY )) == -1 )
{
printf( "Can not open YUV file: %s\n", YUVFilename );
return FALSE;
}
//else
// printf( "Open YUV file: %s\n", YUVFilename );
if ((count=_read(fp, pYUVBuf, YUV_SIZE)) != YUV_SIZE)
{
printf( "Read YUV file failed: count=%d\n", count);
_close(fp);
return FALSE;
}
//else
// printf( "Read YUV file OK\n");
_close(fp);
return TRUE;
}
BOOL WriteBMPFile()
{
FILE *fp;
DWORD count=0;
BITMAPFILEHEADER bmpHeader;
BITMAPINFO bmpInfo;
if( (fp = fopen( BMPFilename, "wb")) == NULL )
{
printf( "Can not create BMP file: %s\n", YUVFilename );
return FALSE;
}
//else
// printf( "Create BMP file: %s\n", BMPFilename );
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 = IMAGE_WIDTH;
bmpInfo.bmiHeader.biHeight = IMAGE_HEIGHT;
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);
//else
// printf( "write BMP file header OK: 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);
//else
// printf( "Read BMP file info OK: count=%d\n", count);
if ((count=fwrite(pRGBBuf, 1, RGB_SIZE, fp)) != RGB_SIZE)
printf( "write BMP file data failed: count=%d\n", count);
//else
// printf( "write BMP file data OK: count=%d\n",count);
fclose(fp);
return TRUE;
}
void Help()
{
printf("Usage: YUV2BMP /h352 /v240 input_file output_file \n");
printf(" /h352 - width in pixels is 352 (in multiples of 16)\n");
printf(" /v240 - height in pixels is 240 (in multiples of 16)\n");
printf("Copyright(C) Winbond Electronics Corp. 1999\n");
}
// Gets command line arguments.
// Returns: TRUE on success, FALSE on error
// returns index of the first unread argument in *pi
BOOL GetArgs(int argc, char* argv[])
{
int i=0;
char str255[256];
if (argc != 5)
{
Help();
return FALSE;
}
#define ArgIs(s) (!strcmp(argv[i]+1, s))
while(*(argv[++i]) == '/') // get parameters - must start with '/'
{
//printf("argv%d=%s\n", i, argv[i]);
if ( (*(argv[i]+1) == 'h') || (*(argv[i]+1) == 'H'))
{
strcpy(str255, argv[i]+2);
IMAGE_WIDTH = atoi(str255);
}
else
if ((*(argv[i]+1) == 'v') || (*(argv[i]+1) == 'V'))
{
strcpy(str255, argv[i]+2);
IMAGE_HEIGHT = atoi(str255);
}
}
if ((IMAGE_WIDTH % 16 != 0) || (IMAGE_HEIGHT % 16 != 0))
{
printf("width or height is not multiples of 16\n");
return FALSE;
}
YUV_SIZE = IMAGE_WIDTH*IMAGE_HEIGHT + IMAGE_WIDTH*IMAGE_HEIGHT/2;
RGB_SIZE = IMAGE_WIDTH*IMAGE_HEIGHT*3L;
strcpy(YUVFilename, argv[3]); // next argument is a input file name
strcpy(BMPFilename, argv[4]); // next argument is a output file name
return TRUE;
}
int main(int argc, char* argv[])
{
//char cWait;
if (!GetArgs(argc, argv))
return 0;
pYUVBuf = pRGBBuf = NULL;
MakeConversionTable();
if (!AllocateBuffers())
{
printf( "Allocate buffer failed\n");
}
else
{
//printf( "Allocate buffer OK\n");
if (ReadYUVFile())
{
if (!YUV420ToRGB(IMAGE_WIDTH, IMAGE_HEIGHT, pYUVBuf, pRGBBuf))
printf("YCbCr4:2:0 to BMP conversion failed\n");
else
{
if (WriteBMPFile())
printf("YCbCr4:2:0 to BMP conversion OK\n");
}
}
}
FreeBuffers();
//printf("\n*** Press return key to continue.\n");
//scanf("%c", &cWait);
return 0;
}