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

权当练手了,效果不好,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处理的明显不一样嘛

posted @ 2013-03-16 13:48  Dsp Tian  阅读(700)  评论(0编辑  收藏  举报