Apparemment, pour utiliser la "pile" , je dois réserver une zone mémoire puis "pointer" la "pile" dessus.
Code : Tout sélectionner
;EnableExplicit
;-------------------------------------------------------------------------------
UseJPEGImageDecoder()
UsePNGImageDecoder()
;-- http://blog.ivank.net/fastest-gaussian-blur.html
;Procedure boxesForGauss(sigma, n) ; standard deviation, number of boxes
;wIdeal = Math.sqrt((12*sigma*sigma/n)+1); // Ideal averaging filter width
;wl = floor(wIdeal)
;If(wl%2==0) wl--
;wu = wl+2
;mIdeal = (12*sigma*sigma - n*wl*wl - 4*n*wl - 3*n)/(-4*wl - 4)
;m = Math.round(mIdeal)
;var sizes = []
;For(var i=0 To 2
;(i<m?wl:wu);
;Next
;Return sizes
;EndProcedure
Procedure boxBlurH_4(source, cible, lg, ht, opt)
Protected r,g,b , r1,g1,b1 , r2,g2,b2 , d.f,d2.f , var ,y,x , pos
Protected np , var1,var2,var3 , s
Dim save.q(20) ; 20*64bits = 10*128bits (5 registres 128bits + 5 registres 64bits)
Dim d2.f(opt)
Dim pix.l(4)
np=@pix()
s=@save()
For i=0 To opt
d2(i)=1/(i+opt)
Next
d.f=1/(opt+opt+1)
For y=0 To ht-1
pos=source+(lg*y*4)
; flou sur la partie gauche de l'image ( de 0 a opt )
r=0:g=0:b=0
For x=0 To (opt*2)
var=PeekL(pos+x*4)
b1=Red(var) : g1=Green(var) : r1=Blue(var)
r=r+r1 : g=g+g1 : b=b+b1
Next
r2=r:g2=g:b2=b
For x=opt To 0 Step -1
var=PeekL(pos+(x+opt)*4)
b1=Red(var) : g1=Green(var) : r1=Blue(var)
r=r-r1 : g=g-g1 : b=b-b1
r1=r*d2(x) : g1=g*d2(x) : b1=b*d2(x)
PokeL(cible+(lg*y+x)*4,(r1<<16)+(g1<<8)+b1)
Next
; flou sur la partie central de l'image ( de opt a lg-opt )
pos=source+(lg*y*4)
pix(0)=b2:pix(1)=g2:pix(2)=r2
x=opt+1
var1=(pos+(x-opt-1)*4)
var2=(pos+(x+opt)*4)
var3=(cible+(lg*y+x)*4)
EnableASM
; partie a modifier pour utiliser la "pile"
; push/pop ne fonctionnent pas avec les registre mmx
;ASSUME SS:segment_pile
;MOV AX, segment_pile
;MOV SS, AX ; initialise le segment de pile
;MOV SP, base_pile ; copie l'adresse de la base de la pile dans SP
!mov rax,[p.v_s]
!movdqu [rax],xmm0
!movdqu [rax+16],xmm1
!movdqu [rax+32],xmm2
!movdqu [rax+48],xmm3
!movdqu [rax+64],xmm15
!mov [rax+80],r8
!mov [rax+88],r9
!mov [rax+96],r12
!mov [rax+112],rdx
!mov [rax+120],rcx
!mov r8,[p.v_var1]
!mov r9,[p.v_var2]
!mov r12,[p.v_var3]
!pxor xmm15,xmm15
!VPBROADCASTD xmm3,[p.v_d]
!mov rax,[p.v_np]
!movdqu xmm2,[rax]
!mov rcx,[p.v_opt] ;For x=opt+1
!inc rcx
!mov rdx,[p.v_lg] ;To lg-opt-1
!sub rdx,[p.v_opt]
!dec rdx
!boxBlurH_saut1:
!movd xmm0,[r8] ;var=PeekL(pos+(x-opt-1)*4)
!punpcklbw xmm0,xmm15 ;RGBReturn(var,r1,g1,b1)
!punpcklwd xmm0,xmm15
!movd xmm1,[r9] ;var=PeekL(pos+(x+opt)*4)
!punpcklbw xmm1,xmm15 ;RGBReturn(var,r2,g2,b2)
!punpcklwd xmm1,xmm15
!psubd xmm2,xmm0 ; r=r-r1
!paddd xmm2,xmm1 ; r=r+r2
!movdqu xmm0,xmm2
!cvtdq2ps xmm0,xmm0
!mulps xmm0,xmm3 ;r1=r*d : d = 1/(opt+opt+1)
!cvtps2dq xmm0,xmm0
!packusdw xmm0,xmm15
!packuswb xmm0,xmm15
!movd [r12],xmm0 ;PokeL(cible+(lg*y+x)*4,(r1<<16)+(g1<<8)+b1)
!add r8,4
!add r9,4
!add r12,4
!inc rcx
!cmp rcx,rdx
!jbe boxBlurH_saut1
!mov rax,[p.v_s]
!movdqu xmm0,[rax]
!movdqu xmm1,[rax+16]
!movdqu xmm2,[rax+32]
!movdqu xmm3,[rax+48]
!movdqu xmm15,[rax+64]
!mov r8,[rax+80]
!mov r9,[rax+88]
!mov r12,[rax+96]
!mov rdx,[rax+112]
!mov rcx,[rax+120]
DisableASM
;flou sur la partie droite de l'image ( de lg-opt a lg )
r=0:g=0:b=0
For x=lg-(opt*2) To lg-1
var=PeekL(pos+x*4)
b1=Red(var) : g1=Green(var) : r1=Blue(var)
r=r+r1 : g=g+g1 : b=b+b1
Next
compt=opt-1
For x=lg-opt To lg-1
var=PeekL(pos+(x-opt)*4)
b1=Red(var) : g1=Green(var) : r1=Blue(var)
r=r-r1 : g=g-g1 : b=b-b1
r1=r*d2(lg-x-1) : g1=g*d2(lg-x-1) : b1=b*d2(lg-x-1)
PokeL(cible+(lg*y+x)*4,(r1<<16)+(g1<<8)+b1)
compt=compt-1
Next
Next
FreeArray(pix())
FreeArray(d2())
FreeArray(save())
EndProcedure
Procedure boxBlurT_4(source, cible, lg, ht, opt)
Protected r,g,b , r1,g1,b1 , r2,g2,b2 , d.f,d2.f , var ,y,x , pos
Protected np , var1,var2,var3 , var4 , s
Dim save.q(20)
Dim d2.f(opt)
Dim pix.l(4)
np=@pix()
s=@save()
For i=0 To opt
d2(i)=1/(i+opt)
Next
d.f=1/(opt+opt+1)
For x=0 To lg-1
r=0:g=0:b=0
For y=0 To (opt*2)
var=PeekL(source+(y*lg+x)*4)
b1=Red(var) : g1=Green(var) : r1=Blue(var)
r=r+r1 : g=g+g1 : b=b+b1
Next
r2=r:g2=g:b2=b
For y=opt To 0 Step -1
var=PeekL(source+(y*lg+x)*4)
b1=Red(var) : g1=Green(var) : r1=Blue(var)
r=r-r1 : g=g-g1 : b=b-b1
r1=r*d2(y) : g1=g*d2(y) : b1=b*d2(y)
PokeL(cible+(lg*y+x)*4,(r1<<16)+(g1<<8)+b1)
Next
pix(0)=b2:pix(1)=g2:pix(2)=r2
y=opt+1
var1=(source+((y-opt-1)*lg+x)*4)
var2=(source+((y+opt)*lg+x)*4)
var3=(cible+(lg*y+x)*4)
var4=lg*4
EnableASM
!mov rax,[p.v_s]
!movdqu [rax],xmm0
!movdqu [rax+16],xmm1
!movdqu [rax+32],xmm2
!movdqu [rax+48],xmm3
!movdqu [rax+64],xmm15
!mov [rax+80],r8
!mov [rax+88],r9
!mov [rax+96],r12
!mov [rax+104],r13
!mov [rax+112],rdx
!mov [rax+120],rcx
!mov r8,[p.v_var1]
!mov r9,[p.v_var2]
!mov r12,[p.v_var3]
!mov r13,[p.v_var4]
!pxor xmm15,xmm15
!VPBROADCASTD xmm2,[p.v_d]
!mov rax,[p.v_np]
!movdqu xmm3,[rax]
!mov rcx,[p.v_opt] ;For y=opt+1
!inc rcx
!mov rdx,[p.v_ht] ;to ht-opt-1
!sub rdx,[p.v_opt]
!dec rdx
!boxBlurT_saut1:
!movd xmm0,[r8] ;var=PeekL(pos+(x-opt-1)*4)
!punpcklbw xmm0,xmm15 ;RGBReturn(var,r1,g1,b1)
!punpcklwd xmm0,xmm15
!movd xmm1,[r9] ;var=PeekL(pos+(x+opt)*4)
!punpcklbw xmm1,xmm15 ;RGBReturn(var,r2,g2,b2)
!punpcklwd xmm1,xmm15
!psubd xmm3,xmm0 ; r=r-r1
!paddd xmm3,xmm1 ; r=r+r2
!movdqu xmm0,xmm3
!cvtdq2ps xmm0,xmm0
!mulps xmm0,xmm2 ;r1=r*d : d = 1/(opt+opt+1)
!cvtps2dq xmm0,xmm0
!packusdw xmm0,xmm15
!packuswb xmm0,xmm15
!movd [r12],xmm0 ;PokeL(cible+(lg*y+x)*4,(r1<<16)+(g1<<8)+b1)
!add r8,r13
!add r9,r13
!add r12,r13
!inc rcx
!cmp rcx,rdx
!jbe boxBlurT_saut1
!mov rax,[p.v_s]
!movdqu xmm0,[rax]
!movdqu xmm1,[rax+16]
!movdqu xmm2,[rax+32]
!movdqu xmm3,[rax+48]
!movdqu xmm15,[rax+64]
!mov r8,[rax+80]
!mov r9,[rax+88]
!mov r12,[rax+96]
!mov r13,[rax+104]
!mov rdx,[rax+112]
!mov rcx,[rax+120]
DisableASM
r=0:g=0:b=0
For y=ht-(opt*2) To ht-1
var=PeekL(source+(lg*y+x)*4)
b1=Red(var):g1=Green(var):r1=Blue(var)
r=r+r1 : g=g+g1 :b=b+b1
Next
For y=ht-opt To ht-1
var=PeekL(source+((y-opt)*lg+x)*4)
b1=Red(var) : g1=Green(var) : r1=Blue(var)
r=r-r1 : g=g-g1 : b=b-b1
r1=r*d2(ht-y-1) : g1=g*d2(ht-y-1) : b1=b*d2(ht-y-1)
PokeL(cible+(lg*y+x)*4,(r1<<16)+(g1<<8)+b1)
Next
Next
FreeArray(pix())
FreeArray(d2())
FreeArray(save())
EndProcedure
Procedure boxBlur_4 (source, cible, lg, ht, r)
CopyMemory(source, cible, lg*ht*4)
boxblurT_4(cible,source,lg,ht,r) ; passe horizontal
boxBlurH_4(source,cible,lg,ht,r) ; passe vertical
EndProcedure
Procedure Filter_GaussBlur(source,cible,r)
Protected lg,ht,bit,source2,taille
ht = ImageHeight(source)
lg = ImageWidth(source)
If lg>ht
If r>=(ht/2):r=(ht/2)-1:EndIf
Else
If r>=(lg/2):r=(lg/2)-1:EndIf
EndIf
If r<1:r=1:EndIf
StartDrawing(ImageOutput(source))
source=DrawingBuffer()
bit=OutputDepth()
StopDrawing()
StartDrawing(ImageOutput(cible))
cible=DrawingBuffer()
StopDrawing()
taille=lg*ht*4
source2=AllocateMemory(taille)
If bit=32
CopyMemory(source, source2, taille)
Else
Dim save.q(4)
s=@save()
EnableASM
!mov rax,[p.v_s]
!mov [rax],rcx
!mov [rax+8],rdx
!mov [rax+16],r8
!mov rcx,[p.v_source]
!mov rdx,[p.v_source2]
!mov r8,[p.v_taille]
!shr r8,2
!copy_boucle24:
!mov eax,[rcx]
!mov [rdx],eax
!add rcx,3
!add rdx,4
!dec r8
!jnz copy_boucle24
!mov rax,[p.v_s]
!mov rcx,[rax]
!mov rdx, [rax+8]
!mov r8,[rax+16]
DisableASM
FreeArray(save())
EndIf
;r()=boxesForGauss(sigma, n) ; partie a ajouter pour avoir un meilleur rendu
boxBlur_4(source2, cible, lg, ht, r) ; passe 1
boxBlur_4(cible, source2, lg, ht, r) ; passe 2
boxBlur_4(source2, cible, lg, ht, r) ; passe 3
FreeMemory(source2)
EndProcedure
Global imgx=1200
Global imgy=800
If OpenWindow(0, 0, 0, imgx+50, imgy+50, "PixLab", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
pic$ = OpenFileRequester("Image indexe",pic$,"",0)
source=10
cible=20
If pic$ <> ""
If LoadImage(source,pic$)
ResizeImage(source,imgx,imgy,#PB_Image_Smooth)
Else
End
EndIf
Else
End
EndIf
CreateImage(cible,imgx,imgy,32)
t.q=ElapsedMilliseconds()
Filter_GaussBlur(source,cible,5)
t1.q=ElapsedMilliseconds()-t
StartDrawing(WindowOutput(0))
DrawImage(ImageID(cible),0,0)
DrawText(5,5,Str(t1))
StopDrawing()
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
;-------------------------------------------------------------------------------