一个yuv转bmp的程序

在黑客中国上找到的,运行调试后,可以使用,代码如下:

// 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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值