Eukalyptus
Anmeldungsdatum: 17.05.2013 Beiträge: 11
|
Verfasst am: 20.08.2016, 23:17 Titel: ASM Blur |
|
|
Hier noch eine Blur-Variante.
Bei kleinen Blur-Radien langsamer als andere Funktionen, jedoch sehr schnell bei immer größeren Blur-Radien.
Mousemove = Blurradius
Mouseclick = ExpandEdge On/Off
wers noch etwas schneller braucht: die temporären Images müssten nicht jedesmal neu erstellt werden...
Code: | #Include "fbgfx.bi"
using fb
Function ImageBlur(pImage As Any Ptr, iRadius As Long, iExpandEdge As Long = 0) As Any Ptr
'By Eukalyptus
Dim As Integer iW, iH, iPX, iPitch, iPitchBlur
Dim As Any Ptr pData, pDataBlur, pDataTmp
If ImageInfo(pImage, iW, iH, iPX, iPitch, pData) <> 0 Then Return 0
If iPX <> 4 Then Return 0
If iRadius < 0 Then
iRadius = 0
ElseIf iRadius > 127 Then
iRadius = 127
EndIf
Dim As Any Ptr pImgBlur, pImgTmp
If iExpandEdge <> 0 Then
iW += iRadius * 2
iH += iRadius * 2
EndIf
pImgBlur = ImageCreate(iW, iH, 0, 32)
pImgTmp = ImageCreate(iW, iH, 0, 32)
ImageInfo(pImgBlur, , , , iPitchBlur, pDataBlur)
ImageInfo(pImgTmp, , , , , pDataTmp)
If pImgBlur = 0 Or pImgTmp = 0 Then
ImageDestroy(pImgBlur)
ImageDestroy(pImgTmp)
Return 0
EndIf
If iExpandEdge <> 0 Then
Put pImgBlur, (iRadius, iRadius), pImage, Alpha
Else
Put pImgBlur, (0, 0), pImage, Alpha
EndIf
Asm
mov ecx, [iW]
mov ebx, [iH]
mov edx, [iPitchBlur]
mov edi, [pDataTmp]
mov esi, [pDataBlur]
mov eax, [iRadius]
inc eax
push ebp
mov ebp, eax
sub esp, 64
mov [esp+8], ecx
mov [esp+12], ebx
mov [esp+16], edx
mov [esp+20], ebp
mov [esp+24], edi
mov [esp+32], edi
mov [esp+28], esi
mov [esp+36], esi
' 0 4 8 12 16 20 24 28 32 36
'esp = [X] [Y] [W] [H] [Stride] [R] [pDst] [pSrc] [pDstO] [pSrcO]
mov eax, 0x47000000 'ByteToFloat MSK
movd xmm7, eax
pshufd xmm7, xmm7, 0
' ####################################################
' # W-Loop
' ####################################################
mov ebx, [esp+12]
mov [esp+4], ebx
_Blur_LoopW:
mov edi, [esp+24]
mov esi, [esp+28]
mov edx, [esp+16] 'Stride
add dword ptr[esp+24], 4 'next RowCol(Transform vertical<->horizontal)
add [esp+28], edx 'next Row
mov edx, [esp+12] 'Y-Stride
shl edx, 2
pxor xmm6, xmm6 'Reset In-Out
pxor xmm5, xmm5 'Reset Sum
/'
xmm7 = Msk
xmm6 = [AO][RO][GO][BO][AI][RI][GI][BI]
xmm5 = [AS][RS][GS][BS]
eax = (SumDiv)
ebx = (DivInc)
ecx = X
edx = Stride
esi = Src
edi = Dst
ebp = R
'/
pxor xmm4, xmm4 'UnPack
mov eax, 0 'Reset SumDiv
mov ebx, 0 'Reset DivInc
' ----------------------------------------------------
' | X-In += Next
' ----------------------------------------------------
mov ebp, 0 'Offset
mov ecx, [esp+20] 'iR
_Blur_LoopX_In:
movd xmm0, [esi+ebp]
punpcklbw xmm0, xmm4 '[ ][ ][ ][ ][An][Rn][Gn][Bn] Next
paddw xmm6, xmm0 'IN+=Next
movdqa xmm0, xmm6
punpcklwd xmm0, xmm4 '[AI][RI][GI][BI]
paddd xmm5, xmm0 'Stack += IN
add ebx, 1 'SumDivInc += 1
add eax, ebx 'SumDiv += Inc
add ebp, 4
sub ecx, 1
jg _Blur_LoopX_In
' ----------------------------------------------------
' | XIn += Next / XIn -= Mid / XOut += Mid
' ----------------------------------------------------
mov ecx, [esp+20] 'iR
_Blur_LoopX_InOut:
cvtsi2ss xmm3, eax
rcpss xmm3, xmm3
pshufd xmm3, xmm3, 0 'SumDiv
movdqa xmm0, xmm5
paddd xmm0, xmm7 ' UByte -> Float
subps xmm0, xmm7 '/
mulps xmm0, xmm3
addps xmm0, xmm7 ' Float -> UByte
psubd xmm0, xmm7 '/
packssdw xmm0, xmm0 '[A][R][G][B][A][R][G][B]
packuswb xmm0, xmm0 '[ARGB][ARGB][ARGB][ARGB]
movd [edi], xmm0
movd xmm0, [esi+ebp]
movd xmm1, [esi]
punpcklbw xmm0, xmm4 '[ ][ ][ ][ ][An][Rn][Gn][Bn] Next
punpcklbw xmm1, xmm4 '[ ][ ][ ][ ][Am][Rm][Gm][Bm] Mid
movlhps xmm0, xmm1 '[Am][Rm][Gm][Bm][An][Rn][Gn][Bn] = [Mid][Next]
paddw xmm6, xmm0 'OUT+=Mid / IN+=Next
psubw xmm6, xmm1 '(OUT-=Last) / IN-=Mid
movdqa xmm1, xmm6
movdqa xmm0, xmm6
punpckhwd xmm1, xmm4 '[AO][RO][GO][BO]
punpcklwd xmm0, xmm4 '[AI][RI][GI][BI]
psubd xmm5, xmm1 'Stack -= OUT
paddd xmm5, xmm0 'Stack += IN
sub ebx, 1 'SumDivInc += 1
add eax, ebx 'SumDiv += Inc
add esi, 4
add edi, edx
sub ecx, 1
jg _Blur_LoopX_InOut
cvtsi2ss xmm3, eax
rcpss xmm3, xmm3
pshufd xmm3, xmm3, 0 'SumDiv
mov ebx, ebp
neg ebx 'Last Index
' ----------------------------------------------------
' | XIn += Next / XIn -= Mid / XOut += Mid / XOut -= Last
' ----------------------------------------------------
mov ecx, [esp+8] 'iW
sub ecx, [esp+20]
sub ecx, [esp+20]
_Blur_LoopX:
movdqa xmm0, xmm5
paddd xmm0, xmm7 ' UByte -> Float
subps xmm0, xmm7 '/
mulps xmm0, xmm3
addps xmm0, xmm7 ' Float -> UByte
psubd xmm0, xmm7 '/
packssdw xmm0, xmm0 '[A][R][G][B][A][R][G][B]
packuswb xmm0, xmm0 '[ARGB][ARGB][ARGB][ARGB]
movd [edi], xmm0
movd xmm0, [esi+ebp]
movd xmm1, [esi]
movd xmm2, [esi+ebx]
punpcklbw xmm0, xmm4 '[ ][ ][ ][ ][An][Rn][Gn][Bn] Next
punpcklbw xmm1, xmm4 '[ ][ ][ ][ ][Am][Rm][Gm][Bm] Mid
punpcklbw xmm2, xmm4 '[ ][ ][ ][ ][Al][Rl][Gl][Bl] Last
movlhps xmm0, xmm1 '[Am][Rm][Gm][Bm][An][Rn][Gn][Bn] = [Mid][Next]
movlhps xmm1, xmm2 '[Al][Rl][Gl][Bl][Ao][Ro][Go][Bo] = [Last][Mid]
paddw xmm6, xmm0 'OUT+=Mid / IN+=Next
psubw xmm6, xmm1 'OUT-=Last / IN-=Mid
movdqa xmm1, xmm6
movdqa xmm0, xmm6
punpckhwd xmm1, xmm4 '[AO][RO][GO][BO]
punpcklwd xmm0, xmm4 '[AI][RI][GI][BI]
psubd xmm5, xmm1 'Stack -= OUT
paddd xmm5, xmm0 'Stack += IN
add esi, 4
add edi, edx
sub ecx, 1
jg _Blur_LoopX
' ----------------------------------------------------
' | XIn -= Mid / XOut += Mid / XOut -= Last
' ----------------------------------------------------
mov ebp, 0 'DivInc
mov ecx, [esp+20] 'iR
_Blur_LoopX_Out:
cvtsi2ss xmm3, eax
rcpss xmm3, xmm3
pshufd xmm3, xmm3, 0 'SumDiv
movdqa xmm0, xmm5
paddd xmm0, xmm7 ' UByte -> Float
subps xmm0, xmm7 '/
mulps xmm0, xmm3
addps xmm0, xmm7 ' Float -> UByte
psubd xmm0, xmm7 '/
packssdw xmm0, xmm0 '[A][R][G][B][A][R][G][B]
packuswb xmm0, xmm0 '[ARGB][ARGB][ARGB][ARGB]
movd [edi], xmm0
movd xmm0, [esi]
movd xmm1, [esi+ebx]
punpcklbw xmm0, xmm4 '[ ][ ][ ][ ][Am][Rm][Gm][Bm] Mid
punpcklbw xmm1, xmm4 '[ ][ ][ ][ ][Al][Rl][Gl][Bl] Last
movlhps xmm0, xmm1 '[Al][Rl][Gl][Bl][Am][Rm][Gm][Bm] = [Last][Mid]
psubw xmm6, xmm0 'OUT-=Last / IN-=Mid
pslldq xmm0, 8
paddw xmm6, xmm0 'OUT+=Mid / (IN+=Next)
movdqa xmm1, xmm6
movdqa xmm0, xmm6
punpckhwd xmm1, xmm4 '[AO][RO][GO][BO]
punpcklwd xmm0, xmm4 '[AI][RI][GI][BI]
psubd xmm5, xmm1 'Stack -= OUT
paddd xmm5, xmm0 'Stack += IN
add ebp, 1
sub eax, ebp
add esi, 4
add edi, edx
sub ecx, 1
jg _Blur_LoopX_Out
sub dword ptr[esp+4], 1
jg _Blur_LoopW
' ####################################################
' # H-Loop
' ####################################################
mov edi, [esp+36]
mov esi, [esp+32]
mov [esp+24], edi
mov [esp+28], esi
mov ebx, [esp+8]
mov [esp], ebx
_Blur_LoopH:
mov edi, [esp+24]
mov esi, [esp+28]
mov edx, [esp+12]
Shl edx, 2
Add dword ptr[esp+24], 4 'next Col
Add [esp+28], edx 'next ColRow
mov edx, [esp+16] 'Stride
pxor xmm6, xmm6 'Reset In-Out
pxor xmm5, xmm5 'Reset Sum
/'
xmm7 = Msk
xmm6 = [AO][RO][GO][BO][AI][RI][GI][BI]
xmm5 = [AS][RS][GS][BS]
eax = (SumDiv)
ebx = (DivInc)
ecx = X
edx = Stride
esi = Src
edi = Dst
ebp = R
'/
pxor xmm4, xmm4 'UnPack
mov eax, 0 'Reset SumDiv
mov ebx, 0 'Reset DivInc
' ----------------------------------------------------
' | X-In += Next
' ----------------------------------------------------
mov ebp, 0 'Offset
mov ecx, [esp+20] 'iR
_Blur_LoopY_In:
movd xmm0, [esi+ebp]
punpcklbw xmm0, xmm4 '[ ][ ][ ][ ][An][Rn][Gn][Bn] Next
paddw xmm6, xmm0 'IN+=Next
movdqa xmm0, xmm6
punpcklwd xmm0, xmm4 '[AI][RI][GI][BI]
paddd xmm5, xmm0 'Stack += IN
Add ebx, 1 'SumDivInc += 1
Add eax, ebx 'SumDiv += Inc
Add ebp, 4
Sub ecx, 1
jg _Blur_LoopY_In
' ----------------------------------------------------
' | XIn += Next / XIn -= Mid / XOut += Mid
' ----------------------------------------------------
mov ecx, [esp+20] 'iR
_Blur_LoopY_InOut:
cvtsi2ss xmm3, eax
rcpss xmm3, xmm3
pshufd xmm3, xmm3, 0 'SumDiv
movdqa xmm0, xmm5
paddd xmm0, xmm7 ' UByte -> Float
subps xmm0, xmm7 '/
mulps xmm0, xmm3
addps xmm0, xmm7 ' Float -> UByte
psubd xmm0, xmm7 '/
packssdw xmm0, xmm0 '[A][R][G][B][A][R][G][B]
packuswb xmm0, xmm0 '[ARGB][ARGB][ARGB][ARGB]
movd [edi], xmm0
movd xmm0, [esi+ebp]
movd xmm1, [esi]
punpcklbw xmm0, xmm4 '[ ][ ][ ][ ][An][Rn][Gn][Bn] Next
punpcklbw xmm1, xmm4 '[ ][ ][ ][ ][Am][Rm][Gm][Bm] Mid
movlhps xmm0, xmm1 '[Am][Rm][Gm][Bm][An][Rn][Gn][Bn] = [Mid][Next]
paddw xmm6, xmm0 'OUT+=Mid / IN+=Next
psubw xmm6, xmm1 '(OUT-=Last) / IN-=Mid
movdqa xmm1, xmm6
movdqa xmm0, xmm6
punpckhwd xmm1, xmm4 '[AO][RO][GO][BO]
punpcklwd xmm0, xmm4 '[AI][RI][GI][BI]
psubd xmm5, xmm1 'Stack -= OUT
paddd xmm5, xmm0 'Stack += IN
Sub ebx, 1 'SumDivInc += 1
Add eax, ebx 'SumDiv += Inc
Add esi, 4
Add edi, edx
Sub ecx, 1
jg _Blur_LoopY_InOut
cvtsi2ss xmm3, eax
rcpss xmm3, xmm3
pshufd xmm3, xmm3, 0 'SumDiv
mov ebx, ebp
neg ebx 'Last Index
' ----------------------------------------------------
' | XIn += Next / XIn -= Mid / XOut += Mid / XOut -= Last
' ----------------------------------------------------
mov ecx, [esp+12] 'iH
Sub ecx, [esp+20]
Sub ecx, [esp+20]
_Blur_LoopY:
movdqa xmm0, xmm5
paddd xmm0, xmm7 ' UByte -> Float
subps xmm0, xmm7 '/
mulps xmm0, xmm3
addps xmm0, xmm7 ' Float -> UByte
psubd xmm0, xmm7 '/
packssdw xmm0, xmm0 '[A][R][G][B][A][R][G][B]
packuswb xmm0, xmm0 '[ARGB][ARGB][ARGB][ARGB]
movd [edi], xmm0
movd xmm0, [esi+ebp]
movd xmm1, [esi]
movd xmm2, [esi+ebx]
punpcklbw xmm0, xmm4 '[ ][ ][ ][ ][An][Rn][Gn][Bn] Next
punpcklbw xmm1, xmm4 '[ ][ ][ ][ ][Am][Rm][Gm][Bm] Mid
punpcklbw xmm2, xmm4 '[ ][ ][ ][ ][Al][Rl][Gl][Bl] Last
movlhps xmm0, xmm1 '[Am][Rm][Gm][Bm][An][Rn][Gn][Bn] = [Mid][Next]
movlhps xmm1, xmm2 '[Al][Rl][Gl][Bl][Ao][Ro][Go][Bo] = [Last][Mid]
paddw xmm6, xmm0 'OUT+=Mid / IN+=Next
psubw xmm6, xmm1 'OUT-=Last / IN-=Mid
movdqa xmm1, xmm6
movdqa xmm0, xmm6
punpckhwd xmm1, xmm4 '[AO][RO][GO][BO]
punpcklwd xmm0, xmm4 '[AI][RI][GI][BI]
psubd xmm5, xmm1 'Stack -= OUT
paddd xmm5, xmm0 'Stack += IN
Add esi, 4
Add edi, edx
Sub ecx, 1
jg _Blur_LoopY
' ----------------------------------------------------
' | XIn -= Mid / XOut += Mid / XOut -= Last
' ----------------------------------------------------
mov ebp, 0 'DivInc
mov ecx, [esp+20] 'iR
_Blur_LoopY_Out:
cvtsi2ss xmm3, eax
rcpss xmm3, xmm3
pshufd xmm3, xmm3, 0 'SumDiv
movdqa xmm0, xmm5
paddd xmm0, xmm7 ' UByte -> Float
subps xmm0, xmm7 '/
mulps xmm0, xmm3
addps xmm0, xmm7 ' Float -> UByte
psubd xmm0, xmm7 '/
packssdw xmm0, xmm0 '[A][R][G][B][A][R][G][B]
packuswb xmm0, xmm0 '[ARGB][ARGB][ARGB][ARGB]
movd [edi], xmm0
movd xmm0, [esi]
movd xmm1, [esi+ebx]
punpcklbw xmm0, xmm4 '[ ][ ][ ][ ][Am][Rm][Gm][Bm] Mid
punpcklbw xmm1, xmm4 '[ ][ ][ ][ ][Al][Rl][Gl][Bl] Last
movlhps xmm0, xmm1 '[Al][Rl][Gl][Bl][Am][Rm][Gm][Bm] = [Last][Mid]
psubw xmm6, xmm0 'OUT-=Last / IN-=Mid
pslldq xmm0, 8
paddw xmm6, xmm0 'OUT+=Mid / (IN+=Next)
movdqa xmm1, xmm6
movdqa xmm0, xmm6
punpckhwd xmm1, xmm4 '[AO][RO][GO][BO]
punpcklwd xmm0, xmm4 '[AI][RI][GI][BI]
psubd xmm5, xmm1 'Stack -= OUT
paddd xmm5, xmm0 'Stack += IN
Add ebp, 1
Sub eax, ebp
Add esi, 4
Add edi, edx
Sub ecx, 1
jg _Blur_LoopY_Out
Sub dword Ptr[esp], 1
jg _Blur_LoopH
add esp, 64
pop ebp
End Asm
ImageDestroy(pImgTmp)
Return pImgBlur
End Function
Dim As EVENT tEvent
Screen 19 , 32 '800 x 600, 32bpp
Dim As Any Ptr pImage, pImgBG, pImgTmp
pImage = ImageCreate(700, 500, &hFF0000FF, 32)
pImgBG = ImageCreate(800, 600, &hFFFFFFFF, 32)
pImgTmp = ImageCreate(8, 8, &hFFCCCCCC, 32)
For y As Integer = 0 To 600 Step 8
For x As Integer = 0 To 800 Step 16
Put pImgBG, (x + (y Mod 16), y), pImgTmp, PSet
Next
Next
ImageDestroy(pImgTmp)
Dim As Integer iImgW, iImgH, iImgPX
ImageInfo(pImage, iImgW, iImgH)
pImgTmp = ImageCreate(80, 20, 0, 32)
Draw String pImgTmp, (0, 0), "FreeBasic", &hFF00FF00
For y As Integer = 0 To 19
For x As Integer = 0 To 79
If Point(x, y, pImgTmp) <> 0 Then Line pImage, (x*9+30, y*9)-(x*9+39, y*9+9), &hFF00FF00, bf
Next
Next
ImageDestroy(pImgTmp)
Line pImage, (10, 200)-(110, 400), &hFFFF0000, bf
Circle pImage, (500, 300), 160, &hFFFFCC00, , , , F
For y As Integer = 10 To iImgH - 20 Step 20
For x As Integer = 15 To iImgW Step 100
Draw String pImage, (x, y), "FreeBasic", &hFF000000 Or RGB(y / iImgH * 255, 255 - (y / iImgH * 255), 255 - (x / iImgW * 255))
Next
Next
Dim As Integer iRadius, iExpand
Dim As Any Ptr pImgBlur
Put (0, 0), pImgBG, PSet
Put (50, 50), pImage, Alpha
Do
If ScreenEvent(@tEvent) Then
Select Case tEvent.type
Case EVENT_MOUSE_MOVE, EVENT_MOUSE_BUTTON_PRESS
If tEvent.type = EVENT_MOUSE_BUTTON_PRESS Then
If iExpand = 0 Then
iExpand = 1
Else
iExpand = 0
EndIf
Else
iRadius = ((tEvent.x-50) / 700) * 127
If iRadius < 0 Then
iRadius = 0
ElseIf iRadius > 127 Then
iRadius = 127
EndIf
EndIf
pImgBlur = ImageBlur(pImage, iRadius, iExpand)
ScreenLock
Put (0, 0), pImgBG, PSet
Put (50 - iRadius * iExpand, 50 - iRadius * iExpand), pImgBlur, Alpha
Draw String (10, 10), "Blur Radius: " & iRadius & " / ExpandEdges: " & iExpand, &hFF000000
ScreenUnLock
ImageDestroy(pImgBlur)
Case SC_ESCAPE, EVENT_WINDOW_CLOSE
Exit Do
End Select
EndIf
Loop
ImageDestroy(pImgBG)
ImageDestroy(pImage)
|
|
|