各种RGB和YUV相互转换的代码

1、用查表的方法实现相互转换,代码可以参考“点对点视频会议程序VideoNet”

2、用C语言定点乘加运算实现,代码参考XviD

参考其中的ConvertYUV2RGB函数
http://hi.baidu.com/yeyingxian/blog/item/193a8882729c9dbf6d8119cd.html

http://hi.baidu.com/yeyingxian/blog/item/7bbcd8bfc8d6d20a18d81f58.html

3、MMX实现,代码参考XviD,还有libmpeg2的rgb_mmx.c
int ConvertRGB2YUV(int w,int h,unsigned char *bmp,unsigned char *yuv)
{
unsigned char *u,*v,*y;
unsigned char *r;
int i,j;
int rgbw=w*3;

short y_mul[]={66,129,25,0};
short u_mul[]={-38,-74,112,0};
short v_mul[]={112,-94,-18,0};

int Y_ADD=16;
int C_ADD=128;

y=yuv;
u=yuv+w*h;
v=u+(w*h)/4;

// Get r,g,b pointers from bmp image data....
r=bmp;

//Get YUV values for rgb values...
_asm {
   movq mm7,[y_mul]
}

for(i=0;i<h;i+=2)
{  
   for(j=0;j<w;j+=2)
   {
    _asm {
     mov edx,rgbw
     mov esi,r
     movq mm0,[esi]
     movq mm2,[esi+edx]
     pxor mm4,mm4
     pxor mm5,mm5
     punpcklbw mm0, mm4            ; [ |b |g |r ]
     punpcklbw mm2, mm5            ; [ |b |g |r ]
     movq mm6, mm0                 ; = [ |b4|g4|r4]
     paddw mm6, mm2                ; +[ |b4|g4|r4]
     pmaddwd mm0, mm7              ; *= Y_MUL
     pmaddwd mm2, mm7              ; *= Y_MUL
     movq mm4, mm0                 ; [r]
     movq mm5, mm2                 ; [r]
     psrlq mm4, 32                 ; +[g]
     psrlq mm5, 32                 ; +[g]
     paddd mm0, mm4                ; +[b]
     paddd mm2, mm5                ; +[b]
    
     movd mm1, [esi+3]            ; src[%1...]
     movd mm3, [esi+edx+3]        ; src[x_stride+%1...]
     pxor mm4, mm4
     pxor mm5, mm5
     punpcklbw mm1, mm4            ; [ |b |g |r ]
     punpcklbw mm3, mm5            ; [ |b |g |r ]
     paddw mm6, mm1                ; +[ |b4|g4|r4]
     paddw mm6, mm3                ; +[ |b4|g4|r4]
     pmaddwd mm1, mm7              ; *= Y_MUL
     pmaddwd mm3, mm7              ; *= Y_MUL
     movq mm4, mm1                 ; [r]
     movq mm5, mm3                 ; [r]
     psrlq mm4, 32                 ; +[g]
     psrlq mm5, 32                 ; +[g]
     paddd mm1, mm4                ; +[b]
     paddd mm3, mm5                ; +[b]
    
     mov edi,y
     mov ebx,u
     mov ecx,v
     mov edx,w

     movd eax, mm0
     shr eax, 8
     add eax, Y_ADD
     mov [edi], al                 ; y_ptr[0]
    
     movd eax, mm1
     shr eax, 8
     add eax, Y_ADD
     mov [edi + 1], al             ; y_ptr[1]
    
     movd eax, mm2
     shr eax, 8
     add eax, Y_ADD
     mov [edi + edx*1 + 0], al       ; y_ptr[y_stride + 0]
    
     movd eax, mm3
     shr eax, 8
     add eax, Y_ADD
     mov [edi + edx*1 + 1], al       ; y_ptr[y_stride + 1]
    
     ; u_ptr, v_ptr
     movq mm0, mm6                 ; = [ |b4|g4|r4]
     pmaddwd mm6, [v_mul]          ; *= V_MUL
     pmaddwd mm0, [u_mul]          ; *= U_MUL
     movq mm1, mm0
     movq mm2, mm6
     psrlq mm1, 32
     psrlq mm2, 32
     paddd mm0, mm1
     paddd mm2, mm6
    
     movd eax, mm0
     shr eax, 10
     add eax, C_ADD
     mov [ebx], al
    
     movd eax, mm2
     shr eax, 10
     add eax, C_ADD
     mov [ecx], al
    
     add esi, 6    ;r+=6
     add edi,2    ;y+=2
     add ebx,1    ;u+=1
     add ecx,1    ;v+=1
     mov r,esi
     mov y,edi
     mov u,ebx
     mov v,ecx
    }
   }
   r+=w*3;
   y+=w;
}  
// Get the right pointers...

return 1;
}

posted on 2009-03-31 02:53  chuncn  阅读(6065)  评论(0编辑  收藏  举报

导航