convert.cpp
上传用户:panstart
上传日期:2022-04-12
资源大小:199k
文件大小:5k
源码类别:

IP电话/视频会议

开发平台:

C++ Builder

  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. //    Project     : VideoNet version 1.1.
  5. //    Description : Peer to Peer Video Conferencing over the LAN.
  6. //   Author      : Nagareshwar Y Talekar ( nsry2002@yahoo.co.in)
  7. //    Date        : 15-6-2004.
  8. //
  9. //
  10. //    File description : 
  11. //    Name    : convert.cpp
  12. //    Details : Conversion routine from RGB24 to YUV420 & YUV420 to RGB24.
  13. //
  14. /////////////////////////////////////////////////////////////////////////////
  15. #include "convert.h"
  16. // Conversion from RGB to YUV420
  17. int RGB2YUV_YR[256], RGB2YUV_YG[256], RGB2YUV_YB[256];
  18. int RGB2YUV_UR[256], RGB2YUV_UG[256], RGB2YUV_UBVR[256];
  19. int RGB2YUV_VG[256], RGB2YUV_VB[256];
  20. // Conversion from YUV420 to RGB24
  21. static long int crv_tab[256];
  22. static long int cbu_tab[256];
  23. static long int cgu_tab[256];
  24. static long int cgv_tab[256];
  25. static long int tab_76309[256];
  26. static unsigned char clp[1024]; //for clip in CCIR601
  27. //
  28. // Table used for RGB to YUV420 conversion
  29. //
  30. void InitLookupTable()
  31. {
  32. int i;
  33. for (i = 0; i < 256; i++) RGB2YUV_YR[i] = (float)65.481 * (i<<8);
  34. for (i = 0; i < 256; i++) RGB2YUV_YG[i] = (float)128.553 * (i<<8);
  35. for (i = 0; i < 256; i++) RGB2YUV_YB[i] = (float)24.966 * (i<<8);
  36. for (i = 0; i < 256; i++) RGB2YUV_UR[i] = (float)37.797 * (i<<8);
  37. for (i = 0; i < 256; i++) RGB2YUV_UG[i] = (float)74.203 * (i<<8);
  38. for (i = 0; i < 256; i++) RGB2YUV_VG[i] = (float)93.786 * (i<<8);
  39. for (i = 0; i < 256; i++) RGB2YUV_VB[i] = (float)18.214 * (i<<8);
  40. for (i = 0; i < 256; i++) RGB2YUV_UBVR[i] = (float)112 * (i<<8);
  41. }
  42. //
  43. //  Convert from  RGB24 to YUV420
  44. //
  45. int ConvertRGB2YUV(int w,int h,unsigned char *bmp,unsigned int *yuv)
  46. {
  47. unsigned int *u,*v,*y,*uu,*vv;
  48. unsigned int *pu1,*pu2,*pu3,*pu4;
  49. unsigned int *pv1,*pv2,*pv3,*pv4;
  50. unsigned char *r,*g,*b;
  51. int i,j;
  52. uu=new unsigned int[w*h];
  53. vv=new unsigned int[w*h];
  54. if(uu==NULL || vv==NULL)
  55. return 0;
  56. y=yuv;
  57. u=uu;
  58. v=vv;
  59. // Get r,g,b pointers from bmp image data....
  60. r=bmp;
  61. g=bmp+1;
  62. b=bmp+2;
  63. //Get YUV values for rgb values...
  64. for(i=0;i<h;i++)
  65. {
  66. for(j=0;j<w;j++)
  67. {
  68. *y++=( RGB2YUV_YR[*r]  +RGB2YUV_YG[*g]+RGB2YUV_YB[*b]+1048576)>>16;
  69. *u++=(-RGB2YUV_UR[*r]  -RGB2YUV_UG[*g]+RGB2YUV_UBVR[*b]+8388608)>>16;
  70. *v++=( RGB2YUV_UBVR[*r]-RGB2YUV_VG[*g]-RGB2YUV_VB[*b]+8388608)>>16;
  71. r+=3;
  72. g+=3;
  73. b+=3;
  74. }
  75. }
  76. // Now sample the U & V to obtain YUV 4:2:0 format
  77. // Sampling mechanism...
  78. /*   @  ->  Y
  79.   #  ->  U or V
  80.   
  81.   @   @   @   @
  82. #       #
  83.   @   @   @   @
  84.   @   @   @   @
  85. #       #
  86.   @   @   @   @
  87. */
  88. // Get the right pointers...
  89. u=yuv+w*h;
  90. v=u+(w*h)/4;
  91. // For U
  92. pu1=uu;
  93. pu2=pu1+1;
  94. pu3=pu1+w;
  95. pu4=pu3+1;
  96. // For V
  97. pv1=vv;
  98. pv2=pv1+1;
  99. pv3=pv1+w;
  100. pv4=pv3+1;
  101. // Do sampling....
  102. for(i=0;i<h;i+=2)
  103. {
  104. for(j=0;j<w;j+=2)
  105. {
  106. *u++=(*pu1+*pu2+*pu3+*pu4)>>2;
  107. *v++=(*pv1+*pv2+*pv3+*pv4)>>2;
  108. pu1+=2;
  109. pu2+=2;
  110. pu3+=2;
  111. pu4+=2;
  112. pv1+=2;
  113. pv2+=2;
  114. pv3+=2;
  115. pv4+=2;
  116. }
  117. pu1+=w;
  118. pu2+=w;
  119. pu3+=w;
  120. pu4+=w;
  121. pv1+=w;
  122. pv2+=w;
  123. pv3+=w;
  124. pv4+=w;
  125. }
  126. delete uu;
  127. delete vv;
  128. return 1;
  129. }
  130. //
  131. //Initialize conversion table for YUV420 to RGB
  132. //
  133. void InitConvertTable()
  134. {
  135.    long int crv,cbu,cgu,cgv;
  136.    int i,ind;   
  137.      
  138.    crv = 104597; cbu = 132201;  /* fra matrise i global.h */
  139.    cgu = 25675;  cgv = 53279;
  140.   
  141.    for (i = 0; i < 256; i++) {
  142.       crv_tab[i] = (i-128) * crv;
  143.       cbu_tab[i] = (i-128) * cbu;
  144.       cgu_tab[i] = (i-128) * cgu;
  145.       cgv_tab[i] = (i-128) * cgv;
  146.       tab_76309[i] = 76309*(i-16);
  147.    }
  148.  
  149.    for (i=0; i<384; i++)
  150.   clp[i] =0;
  151.    ind=384;
  152.    for (i=0;i<256; i++)
  153.    clp[ind++]=i;
  154.    ind=640;
  155.    for (i=0;i<384;i++)
  156.    clp[ind++]=255;
  157. }
  158. //
  159. //  Convert from YUV420 to RGB24
  160. //
  161. void ConvertYUV2RGB(unsigned char *src0,unsigned char *src1,unsigned char *src2,unsigned char *dst_ori,
  162.  int width,int height)
  163. {
  164. int y1,y2,u,v; 
  165. unsigned char *py1,*py2;
  166. int i,j, c1, c2, c3, c4;
  167. unsigned char *d1, *d2;
  168. py1=src0;
  169. py2=py1+width;
  170. d1=dst_ori;
  171. d2=d1+3*width;
  172.   for (j = 0; j < height; j += 2) { 
  173. for (i = 0; i < width; i += 2) {
  174. u = *src1++;
  175. v = *src2++;
  176. c1 = crv_tab[v];
  177. c2 = cgu_tab[u];
  178. c3 = cgv_tab[v];
  179. c4 = cbu_tab[u];
  180. //up-left
  181.             y1 = tab_76309[*py1++];
  182. *d1++ = clp[384+((y1 + c1)>>16)];  
  183. *d1++ = clp[384+((y1 - c2 - c3)>>16)];
  184.             *d1++ = clp[384+((y1 + c4)>>16)];
  185. //down-left
  186. y2 = tab_76309[*py2++];
  187. *d2++ = clp[384+((y2 + c1)>>16)];  
  188. *d2++ = clp[384+((y2 - c2 - c3)>>16)];
  189.             *d2++ = clp[384+((y2 + c4)>>16)];
  190. //up-right
  191. y1 = tab_76309[*py1++];
  192. *d1++ = clp[384+((y1 + c1)>>16)];  
  193. *d1++ = clp[384+((y1 - c2 - c3)>>16)];
  194. *d1++ = clp[384+((y1 + c4)>>16)];
  195. //down-right
  196. y2 = tab_76309[*py2++];
  197. *d2++ = clp[384+((y2 + c1)>>16)];  
  198. *d2++ = clp[384+((y2 - c2 - c3)>>16)];
  199.             *d2++ = clp[384+((y2 + c4)>>16)];
  200. }
  201. d1 += 3*width;
  202. d2 += 3*width;
  203. py1+=   width;
  204. py2+=   width;
  205. }       
  206. }