yuv420argb.c
上传用户:jylinhe
上传日期:2022-07-11
资源大小:334k
文件大小:6k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. // yuv4202rgba.cpp : Defines the entry point for the console application.
  2. #include "yuv420argb.h"
  3. static long int crv_tab[256];
  4. static long int cbu_tab[256];
  5. static long int cgu_tab[256];
  6. static long int cgv_tab[256];
  7. static long int tab_76309[256];
  8. static unsigned char clp[1024];
  9. static unsigned __int64 mmw_mult_Y    = 0x2568256825682568;
  10. static unsigned __int64 mmw_mult_U_G  = 0xf36ef36ef36ef36e;
  11. static unsigned __int64 mmw_mult_U_B  = 0x40cf40cf40cf40cf;
  12. static unsigned __int64 mmw_mult_V_R  = 0x3343334333433343;
  13. static unsigned __int64 mmw_mult_V_G  = 0xe5e2e5e2e5e2e5e2;
  14. static unsigned __int64 mmb_0x10      = 0x1010101010101010;
  15. static unsigned __int64 mmw_0x0080    = 0x0080008000800080;
  16. static unsigned __int64 mmw_0x00ff    = 0x00ff00ff00ff00ff;
  17. void init_dither_tab()
  18. {
  19. int i,ind;
  20. long crv,cbu,cgu,cgv;
  21. static int inited = 0;
  22.     
  23. if (inited != 0)
  24. return;
  25.     
  26. inited = 1;
  27. crv = 104597; cbu = 132201; 
  28. cgu = 25675;  cgv = 53279;
  29. for (i = 0; i < 256; i++) 
  30. {
  31. crv_tab[i] = (i-128) * crv;
  32. cbu_tab[i] = (i-128) * cbu;
  33. cgu_tab[i] = (i-128) * cgu;
  34. cgv_tab[i] = (i-128) * cgv;
  35. tab_76309[i] = 76309*(i-16);
  36. }
  37. for (i=0; i<384; i++)
  38. clp[i] =0;
  39. ind=384;
  40. for (i=0;i<256; i++)
  41. clp[ind++]=i;
  42. ind=640;
  43. for (i=0;i<384;i++)
  44. clp[ind++]=255;
  45. }
  46. int YUV420ToARGB32( unsigned char *src0,
  47. unsigned char *src1,
  48. unsigned char *src2,
  49. int stride_y,
  50. int stride_u,
  51. int stride_v,
  52. unsigned char *dst_ori,
  53. int width,
  54. int height,
  55. int out_stride )
  56. {    
  57. int i,j,c1,c2,c3,c4;
  58. int y1,y2,u,v; 
  59. unsigned char *py0,*py1,*pu,*pv;
  60. unsigned char *d1, *d2;
  61. py0 = src0;
  62. py1 = src0+stride_y;
  63. pu = src1;
  64. pv = src2;
  65. d1 = dst_ori;
  66. d2 = dst_ori+out_stride;
  67. for (j = 0; j < height; j += 2) 
  68. for (i = 0; i < width; i += 2) 
  69. {
  70. u = *pu++;
  71. v = *pv++;
  72. c1 = crv_tab[v];
  73. c2 = cgu_tab[u];
  74. c3 = cgv_tab[v];
  75. c4 = cbu_tab[u];
  76. //up-left
  77. y1 = tab_76309[*py0++];    
  78. *d1++ = clp[384+((y1 + c4)>>16)];
  79. *d1++ = clp[384+((y1 - c2 - c3)>>16)];
  80. *d1++ = clp[384+((y1 + c1)>>16)];
  81. *d1++ = 0;
  82. //down-left
  83. y2 = tab_76309[*py1++];
  84. *d2++ = clp[384+((y2 + c4)>>16)];
  85. *d2++ = clp[384+((y2 - c2 - c3)>>16)];
  86. *d2++ = clp[384+((y2 + c1)>>16)];  
  87. *d2++ = 0;
  88. //up-right
  89. y1 = tab_76309[*py0++];
  90. *d1++ = clp[384+((y1 + c4)>>16)];
  91. *d1++ = clp[384+((y1 - c2 - c3)>>16)];
  92. *d1++ = clp[384+((y1 + c1)>>16)];  
  93. *d1++ = 0;
  94. //down-right
  95. y2 = tab_76309[*py1++];
  96. *d2++ = clp[384+((y2 + c4)>>16)];
  97. *d2++ = clp[384+((y2 - c2 - c3)>>16)];
  98. *d2++ = clp[384+((y2 + c1)>>16)];  
  99. *d2++ = 0;
  100. }
  101. d1 += out_stride;
  102. d2 += out_stride;
  103. src0 += stride_y*2;
  104. py0 = src0;
  105. py1 = src0+stride_y;
  106. src1 += stride_u;
  107. src2 += stride_v;
  108. pu = src1;
  109. pv = src2;
  110. }
  111. return 1;
  112. }
  113. int YUV420_TO_ARGB32_MMX( unsigned char *puc_y,     
  114. int stride_y, 
  115. unsigned char *puc_u,     
  116. unsigned char *puc_v,
  117. int stride_u,
  118. int stride_v,
  119. unsigned char *puc_out,
  120. int out_width,    
  121. int out_height,
  122. int out_stride ) 
  123. {
  124. //unsigned char temp;
  125. int y, horiz_count;
  126. horiz_count = -(out_width >> 3);
  127. for (y=0; y<out_height; y++) 
  128. {
  129. __asm
  130. {
  131. push eax
  132. push ebx
  133. push ecx
  134. push edx
  135. push edi
  136. mov eax, puc_out
  137. mov ebx, puc_y
  138. mov ecx, puc_u
  139. mov edx, puc_v
  140. mov edi, horiz_count
  141. horiz_loop:
  142. movd mm2, [ecx]
  143. pxor mm7, mm7
  144. movd mm3, [edx]
  145. punpcklbw mm2, mm7       
  146. movq mm0, [ebx]          
  147. punpcklbw mm3, mm7       
  148. movq mm1, mmw_0x00ff     
  149. psubusb mm0, mmb_0x10    
  150. psubw mm2, mmw_0x0080    
  151. pand mm1, mm0            
  152. psubw mm3, mmw_0x0080    
  153. psllw mm1, 3             
  154. psrlw mm0, 8             
  155. psllw mm2, 3             
  156. pmulhw mm1, mmw_mult_Y   
  157. psllw mm0, 3             
  158. psllw mm3, 3             
  159. movq mm5, mm3            
  160. pmulhw mm5, mmw_mult_V_R 
  161. movq mm4, mm2            
  162. pmulhw mm0, mmw_mult_Y   
  163. movq mm7, mm1            
  164. pmulhw mm2, mmw_mult_U_G 
  165. paddsw mm7, mm5
  166. pmulhw mm3, mmw_mult_V_G
  167. packuswb mm7, mm7
  168. pmulhw mm4, mmw_mult_U_B
  169. paddsw mm5, mm0      
  170. packuswb mm5, mm5
  171. paddsw mm2, mm3          
  172. movq mm3, mm1            
  173. movq mm6, mm1            
  174. paddsw mm3, mm4
  175. paddsw mm6, mm2
  176. punpcklbw mm7, mm5
  177. paddsw mm2, mm0
  178. packuswb mm6, mm6
  179. packuswb mm2, mm2
  180. packuswb mm3, mm3
  181. paddsw mm4, mm0
  182. packuswb mm4, mm4
  183. punpcklbw mm6, mm2
  184. punpcklbw mm3, mm4
  185. // 32-bit shuffle.
  186. pxor mm0, mm0
  187. movq mm1, mm6
  188. punpcklbw mm1, mm0
  189. movq mm0, mm3
  190. punpcklbw mm0, mm7
  191. movq mm2, mm0
  192. punpcklbw mm0, mm1
  193. punpckhbw mm2, mm1
  194. // 24-bit shuffle and sav
  195. movd   [eax], mm0
  196. psrlq mm0, 32
  197. movd 4[eax], mm0
  198. movd 8[eax], mm2
  199. psrlq mm2, 32
  200. movd  12[eax], mm2        
  201. // 32-bit shuffle.
  202. pxor mm0, mm0            
  203. movq mm1, mm6            
  204. punpckhbw mm1, mm0       
  205. movq mm0, mm3            
  206. punpckhbw mm0, mm7       
  207. movq mm2, mm0            
  208. punpcklbw mm0, mm1       
  209. punpckhbw mm2, mm1       
  210. // 24-bit shuffle and sav
  211. movd 16[eax], mm0        
  212. psrlq mm0, 32            
  213. movd 20[eax], mm0        
  214. add ebx, 8               
  215. movd 24[eax], mm2        
  216. psrlq mm2, 32            
  217. add ecx, 4               
  218. add edx, 4               
  219. movd 28[eax], mm2
  220. add eax, 32              
  221. inc edi
  222. jne horiz_loop
  223. pop edi
  224. pop edx
  225. pop ecx
  226. pop ebx
  227. pop eax
  228. emms
  229. }
  230. puc_out += out_stride;
  231. puc_y += stride_y;
  232. if (y%2) 
  233. {
  234. puc_u   += stride_u;
  235. puc_v   += stride_v;
  236. }
  237. }
  238. return 1;
  239. }