Y2R.cpp
上传用户:gtting103
上传日期:2007-01-12
资源大小:26k
文件大小:7k
源码类别:

图形图象

开发平台:

Visual C++

  1. // Y2R.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include <fcntl.h>
  5. #include <io.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <windows.h>
  9. #define BYTE unsigned char
  10. #define BOOL bool
  11. #define DWORD unsigned long
  12. #define FALSE 0
  13. #define TRUE 1
  14. BYTE *pYUVBuf, *pRGBBuf;
  15. //#define YUV_SIZE 84480L+21120+21120
  16. //#define RGB_SIZE IMAGE_WIDTH*IMAGE_HEIGHT*3L
  17. //#define YUVFilename "c:\pict.yuv"
  18. //#define BMPFilename "c:\pict.bmp"
  19. /*
  20. #define YUV_SIZE 1536L
  21. #define IMAGE_WIDTH 32L
  22. #define IMAGE_HEIGHT 32L
  23. #define RGB_SIZE IMAGE_WIDTH*IMAGE_HEIGHT*3L
  24. #define YUVFilename "gta10.bin"
  25. #define BMPFilename "pp0.bmp"
  26. */
  27. long U[256], V[256], Y1[256], Y2[256];
  28. DWORD IMAGE_WIDTH=1;
  29. DWORD IMAGE_HEIGHT=1;
  30. DWORD YUV_SIZE=0;
  31. DWORD RGB_SIZE=0;
  32. char YUVFilename[MAX_PATH];
  33. char BMPFilename[MAX_PATH];
  34. void MakeConversionTable()
  35. {
  36. long i;
  37. for (i=0; i<256; i++)
  38. {
  39. V[i] = 15938*i-2221300;
  40.         U[i] = 20238*i-2771300;
  41.         Y1[i] = 11644*i;
  42.         Y2[i] = 19837*i-311710;
  43. }
  44. }
  45. BOOL YUV420ToRGB (DWORD width, 
  46.   DWORD height,
  47.   BYTE *pYUVBuf,
  48.   BYTE *pRGBBuf
  49.   )
  50. {
  51. unsigned char *pY, *pU, *pV, *pUbase, *pVbase;
  52. DWORD i, j;
  53. unsigned char *pR, *pG, *pB;
  54. // check if width and height is both in unit of 16 pixels
  55. if ((width % 16) || (height % 16))
  56. return FALSE;
  57. pY = pYUVBuf;
  58. pU = pUbase = pYUVBuf + width*height;
  59. pV = pVbase = pUbase + width*height/4;
  60. for (i=0; i<height; i++)
  61. {
  62. pB = pRGBBuf+RGB_SIZE-3*width*(i+1);
  63. pG = pRGBBuf+RGB_SIZE-3*width*(i+1)+1;
  64. pR = pRGBBuf+RGB_SIZE-3*width*(i+1)+2;
  65. for (j=0; j<width; j+=2)
  66. {
  67. *pR = max (0, min (255, (V[*pV] + Y1[*pY])/10000) );   //R value
  68. *pB = max (0, min (255, (U[*pU] + Y1[*pY])/10000) );   //B value
  69. *pG = max (0, min (255, (Y2[*pY] - 5094*(*pR) - 1942*(*pB))/10000) ); //G value
  70. pR += 3;
  71. pB += 3;
  72. pG += 3;
  73. pY++;
  74. *pR = max (0, min (255, (V[*pV] + Y1[*pY])/10000) );   //R value
  75. *pB = max (0, min (255, (U[*pU] + Y1[*pY])/10000) );   //B value
  76. *pG = max (0, min (255, (Y2[*pY] - 5094*(*pR) - 1942*(*pB))/10000) ); //G value
  77. pR += 3;
  78. pB += 3;
  79. pG += 3;
  80. pY++;
  81. pU++;
  82. pV++;
  83. }
  84. if ((i % 2 == 0))
  85. {
  86. pU = pU-(width >> 1);
  87. pV = pV-(width >> 1);
  88. }
  89. }
  90. return TRUE;
  91. }
  92. BOOL AllocateBuffers()
  93. {
  94. pYUVBuf = (BYTE *)new char [YUV_SIZE];
  95. pRGBBuf = (BYTE *)new char [RGB_SIZE];
  96. if (pYUVBuf && pRGBBuf)
  97. return TRUE;
  98. else
  99. return FALSE;
  100. }
  101. void FreeBuffers()
  102. {
  103. if (pYUVBuf) delete pYUVBuf; 
  104. if (pRGBBuf) delete pRGBBuf;
  105. pYUVBuf = pRGBBuf = NULL;
  106. }
  107. BOOL ReadYUVFile()
  108. {
  109. int fp;
  110. DWORD count=0;
  111. if( (fp = _open( YUVFilename, _O_RDONLY|_O_BINARY )) == -1 ) 
  112. {
  113. printf( "Can not open YUV file: %sn", YUVFilename );
  114. return FALSE;
  115. }
  116. //else
  117. // printf( "Open YUV file: %sn", YUVFilename );
  118. if ((count=_read(fp, pYUVBuf, YUV_SIZE)) != YUV_SIZE)
  119. {
  120. printf( "Read YUV file failed: count=%dn", count);
  121. _close(fp);
  122. return FALSE;
  123. }
  124. //else
  125. // printf( "Read YUV file OKn");
  126. _close(fp);
  127. return TRUE;
  128. }
  129. BOOL WriteBMPFile()
  130. {
  131. FILE *fp;
  132. DWORD count=0;
  133. BITMAPFILEHEADER bmpHeader;
  134. BITMAPINFO bmpInfo;
  135. if( (fp = fopen( BMPFilename, "wb")) == NULL ) 
  136. {
  137. printf( "Can not create BMP file: %sn", YUVFilename );
  138. return FALSE;
  139. }
  140. //else
  141. // printf( "Create BMP file: %sn", BMPFilename );
  142. bmpHeader.bfType = 'MB';
  143. bmpHeader.bfSize = RGB_SIZE + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  144. bmpHeader.bfReserved1 = 0;
  145. bmpHeader.bfReserved2 = 0;
  146. bmpHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  147. bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  148. bmpInfo.bmiHeader.biWidth = IMAGE_WIDTH;
  149. bmpInfo.bmiHeader.biHeight = IMAGE_HEIGHT;
  150. bmpInfo.bmiHeader.biPlanes = 1;
  151. bmpInfo.bmiHeader.biBitCount = 24;
  152. bmpInfo.bmiHeader.biCompression = BI_RGB;
  153. bmpInfo.bmiHeader.biSizeImage = RGB_SIZE;
  154. bmpInfo.bmiHeader.biXPelsPerMeter = 0;
  155. bmpInfo.bmiHeader.biYPelsPerMeter = 0;
  156. bmpInfo.bmiHeader.biClrUsed = 0;
  157. bmpInfo.bmiHeader.biClrImportant = 0;
  158. if ((count=fwrite(&bmpHeader, 1, sizeof(BITMAPFILEHEADER), fp)) != sizeof(BITMAPFILEHEADER))
  159. printf( "write BMP file header failed: count=%dn", count);
  160. //else
  161. // printf( "write BMP file header OK: count=%dn", count);
  162. if ((count=fwrite(&(bmpInfo.bmiHeader), 1, sizeof(BITMAPINFOHEADER), fp)) != sizeof(BITMAPINFOHEADER))
  163. printf( "Read BMP file info failed: count=%dn", count);
  164. //else
  165. // printf( "Read BMP file info OK: count=%dn", count);
  166. if ((count=fwrite(pRGBBuf, 1, RGB_SIZE, fp)) != RGB_SIZE)
  167. printf( "write BMP file data failed: count=%dn", count);
  168. //else
  169. // printf( "write BMP file data OK: count=%dn",count);
  170. fclose(fp);
  171. return TRUE;
  172. }
  173. void Help()
  174. {
  175. printf("Usage: YUV2BMP /h352 /v240 input_file output_file n");
  176. printf("       /h352  -  width in pixels is 352 (in multiples of 16)n");
  177. printf("       /v240  -  height in pixels is 240 (in multiples of 16)n");
  178. printf("Copyright(C) Winbond Electronics Corp. 1999n");
  179. }
  180. // Gets command line arguments.
  181. // Returns: TRUE on success, FALSE on error
  182. // returns index of the first unread argument in *pi
  183. BOOL GetArgs(int argc, char* argv[])
  184. {
  185. int i=0;
  186. char str255[256];
  187. if (argc != 5) 
  188. {
  189. Help();
  190. return FALSE;
  191. }
  192. #define ArgIs(s)  (!strcmp(argv[i]+1, s))
  193. while(*(argv[++i]) == '/') // get parameters - must start with '/'
  194. {
  195. //printf("argv%d=%sn", i, argv[i]);
  196. if ( (*(argv[i]+1) == 'h') || (*(argv[i]+1) == 'H'))
  197. {
  198. strcpy(str255, argv[i]+2);
  199. IMAGE_WIDTH = atoi(str255);
  200. }
  201. else
  202. if ((*(argv[i]+1) == 'v') || (*(argv[i]+1) == 'V'))
  203. {
  204. strcpy(str255, argv[i]+2);
  205. IMAGE_HEIGHT = atoi(str255);
  206. }
  207. }
  208. if ((IMAGE_WIDTH % 16 != 0) || (IMAGE_HEIGHT % 16 != 0))
  209. {
  210. printf("width or height is not multiples of 16n");
  211. return FALSE;
  212. }
  213. YUV_SIZE = IMAGE_WIDTH*IMAGE_HEIGHT + IMAGE_WIDTH*IMAGE_HEIGHT/2;
  214. RGB_SIZE = IMAGE_WIDTH*IMAGE_HEIGHT*3L;
  215. strcpy(YUVFilename, argv[3]); // next argument is a input file name
  216. strcpy(BMPFilename, argv[4]); // next argument is a output file name
  217. return TRUE;
  218. }
  219. int main(int argc, char* argv[])
  220. {
  221. //char cWait;
  222. if (!GetArgs(argc, argv))
  223. return 0;
  224. pYUVBuf = pRGBBuf = NULL;
  225. MakeConversionTable();
  226. if (!AllocateBuffers())
  227. {
  228. printf( "Allocate buffer failedn");
  229. }
  230. else
  231. {
  232. //printf( "Allocate buffer OKn");
  233. if (ReadYUVFile())
  234. {
  235. if (!YUV420ToRGB(IMAGE_WIDTH, IMAGE_HEIGHT, pYUVBuf, pRGBBuf))
  236. printf("YCbCr4:2:0 to BMP conversion failedn");
  237. else
  238. {
  239. if (WriteBMPFile())
  240. printf("YCbCr4:2:0 to BMP conversion OKn");
  241. }
  242. }
  243. }
  244. FreeBuffers();
  245. //printf("n*** Press return key to continue.n");
  246. //scanf("%c", &cWait);
  247. return 0;
  248. }