Assembly code snippets
Details
Title | Composite blend (AlphaBlend API replacement) (MMX) |
---|---|
Author | bitRAKE |
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
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