您的位置:首页 > 编程语言

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

2013-08-05 15:23 127 查看
转自: http://www.cnblogs.com/chuncn/archive/2009/03/31/1425646.html

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: