it seems that "Contract All" for the function _ASM_ImageBlur doesn't work properly:
Code: Select all
Function _ASM_ImageBlur(pImage As Any Ptr, iRadius As Integer, iExpandEdge As Integer = 0) As Any Ptr
'By Eukalyptus / modified by D.J. Peters aka Joshy
Dim As Long iW, iH, iPX, iPitch
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)
Dim As Integer iWidth = iw, iHeight = iH
Dim As Integer iPitchBlur
Dim As Long iPitchBlur_tmp
Imageinfo(pImgBlur, , , , iPitchBlur_tmp, pDataBlur)
Imageinfo(pImgTmp, , , , , pDataTmp)
If pImgBlur = 0 Orelse pImgTmp = 0 Then
Imagedestroy(pImgBlur)
Imagedestroy(pImgTmp)
Return 0
End If
iPitchBlur = iPitchBlur_tmp
If iExpandEdge <> 0 Then
Put pImgBlur, (iRadius, iRadius), pImage, Alpha
Else
Put pImgBlur, (0, 0), pImage, Alpha
End If
#Ifndef __Fb_64bit__
#Define REG_SIZE 4
#Define REG_ACCESS DWORD
#Define REG_AX eax
#Define REG_BX ebx
#Define REG_CX ecx
#Define REG_DX edx
#Define REG_DI edi
#Define REG_SI esi
#Define REG_SP esp
#Define REG_BP ebp
#Else
#Define REG_SIZE 8
#Define REG_ACCESS QWORD
#Define REG_AX rax
#Define REG_BX rbx
#Define REG_CX rcx
#Define REG_DX rdx
#Define REG_DI rdi
#Define REG_SI rsi
#Define REG_SP rsp
#Define REG_BP rbp
#Endif
#Define LOCAL_VAR_SPACE 16*REG_SIZE
'esp/rsp = [X] [Y] [W] [H] [Stride] [R] [pDst] [pSrc] [pDstO] [pSrcO]
#Define X_OFF [REG_SP]
#Define Y_OFF [REG_SP+1*REG_SIZE]
#Define W_OFF [REG_SP+2*REG_SIZE]
#Define H_OFF [REG_SP+3*REG_SIZE]
#Define S_OFF [REG_SP+4*REG_SIZE]
#Define R_OFF [REG_SP+5*REG_SIZE]
#Define DST_OFF [REG_SP+6*REG_SIZE]
#Define SRC_OFF [REG_SP+7*REG_SIZE]
#Define DSTO_OFF [REG_SP+8*REG_SIZE]
#Define SRCO_OFF [REG_SP+9*REG_SIZE]
Asm
mov REG_CX, [iWidth]
mov REG_BX, [iHeight]
mov REG_DX, [iPitchBlur]
mov REG_DI, [pDataTmp]
mov REG_SI, [pDataBlur]
mov REG_AX, [iRadius]
inc REG_AX
push REG_BP
mov REG_BP, REG_AX
Sub REG_SP, LOCAL_VAR_SPACE
mov W_OFF, REG_CX
mov H_OFF, REG_BX
mov S_OFF, REG_DX
mov R_OFF, REG_BP
mov DST_OFF, REG_DI
mov DSTO_OFF, REG_DI
mov SRC_OFF, REG_SI
mov SRCO_OFF, REG_SI
mov REG_AX, 0x47000000 'ByteToFloat MSK
movd xmm7, REG_AX
pshufd xmm7, xmm7, 0
' ####################################################
' # W-Loop
' ####################################################
mov REG_BX, H_OFF
mov Y_OFF, REG_BX
_Blur_LoopW:
mov REG_DI, DST_OFF
mov REG_SI, SRC_OFF
mov REG_DX, S_OFF 'Stride
Add REG_ACCESS Ptr DST_OFF, 4 'Next RowCol(Transform vertical<->horizontal)
Add SRC_OFF, REG_DX 'Next Row
mov REG_DX, H_OFF 'Y-Stride
Shl REG_DX, 2
pxor xmm6, xmm6 'Reset In-Out
pxor xmm5, xmm5 'Reset Sum
pxor xmm4, xmm4 'UnPack
mov REG_AX, 0 'Reset SumDiv
mov REG_BX, 0 'Reset DivInc
' ----------------------------------------------------
' | X-In += Next
' ----------------------------------------------------
mov REG_BP, 0 'Offset
mov REG_CX, R_OFF 'iR
_Blur_LoopX_In:
movd xmm0, [REG_SI+REG_BP]
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 REG_BX, 1 'SumDivInc += 1
Add REG_AX, REG_BX 'SumDiv += Inc
Add REG_BP, 4
Sub REG_CX, 1
jg _Blur_LoopX_In
' ----------------------------------------------------
' | XIn += Next / XIn -= Mid / XOut += Mid
' ----------------------------------------------------
mov REG_CX, R_OFF 'iR
_Blur_LoopX_InOut:
cvtsi2ss xmm3, REG_AX
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 [REG_DI], xmm0
movd xmm0, [REG_SI+REG_BP]
movd xmm1, [REG_SI]
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 REG_BX, 1 'SumDivInc += 1
Add REG_AX, REG_BX 'SumDiv += Inc
Add REG_SI, 4
Add REG_DI, REG_DX
Sub REG_CX, 1
jg _Blur_LoopX_InOut
cvtsi2ss xmm3, REG_AX
rcpss xmm3, xmm3
pshufd xmm3, xmm3, 0 'SumDiv
mov REG_BX, REG_BP
neg REG_BX 'Last Index
' ----------------------------------------------------
' | XIn += Next / XIn -= Mid / XOut += Mid / XOut -= Last
' ----------------------------------------------------
mov REG_CX, W_OFF 'iWidth
Sub REG_CX, R_OFF
Sub REG_CX, R_OFF
_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 [REG_DI], xmm0
movd xmm0,[REG_SI+REG_BP]
movd xmm1,[REG_SI]
movd xmm2,[REG_SI+REG_BX]
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 REG_SI, 4
Add REG_DI, REG_DX
Sub REG_CX, 1
jg _Blur_LoopX
' ----------------------------------------------------
' | XIn -= Mid / XOut += Mid / XOut -= Last
' ----------------------------------------------------
mov REG_BP, 0 'DivInc
mov REG_CX, R_OFF 'iR
_Blur_LoopX_Out:
cvtsi2ss xmm3, REG_AX
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 [REG_DI], xmm0
movd xmm0, [REG_SI]
movd xmm1, [REG_SI+REG_BX]
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 REG_BP, 1
Sub REG_AX, REG_BP
Add REG_SI, 4
Add REG_DI, REG_DX
Sub REG_CX, 1
jg _Blur_LoopX_Out
Sub REG_ACCESS Ptr Y_OFF, 1
jg _Blur_LoopW
' ####################################################
' # H-Loop
' ####################################################
mov REG_DI, SRCO_OFF
mov REG_SI, DSTO_OFF
mov DST_OFF, REG_DI
mov SRC_OFF, REG_SI
mov REG_BX, W_OFF
mov X_OFF, REG_BX
_Blur_LoopH:
mov REG_DI, DST_OFF
mov REG_SI, SRC_OFF
mov REG_DX, H_OFF
Shl REG_DX, 2
Add REG_ACCESS Ptr DST_OFF, 4 'Next Col
Add SRC_OFF, REG_DX 'Next ColRow
mov REG_DX, S_OFF 'Stride
pxor xmm6, xmm6 'Reset In-Out
pxor xmm5, xmm5 'Reset Sum
pxor xmm4, xmm4 'UnPack
mov REG_AX, 0 'Reset SumDiv
mov REG_BX, 0 'Reset DivInc
' ----------------------------------------------------
' | X-In += Next
' ----------------------------------------------------
mov REG_BP, 0 'Offset
mov REG_CX, R_OFF 'iR
_Blur_LoopY_In:
movd xmm0, [REG_SI+REG_BP]
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 REG_BX, 1 'SumDivInc += 1
Add REG_AX, REG_BX 'SumDiv += Inc
Add REG_BP, 4
Sub REG_CX, 1
jg _Blur_LoopY_In
' ----------------------------------------------------
' | XIn += Next / XIn -= Mid / XOut += Mid
' ----------------------------------------------------
mov REG_CX, R_OFF 'iR
_Blur_LoopY_InOut:
cvtsi2ss xmm3, REG_AX
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 [REG_DI], xmm0
movd xmm0, [REG_SI+REG_BP]
movd xmm1, [REG_SI]
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 REG_BX, 1 'SumDivInc += 1
Add REG_AX, REG_BX 'SumDiv += Inc
Add REG_SI, 4
Add REG_DI, REG_DX
Sub REG_CX, 1
jg _Blur_LoopY_InOut
cvtsi2ss xmm3, REG_AX
rcpss xmm3, xmm3
pshufd xmm3, xmm3, 0 'SumDiv
mov REG_BX, REG_BP
neg REG_BX 'Last Index
' ----------------------------------------------------
' | XIn += Next / XIn -= Mid / XOut += Mid / XOut -= Last
' ----------------------------------------------------
mov REG_CX, H_OFF 'iHeight
Sub REG_CX, R_OFF
Sub REG_CX, R_OFF
_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 [REG_DI], xmm0
movd xmm0, [REG_SI+REG_BP]
movd xmm1, [REG_SI]
movd xmm2, [REG_SI+REG_BX]
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 REG_SI, 4
Add REG_DI, REG_DX
Sub REG_CX, 1
jg _Blur_LoopY
' ----------------------------------------------------
' | XIn -= Mid / XOut += Mid / XOut -= Last
' ----------------------------------------------------
mov REG_BP, 0 'DivInc
mov REG_CX, R_OFF 'iR
_Blur_LoopY_Out:
cvtsi2ss xmm3, REG_AX
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 [REG_DI], xmm0
movd xmm0, [REG_SI]
movd xmm1, [REG_SI+REG_BX]
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 REG_BP, 1
Sub REG_AX, REG_BP
Add REG_SI, 4
Add REG_DI, REG_DX
Sub REG_CX, 1
jg _Blur_LoopY_Out
Sub REG_ACCESS Ptr X_OFF, 1
jg _Blur_LoopH
Add REG_SP, LOCAL_VAR_SPACE
pop REG_BP
End Asm
Imagedestroy(pImgTmp)
Return pImgBlur
End Function
Sub ImageContrast(pImage as any Pointer, contrast as Integer, brightness as Integer = 0, iW As Ushort, iH As Ushort)
#Define Red(colour) ((colors Shr 16) And 255)
#Define Green(colour) ((colors Shr 8) And 255)
#Define Blue(colour) (colors And 255)
#Define Truncate(colour) (Iif(colour < 0, 0, Iif(colour > 255, 255, CUbyte(colour))))
Dim as Ulong colors
Dim As Integer w, h, pitch
Dim As Any Pointer pixdata
Imageinfo(pImage, w, h, , pitch, pixdata)
Dim as Single factor, contrastLevel = (((100.0 + contrast) / 100.0) * ((100.0 + contrast) / 100.0))
For y as UShort = 0 to iH - 1
For x as Ushort = 0 to iW - 1
colors = *CPtr(ULong ptr, pixdata + y * pitch + x Shl 2)
*CPtr(ULong ptr, pixdata + y * pitch + x Shl 2) = RGB(Truncate(brightness + (((Red(colour) / 255 - 0.5) * contrastLevel) + 0.5) * 255.0), _
Truncate(brightness + (((Green(colour) / 255 - 0.5) * contrastLevel) + 0.5) * 255.0), _
Truncate(brightness + (((Blue(colour) / 255 - 0.5) * contrastLevel) + 0.5) * 255.0))
Next
Next
End Sub
? "Contract All"
If you contract all then the next functions will be hidden. I know that it might be difficult because of the ASM commands which uses also FB.
Thx.