多媒体指令(图像灰度化)

权当练手了,效果不好,cpu没有提供pmulluw这样一个无符号字相乘指令。

处理的效果和matlab明显不同,尤其是背景,我实在找不出问题在哪里,最可能就在寄存器符号上。

灰度公式是:Gray = (R*76 + G*150 + B*30) >> 8

有符号范围是[-32768-32767],无符号范围是[0-65536],前者显然不够存放255*150=38250的,所以就溢出了。

提高了位宽模拟无符号相乘不行,减小运算精度也不行,开源节流都不行,让人很纠结。

反正是初学,这指令还要多练才行。

VOID asmARGB2Gray(BitmapData *data)

{

    UINT Height=data->Height;

    UINT Width=data->Width;

    Pix* p=(Pix*)data->Scan0;

    UINT n=Height*Width;



    Pix cp[]={0x014c961e};    

    __asm

    {

        push esi;



        mov ecx,n;

        pxor mm7,mm7;

        mov esi,[p];

        movd mm2,[cp];

lp:

        movq    mm1,mm2;

        movd    mm0,[esi];        //mm0:00 00 00 00 Alpha R G B

        mov        al,[esi+3];        //al:Alpha

        punpcklbw mm0,mm7;        //mm0:00 Alpha 00 R 00 G 00 B

        punpcklbw mm1,mm7;        //mm1:00 01 00 4c 00 96 00 1e



        movq        mm3,mm0;

        movq        mm5,mm1;



        //模拟 pmulluw    

        movq        mm4, mm5

        pmullw        mm5, mm3    /* a * b lo 16×16 unsigned */

        pmulhuw        mm4, mm3    /* a * b hi 16×16 unsigned */

        movq        mm6, mm5

        punpcklwd    mm5, mm4

        punpckhwd    mm6, mm4



        movq    mm0,mm5;    

        movq    mm1,mm6;    

        psrlw    mm0,8;

        psrlw    mm1,8;





        packssdw    mm0,mm0;

        packssdw    mm1,mm1;



        movd        edx,mm0;

        movd        ebx,mm1;

        shr            edx,16;



        add            dl,bl;

        shr            ebx,16;

        add            dl,bl;



        mov        [esi],  dl;

        mov        [esi+1],dl;

        mov        [esi+2],dl;



        mov        [esi+3],al;

        add esi,4;

        dec    ecx;

        jnz lp;



        pop esi;

        emms;

    }

}

效果:

多媒体指令(图像灰度化)

和matlab处理的明显不一样嘛

多媒体指令(图像灰度化)

你可能感兴趣的:(多媒体)