---笨笨周---

-- 执子之手,与子偕老;死生契阔,与子相悦。 --

   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  2 随笔 :: 0 文章 :: 1 评论 :: 0 Trackbacks
  1
  2/************************************************************************/
  3/* 普通模式的alpha混合       */
  4/************************************************************************/
  5void NormalAlphaBlend(
  6    unsigned long*    lpDst,        // 目标缓冲
  7    unsigned long    iDstX,        // 目标位置
  8    unsigned long    iDstY,        // 目标位置
  9    unsigned long    iDstPitch,    // 目标缓冲的pitch
 10    unsigned long*    lpSrc,        // 原色彩缓冲
 11    unsigned long    iSrcX,        // 原色彩位置
 12    unsigned long    iSrcY,        // 原色彩位置
 13    unsigned long    iSrcW,        // 原缓冲的尺寸
 14    unsigned long    iSrcH,        // 原缓冲的尺寸
 15    unsigned long    iSrcPitch    // 原色彩pitch
 16    )
 17{
 18    // 需要是4的倍数
 19    unsigned long *lpLinearDstBp=(iDstX)+(iDstY*iDstPitch/sizeof(DWORD))+lpDst; //base pointer for linear destination
 20    unsigned long *lpLinearSrcBp=(iSrcX)+(iSrcY*iSrcPitch/sizeof(DWORD))+lpSrc; //base pointer for linear source
 21
 22    __asm
 23        mov esi,lpLinearSrcBp;                    // 移入源像素缓冲地址
 24
 25        mov edi,lpLinearDstBp;                    // 移入目标像素缓冲地址
 26
 27        mov ecx,iSrcH;                            // 下面两步操作是移入原缓冲的高度和宽度
 28
 29        mov ebx,iSrcW;
 30
 31MainLoop:
 32        pxor mm2,mm2                            // 把MM2清0
 33
 34        movd mm0,[esi]                            // 把Source像素取到mm0低32bit
 35
 36        movd mm1,[edi]                            // 把32 bit Dest像素取到mm1低32bit
 37
 38        punpcklbw mm0,mm2                        // Source:8 bit到16 bit以容纳结果,32bit expand to 64 bit
 39
 40        punpcklbw mm1,mm2                        // Dest:8 bit到16 bit以容纳结果.32bit expand to 64 bit
 41
 42        movq mm3,mm0                            // 因为要用Src的Alpha值
 43
 44        punpckhwd mm3,mm3                        // 高字移动到双字
 45
 46        punpckhdq mm3,mm3                        // 双字移动到四字,现在有八个像素的Alpha了!
 47        
 48        movd edx,mm3    
 49
 50        cmp  edx,0x00ff00ff;                    // 判断alpha值是否为255
 51
 52        je  CopySrc;                            // 如果为255 那么拷贝源像素,不做alpha处理
 53
 54        test edx,0xffffffff;                    // 如果alpha为0 ,那么会影响寄存器的标志位,ZF=1
 55
 56        jz BeginPixel;                            // ZF=1,转至标号处执,如果alpha为0 那么读取下一个像素
 57
 58        //R(C)=alpha*R(B)/255+(255-alpha)/255*R(A) = ((R(B)-R(A))*alpha+R(A)*255)/255
 59        // 显示颜色 = 源颜色 × alpha / 255 + 背景颜色 × (255 - alpha) / 255
 60
 61        psubusw mm0,mm1                            // Source-Dest,饱和减,小于0为0
 62
 63        pmullw mm0,mm3                            // Alpha * (Source-Overlay)
 64        
 65        psllw mm1,8                                // 左移动8位 目标*255
 66
 67        paddusw mm1,mm0                            // 饱和加到原图象D=S-Alpha*(S-O),(Overlay-Source)>0 部分
 68
 69        psrlw mm1,8                                // 右移动8位 混合结果/255
 70
 71        packuswb mm1,mm1                        // 紧缩到低32bit
 72
 73        movd [edi],mm1                            // 保存结果
 74
 75        jmp BeginPixel
 76
 77CopySrc:
 78        packuswb  mm0, mm0                        // 紧缩到低
 79
 80        movd [edi],mm0;                            // 将源像素移动到目标像素中
 81
 82BeginPixel:
 83        add edi,4;                                // 目标像素向前移动4个像素
 84
 85        add esi,4;                                 // 源像素向前移动4个像素    
 86
 87        sub ebx,1;                                 // 宽度减4
 88
 89        test ebx,0xFFFFFFFF;                    // check if only 0 pixels left
 90
 91        jz NextLine;                            // 如果只有0个像素,跳转到NextLine处理
 92
 93        jmp MainLoop;                            // 跳转到开始处,重新计算
 94
 95NextLine:
 96        dec ecx;
 97
 98        jz  Done;                                // 处理完成
 99
100        mov esi,lpLinearSrcBp;                    // src
101
102        mov edi,lpLinearDstBp;                    // dst
103
104        add esi,iSrcPitch;                        // inc src ptr by 1 line
105
106        add edi,iDstPitch;                        // inc dst ptr by 1 line
107
108        mov ebx,iSrcW;                            // ebx=span width to copy
109
110        mov lpLinearSrcBp,esi;                    // save new src base ptr
111
112        mov lpLinearDstBp,edi;                    // save new dst base ptr
113
114        jmp MainLoop;                            // start the next span
115Done:
116        emms                                    // 必要的!Empty MMX Status
117    }
 
118



  说明: 上面的代码参考过网上的示例,经过自己的修改! 如果效率不好的地方 请多多指教!
posted on 2011-03-21 15:14 ---笨笨周--- 阅读(902) 评论(1)  编辑 收藏 引用

评论

# re: 32 MMX Alpha混合算法 2013-09-11 00:49 有课
61 psubusw mm0,mm1 // Source-Dest,饱和
67 paddusw mm1,mm0 // 饱和加到原图象D=S-Alpha*(S-O),(Overlay-Source)>0 部分

确定是饱和加减么  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理