Yuv2rgb.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:10k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include <memory.h>
  2. #include "portab.h"
  3. #include "yuv2rgb.h"
  4. /**
  5.  *
  6. **/
  7. void (*convert_yuv)(unsigned char *puc_y, int stride_y,
  8. unsigned char *puc_u, unsigned char *puc_v, int stride_uv,
  9. unsigned char *bmp, int width_y, int height_y,
  10. unsigned int stride_out);
  11. /**
  12.  *
  13. **/
  14. #define _S(a) (a)>255 ? 255 : (a)<0 ? 0 : (a)
  15. #define _R(y,u,v) (0x2568*(y)          + 0x3343*(u)) /0x2000
  16. #define _G(y,u,v) (0x2568*(y) - 0x0c92*(v) - 0x1a1e*(u)) /0x2000
  17. #define _B(y,u,v) (0x2568*(y) + 0x40cf*(v))      /0x2000
  18. struct lookuptable
  19. {
  20.     int32_t m_plY[256];
  21.     int32_t m_plRV[256];
  22.     int32_t m_plGV[256];
  23.     int32_t m_plGU[256];
  24.     int32_t m_plBU[256];
  25. };
  26. static struct lookuptable lut;
  27. void init_yuv2rgb()
  28. {
  29.     int i;
  30.     for(i=0; i<256; i++)
  31.     {
  32. if(i>=16)
  33.     if(i>240)
  34. lut.m_plY[i]=lut.m_plY[240];
  35.     else
  36. lut.m_plY[i]=298*(i-16);
  37. else
  38.     lut.m_plY[i]=0;
  39. if((i>=16) && (i<=240))
  40. {
  41.     lut.m_plRV[i]=408*(i-128);
  42.     lut.m_plGV[i]=-208*(i-128);
  43.     lut.m_plGU[i]=-100*(i-128);
  44.     lut.m_plBU[i]=517*(i-128);
  45. }
  46. else if(i<16)
  47. {
  48.     lut.m_plRV[i]=408*(16-128);
  49.     lut.m_plGV[i]=-208*(16-128);
  50.     lut.m_plGU[i]=-100*(16-128);
  51.     lut.m_plBU[i]=517*(16-128);
  52. }
  53. else
  54. {
  55.     lut.m_plRV[i]=lut.m_plRV[240];
  56.     lut.m_plGV[i]=lut.m_plGV[240];
  57.     lut.m_plGU[i]=lut.m_plGU[240];
  58.     lut.m_plBU[i]=lut.m_plBU[240];
  59. }
  60.     }
  61. }
  62. void yuv2rgb_32(uint8_t *puc_y, int stride_y, 
  63.                 uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  64.                 uint8_t *puc_out, int width_y, int height_y,
  65. unsigned int _stride_out) 
  66. {
  67. int x, y;
  68. int stride_diff = 4 * (_stride_out - width_y);
  69. if (height_y < 0) {
  70. height_y  = -height_y;
  71. puc_y     += (height_y   - 1) * stride_y ;
  72. puc_u     += (height_y/2 - 1) * stride_uv;
  73. puc_v     += (height_y/2 - 1) * stride_uv;
  74. stride_y  = -stride_y;
  75. stride_uv = -stride_uv;
  76. }
  77. for (y=0; y<height_y; y++) 
  78. {
  79. for (x=0; x<width_y; x++)
  80. {
  81. signed int _r,_g,_b; 
  82. signed int r, g, b;
  83. signed int y, u, v;
  84. y = puc_y[x] - 16;
  85. u = puc_u[x>>1] - 128;
  86. v = puc_v[x>>1] - 128;
  87. _r = _R(y,u,v);
  88. _g = _G(y,u,v);
  89. _b = _B(y,u,v);
  90. r = _S(_r);
  91. g = _S(_g);
  92. b = _S(_b);
  93. puc_out[0] = r;
  94. puc_out[1] = g;
  95. puc_out[2] = b;
  96. puc_out[3] = 0;
  97. puc_out+=4;
  98. }
  99. puc_y   += stride_y;
  100. if (y%2) {
  101. puc_u   += stride_uv;
  102. puc_v   += stride_uv;
  103. }
  104. puc_out += stride_diff;
  105. }
  106. }
  107. void yuv2rgb_24(uint8_t *puc_y, int stride_y, 
  108.                 uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  109.                 uint8_t *puc_out, int width_y, int height_y,
  110. unsigned int _stride_out) 
  111. {
  112. int x, y;
  113. int stride_diff = 6*_stride_out - 3*width_y;
  114. if (height_y < 0) {
  115. height_y  = -height_y;
  116. puc_y     += (height_y   - 1) * stride_y ;
  117. puc_u     += (height_y/2 - 1) * stride_uv;
  118. puc_v     += (height_y/2 - 1) * stride_uv;
  119. stride_y  = -stride_y;
  120. stride_uv = -stride_uv;
  121. }
  122. for (y=0; y<height_y; y+=2) 
  123. {
  124. uint8_t* pY=puc_y;
  125. uint8_t* pY1=puc_y+stride_y;
  126. uint8_t* pU=puc_u;
  127. uint8_t* pV=puc_v;
  128. uint8_t* pOut2=puc_out+3*_stride_out;
  129. for (x=0; x<width_y; x+=2)
  130. {
  131. int R, G, B;
  132. int Y;
  133. unsigned int tmp;
  134. R=lut.m_plRV[*pU];
  135. G=lut.m_plGV[*pU];
  136. pU++;
  137. G+=lut.m_plGU[*pV];
  138. B=lut.m_plBU[*pV];
  139. pV++;
  140. #define PUT_COMPONENT(p,v,i) 
  141.     tmp=(unsigned int)(v); 
  142.     if(tmp < 0x10000) 
  143. p[i]=tmp>>8; 
  144.     else
  145. p[i]=(tmp >> 24) ^ 0xff; 
  146. Y=lut.m_plY[*pY];
  147. pY++;
  148. PUT_COMPONENT(puc_out, R+Y, 0);
  149. PUT_COMPONENT(puc_out, G+Y, 1);
  150. PUT_COMPONENT(puc_out, B+Y, 2);
  151. Y=lut.m_plY[*pY];
  152. pY++;
  153. PUT_COMPONENT(puc_out, R+Y, 3);
  154. PUT_COMPONENT(puc_out, G+Y, 4);
  155. PUT_COMPONENT(puc_out, B+Y, 5);
  156. Y=lut.m_plY[*pY1];
  157. pY1++;
  158. PUT_COMPONENT(pOut2, R+Y, 0);
  159. PUT_COMPONENT(pOut2, G+Y, 1);
  160. PUT_COMPONENT(pOut2, B+Y, 2);
  161. Y=lut.m_plY[*pY1];
  162. pY1++;
  163. PUT_COMPONENT(pOut2, R+Y, 3);
  164. PUT_COMPONENT(pOut2, G+Y, 4);
  165. PUT_COMPONENT(pOut2, B+Y, 5);
  166. puc_out+=6;
  167. pOut2+=6;
  168. }
  169. puc_y   += 2*stride_y;
  170. puc_u   += stride_uv;
  171. puc_v   += stride_uv;
  172. puc_out += stride_diff;
  173. }
  174. }
  175. /***/
  176. #define _S(a) (a)>255 ? 255 : (a)<0 ? 0 : (a)
  177. #define _R(y,u,v) (0x2568*(y)          + 0x3343*(u)) /0x2000
  178. #define _G(y,u,v) (0x2568*(y) - 0x0c92*(v) - 0x1a1e*(u)) /0x2000
  179. #define _B(y,u,v) (0x2568*(y) + 0x40cf*(v))      /0x2000
  180. #define _mR 0x7c00
  181. #define _mG 0x03e0
  182. #define _mB 0x001f
  183. #define _Ps555(r,g,b) (((r) << 7) & _mR) | (((g) << 2) & _mG) | (((b) >> 3) & _mB)
  184. #define _Ps565(r,g,b) ( ((r & 0xF8) >> 3) | (((g & 0xF8) << 3)) | (((b & 0xF8) << 8)) )
  185. void yuv2rgb_555(uint8_t *puc_y, int stride_y, 
  186.                 uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  187.                 uint8_t *puc_out, int width_y, int height_y,
  188. unsigned int _stride_out) 
  189. {
  190. int x, y;
  191. unsigned short *pus_out;
  192. int stride_diff = _stride_out - width_y; 
  193. if (height_y < 0) {
  194. height_y  = -height_y;
  195. puc_y     += (height_y   - 1) * stride_y ;
  196. puc_u     += (height_y/2 - 1) * stride_uv;
  197. puc_v     += (height_y/2 - 1) * stride_uv;
  198. stride_y  = -stride_y;
  199. stride_uv = -stride_uv;
  200. }
  201. pus_out = (unsigned short *) puc_out;
  202. for (y=0; y<height_y; y++) 
  203. {
  204. for (x=0; x<width_y; x++)
  205. {
  206. signed int _r,_g,_b; 
  207. signed int r, g, b;
  208. signed int y, u, v;
  209. y = puc_y[x] - 16;
  210. u = puc_u[x>>1] - 128;
  211. v = puc_v[x>>1] - 128;
  212. _r = _R(y,u,v);
  213. _g = _G(y,u,v);
  214. _b = _B(y,u,v);
  215. r = _S(_r);
  216. g = _S(_g);
  217. b = _S(_b);
  218. pus_out[0] = _Ps555(b,g,r);
  219. pus_out++;
  220. }
  221. puc_y   += stride_y;
  222. if (y%2) {
  223. puc_u   += stride_uv;
  224. puc_v   += stride_uv;
  225. }
  226. pus_out += stride_diff;
  227. }
  228. }
  229. /***/
  230. void yuv2rgb_565(uint8_t *puc_y, int stride_y, 
  231.                 uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  232.                 uint8_t *puc_out, int width_y, int height_y,
  233. unsigned int _stride_out) 
  234. {
  235. int x, y;
  236. unsigned short *pus_out;
  237. int stride_diff = _stride_out - width_y; 
  238. if (height_y < 0) {
  239. height_y  = -height_y;
  240. puc_y     += (height_y   - 1) * stride_y ;
  241. puc_u     += (height_y/2 - 1) * stride_uv;
  242. puc_v     += (height_y/2 - 1) * stride_uv;
  243. stride_y  = -stride_y;
  244. stride_uv = -stride_uv;
  245. }
  246. pus_out = (unsigned short *) puc_out;
  247. for (y=0; y<height_y; y++) 
  248. {
  249. for (x=0; x<width_y; x++)
  250. {
  251. signed int _r,_g,_b; 
  252. signed int r, g, b;
  253. signed int y, u, v;
  254. y = puc_y[x] - 16;
  255. u = puc_u[x>>1] - 128;
  256. v = puc_v[x>>1] - 128;
  257. _r = _R(y,u,v);
  258. _g = _G(y,u,v);
  259. _b = _B(y,u,v);
  260. r = _S(_r);
  261. g = _S(_g);
  262. b = _S(_b);
  263. pus_out[0] = (unsigned short) _Ps565(r,g,b);
  264. pus_out++;
  265. }
  266. puc_y   += stride_y;
  267. if (y%2) {
  268. puc_u   += stride_uv;
  269. puc_v   += stride_uv;
  270. }
  271. pus_out += stride_diff;
  272. }
  273. }
  274. void yuy2_out(uint8_t *puc_y, int stride_y, 
  275.   uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  276.   uint8_t *puc_out, int width_y, int height_y,
  277. unsigned int stride_out) 
  278. int y;
  279. uint8_t* puc_out2;
  280. unsigned int stride_diff = 4 * stride_out - 2 * width_y; 
  281. if (height_y < 0) {
  282. height_y  = -height_y;
  283. puc_y     += (height_y   - 1) * stride_y ;
  284. puc_u     += (height_y/2 - 1) * stride_uv;
  285. puc_v     += (height_y/2 - 1) * stride_uv;
  286. stride_y  = -stride_y;
  287. stride_uv = -stride_uv;
  288. }
  289. puc_out2 = puc_out + 2 * stride_out;
  290. for (y=height_y/2; y; y--) {
  291. register uint8_t *py, *py2, *pu, *pv;
  292. register int x;
  293. uint32_t tmp;
  294. py = puc_y;
  295. py2 = puc_y + stride_y;
  296. pu = puc_u;
  297. pv = puc_v;
  298. for (x=width_y/2; x; x--) {
  299. tmp = *(py++);
  300. tmp |= *(pu++) << 8;
  301. tmp |= *(py++) << 16;
  302. tmp |= *(pv++) << 24;
  303. *(uint32_t*)puc_out=tmp;
  304. puc_out += 4;
  305. tmp &= 0xFF00FF00;
  306. tmp |= *(py2++);
  307. tmp |= *(py2++) << 16;
  308. *(uint32_t*)puc_out2=tmp;
  309. puc_out2 += 4;
  310. }
  311. puc_y += 2*stride_y;
  312. puc_u += stride_uv;
  313. puc_v += stride_uv;
  314. puc_out += stride_diff;
  315. puc_out2 += stride_diff;
  316. }
  317. }
  318. void uyvy_out(uint8_t *puc_y, int stride_y, 
  319.   uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  320.   uint8_t *puc_out, int width_y, int height_y,
  321. unsigned int stride_out) 
  322. int y;
  323. uint8_t* puc_out2;
  324. unsigned int stride_diff = 4 * stride_out - 2 * width_y; 
  325. if (height_y < 0) {
  326. height_y  = -height_y;
  327. puc_y     += (height_y   - 1) * stride_y ;
  328. puc_u     += (height_y/2 - 1) * stride_uv;
  329. puc_v     += (height_y/2 - 1) * stride_uv;
  330. stride_y  = -stride_y;
  331. stride_uv = -stride_uv;
  332. }
  333. puc_out2 = puc_out + 2 * stride_out;
  334. for (y=height_y/2; y; y--) {
  335. register uint8_t *py, *py2, *pu, *pv;
  336. register int x;
  337. uint32_t tmp;
  338. py = puc_y;
  339. py2 = puc_y + stride_y;
  340. pu = puc_u;
  341. pv = puc_v;
  342. for (x=width_y/2; x; x--) {
  343. tmp = *(pu++);
  344. tmp |= *(py++) << 8;
  345. tmp |= *(pv++) << 16;
  346. tmp |= *(py++) << 24;
  347. *(uint32_t*)puc_out=tmp;
  348. puc_out += 4;
  349. tmp &= 0x00FF00FF;
  350. tmp |= *(py2++) << 8;
  351. tmp |= *(py2++) << 24;
  352. *(uint32_t*)puc_out2=tmp;
  353. puc_out2 += 4;
  354. }
  355. puc_y += 2*stride_y;
  356. puc_u += stride_uv;
  357. puc_v += stride_uv;
  358. puc_out += stride_diff;
  359. puc_out2 += stride_diff;
  360. }
  361. }
  362. void yuv12_out(uint8_t *puc_y, int stride_y, 
  363.   uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  364.   uint8_t *puc_out, int width_y, int height_y,
  365. unsigned int stride_out) 
  366. int i;
  367. unsigned char * pauc_out[3];
  368. if (height_y < 0) {
  369. height_y = -height_y;
  370. puc_y     += (height_y   - 1) * stride_y ;
  371. puc_u     += (height_y/2 - 1) * stride_uv;
  372. puc_v     += (height_y/2 - 1) * stride_uv;
  373. stride_y  = -stride_y;
  374. stride_uv = -stride_uv;
  375. }
  376. pauc_out[0] = puc_out;
  377. pauc_out[1] = puc_out + stride_out * height_y;
  378. pauc_out[2] = puc_out + stride_out * height_y * 5 / 4;
  379. for (i=0; i<height_y; i++) {
  380. memcpy(pauc_out[0], puc_y, width_y);
  381. pauc_out[0] += stride_out;
  382. puc_y += stride_y;
  383. }
  384. for (i=0; i<height_y/2; i++) {
  385. memcpy(pauc_out[2], puc_u, width_y/2); 
  386. memcpy(pauc_out[1], puc_v, width_y/2);
  387. pauc_out[1] += stride_out/2;
  388. pauc_out[2] += stride_out/2;
  389. puc_u += stride_uv;
  390. puc_v += stride_uv;
  391. }
  392. }