Assembly code snippets

Back to the snippets overview

Details

TitleComposite blend (AlphaBlend API replacement) (MMX)
AuthorbitRAKE
Submitted by:Qweerdy
Date added:2003-01-03 14:02:39
Date modified:2003-01-03 14:02:39

Comments

This proc blends a 32-bit bitmap with an alpha channel onto another one. Unlike the other MMX alphablend snippet, this snippet also produces correct alpha values in the destination bitmap. To use this proc, the two bitmaps must have been "pre-multiplied". To do this you can use the Pre-multiply snippet.

Snippet

CompositeBlend proc USES ebx esi edi,  hSrcBm:DWORD,srcx:DWORD,srcy:DWORD,srcw:DWORD,srch:DWORD,hDstBm:DWORD,dstx:DWORD,dsty:DWORD
    LOCAL bmsrc:BITMAP
    LOCAL bmdst:BITMAP

    invoke GetObject,hSrcBm,sizeof bmsrc,addr bmsrc
    invoke GetObject,hDstBm,sizeof bmdst,addr bmdst

    mov edx, bmdst.bmHeight
    mov eax, bmdst.bmWidth
    sub edx, srch
    mov edi, bmdst.bmBits
    sub edx, dsty
    mul edx
    add eax, dstx
    lea edi, [edi + eax*4]

    mov edx, bmsrc.bmHeight
    mov eax, bmsrc.bmWidth
    sub edx, srch
    mov esi, bmsrc.bmBits
    sub edx, srcy
    mul edx
    add eax, srcx
    lea esi, [esi + eax*4]

    shr srcw, 1
    dec srcw
    shl bmsrc.bmWidth, 2
    shl bmdst.bmWidth, 2

    Top EQU <esi + ecx*8>
    Bottom  EQU <edi + ecx*8>
    Destination EQU <Bottom>

    pxor        mm7, mm7
    pcmpeqd     mm6, mm6

; -- PreMultiplied Alpha --
; H = result color (y, yr, yg, yb)
; F = top color (a, ar, ag, ab)
; G = bottom color (b, br, bg, bb)
;
; Composite: H = (1-b)F + G

BlendLoop:
    mov ecx, srcw

IFDEF __MMX_PLUS__

_0: movq        mm1, [Bottom]       ; 8 bits per component
    movq        mm0, [Top]
    movq        mm2, mm1
    punpcklbw   mm1, mm7
    punpckhbw   mm2, mm7
    pshufw      mm4, mm0, 11111111y
    pshufw      mm5, mm0, 01010101y
    pxor        mm4, mm6
    pxor        mm5, mm6
    pmulhuw     mm1, mm4
    pmulhuw     mm2, mm5
    packuswb    mm2, mm1
    paddusb     mm2, mm0
    movq        [Destination], mm2
ELSE

_0: movq        mm1, [Bottom]       ; 8 bits per component
    movq        mm0, [Top]
    movq        mm2, mm1

    punpcklbw   mm1, mm7
    punpckhbw   mm2, mm7

    movq        mm4, mm0
    pxor        mm4, mm6
    psrlw       mm4, 8
    movq        mm5, mm4

    punpcklwd   mm4, mm4
    punpckhwd   mm5, mm5
    punpckhdq   mm4, mm4
    punpckhdq   mm5, mm5

    pmullw      mm1, mm4
    pmullw      mm2, mm5

    psrlw       mm1, 8
    psrlw       mm2, 8

    packuswb    mm1, mm2
    paddusb     mm1, mm0

    movq        [Destination], mm1
ENDIF
    dec ecx
    jns _0

    add esi, bmsrc.bmWidth
    add edi, bmdst.bmWidth
    dec srch
    jnz BlendLoop

    ret
CompositeBlend endp