Code : Tout sélectionner
EnableExplicit
Global Dim Reg_memory.q(4*344)
;-------------------------------------------------------------------
; sauvegarde de registres
Macro Save_reg()
Protected s.q
s=@reg_memory()
EnableASM
!mov rax,[p.v_s]
!mov [rax+000],rbx
!mov [rax+008],rcx ;
!mov [rax+016],rdx ;
!mov [rax+024],rsi
!mov [rax+032],rdi
!mov [rax+040],r8 ;
!mov [rax+048],r9 ;
!mov [rax+056],r10
!mov [rax+064],r11
!mov [rax+072],r12
!mov [rax+080],r13
!mov [rax+088],r14
!mov [rax+096],r15
!movdqu [rax+104],xmm0 ;
!movdqu [rax+120],xmm1 ;
!movdqu [rax+136],xmm2 ;
!movdqu [rax+152],xmm3 ;
!movdqu [rax+168],xmm4
!movdqu [rax+184],xmm5
!movdqu [rax+200],xmm6
!movdqu [rax+216],xmm7
!movdqu [rax+232],xmm8
!movdqu [rax+248],xmm9
!movdqu [rax+264],xmm10
!movdqu [rax+280],xmm11
!movdqu [rax+296],xmm12
!movdqu [rax+312],xmm13
!movdqu [rax+328],xmm14
!movdqu [rax+344],xmm15
DisableASM
EndMacro
Macro Rest_Reg()
; restore les registres
s=@reg_memory()
EnableASM
!mov rax,[p.v_s]
!mov rbx,[rax+000]
!mov rcx,[rax+008]
!mov rdx,[rax+016]
!mov rsi,[rax+024]
!mov rdi,[rax+032]
!mov r8,[rax+040]
!mov r9,[rax+048]
!mov r10,[rax+056]
!mov r11,[rax+064]
!mov r12,[rax+072]
!mov r13,[rax+080]
!mov r14,[rax+088]
!mov r15,[rax+096]
!movdqu xmm0,[rax+104] ;
!movdqu xmm1,[rax+120] ;
!movdqu xmm2,[rax+136] ;
!movdqu xmm3,[rax+152] ;
!movdqu xmm4,[rax+168]
!movdqu xmm5,[rax+184]
!movdqu xmm6,[rax+200]
!movdqu xmm7,[rax+216]
!movdqu xmm8,[rax+232]
!movdqu xmm9,[rax+248]
!movdqu xmm10,[rax+264]
!movdqu xmm11,[rax+280]
!movdqu xmm12,[rax+296]
!movdqu xmm13,[rax+312]
!movdqu xmm14,[rax+328]
!movdqu xmm15,[rax+344]
DisableASM
EndMacro
; charge une image et la convertie en 32bit
;-------------------------------------------------------------------
Procedure load_image(nom,file$)
Protected source_p , cible_p , s.q
Protected lg.q , ht.q , taille.q , depth.q
LoadImage(nom,file$)
If Not IsImage(nom) : ProcedureReturn 0 : EndIf
StartDrawing(ImageOutput(nom))
source_p = DrawingBuffer()
ht = ImageHeight(nom)
lg = ImageWidth(nom)
Depth=OutputDepth()
StopDrawing()
If Depth=24
taille=lg*ht
cible_p=AllocateMemory(taille*4)
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_p]
!mov rdx,[p.v_cible_p]
!mov r8,[p.v_taille]
!sub r8,1 ; <---------------- ????
!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())
FreeImage(nom) ; supprime l'image 24bits
CreateImage(nom,lg,ht,32)
StartDrawing(ImageOutput(nom))
source_p = DrawingBuffer()
StopDrawing()
CopyMemory( cible_p , source_p , taille*4 )
FreeMemory(cible_p)
EndIf
ProcedureReturn 1
EndProcedure
; partie du programme à modifier pour adapter se programme au votre
; convertie les "IDs" des images en pointer d'adresse
; test si les images sont en 32bits et de la meme taille
;-------------------------------------------------------------------
Macro sp(source,cible)
Protected Depth.q , lg.q , ht.q , lg1.q , ht1.q , taille.q
Protected cible_p.q , source_p.q
StartDrawing(ImageOutput(cible))
cible_p = DrawingBuffer()
ht1 = ImageHeight(cible)
lg1 = ImageWidth(cible)
Depth=OutputDepth()
StopDrawing()
If depth<>32 : ProcedureReturn : EndIf
StartDrawing(ImageOutput(source))
source_p = DrawingBuffer()
ht = ImageHeight(source)
lg = ImageWidth(source)
Depth=OutputDepth()
StopDrawing()
If depth<>32 : ProcedureReturn : EndIf
If lg<>lg1 Or ht<>ht1 : ProcedureReturn : EndIf
EndMacro
;-------------------------------------------------------------------
;--version purebasic
Procedure Filter_Rotate_pb(source,cible,angle)
Protected degres.f , c1.f , s1.f , x3.f , y3.f
Protected x.l , y.l, xx.l , yy.l , var.l
Protected pos.q
sp(source,cible)
degres.f=angle*#PI/180
c1.f=Cos(degres)
s1.f=Sin(degres)
x3.f=lg/2
y3.f=ht/2
For y=0 To ht-1
pos=(cible_p+(lg*y)*4)
For x=0 To lg-1
xx.l=x3+ ((x-x3) * c1) + (y-y3)* s1
yy.l=y3- ((x-x3) * s1) + (y-y3)* c1
If (xx<0) Or (xx>lg-1) Or (yy<0) Or (yy>ht-1)
PokeL(pos+x*4,0) ; fond noir
Else
var=PeekL(source_p+(yy*lg*4)+xx*4)
PokeL(pos+x*4,var)
EndIf
Next
Next
EndProcedure
;-------------------------------------------------------------------
;--version asm
Procedure Filter_Rotate_asm(source,cible,angle)
Save_reg()
Protected degres.f , c1.f , s1.f , x3.f , y3.f
sp(source,cible)
degres=angle*#PI/180
c1=Cos(degres)
s1=Sin(degres)
x3=lg/2
y3=ht/2
!INSERTPS xmm1,[p.v_x3],$10 ; x3
!INSERTPS xmm1,[p.v_y3],$00 ; y3
; xmm1 = x3 y3
!INSERTPS xmm2,[p.v_c1],$10 ; c1
!INSERTPS xmm2,[p.v_s1],$00 ; s1
; xmm2 = c1 s1
!INSERTPS xmm3,[p.v_s1],$10 ; s1
!INSERTPS xmm3,[p.v_c1],$00 ; c1
; xmm3 = s1 c1
!xor r11,r11
!xor r10,r10 ; For y=0 To ht-1
!boucle_y:
!xor r9,r9 ; For x=0 To lg-1
!boucle_x:
;xx= x3 + ( ( x - x3 ) * c1 ) + ( ( y - y3 ) * s1 )
;yy= y3 - ( ( x - x3 ) * s1 ) + ( ( y - y3 ) * c1 )
!movq xmm4,r9;[p.v_x]
!CVTDQ2PS xmm4,xmm4 ; xmm4 = float(x)
!movq xmm5,r10;[p.v_y]
!CVTDQ2PS xmm5,xmm5 ; xmm5 = float(y)
!subss xmm4,[p.v_x3]; (x-x3)
!subss xmm5,[p.v_y3]; (y-y3)
!VBROADCASTSS xmm4,xmm4 ; (x-x3) (x-x3)
!VBROADCASTSS xmm5,xmm5 ; (y-y3) (y-y3)
!mulps xmm4,xmm2 ; (x-x3)*c1 (x-x3)*s1
!mulps xmm5,xmm3 ; (y-y3)*s1 (y-y3)*c1
!ADDSUBPS xmm4,xmm5 ; (x-x3)*c1+(y-y3)*s1 (x-x3)*s1-(y-y3)*c1
!movups xmm5,xmm1
!ADDSUBPS xmm5,xmm4 ; x3+(x-x3)*c1+(y-y3)*s1 y3-(x-x3)*s1-(y-y3)*c1
!CVTPS2DQ xmm5,xmm5 ; xmm5 = int(xmm5)
!xor rax,rax
!PEXTRD eax,xmm5,0
!mov r13,rax ; r13 = yy
!xor rax,rax
!PEXTRD eax,xmm5,1
!mov r12,rax ; r12 = xx
!mov ecx,0 ; var = 0 = couleur noir
!cmp r12,[p.v_lg] ; if xx>=lg : goto 'saut'
!jge saut
;!cmp r12,0 ; if xx<0 : goto 'saut'
;!jl saut
!cmp r13,[p.v_ht] ; if yy>=ht : goto 'saut'
!jge saut
;!cmp r13,0 ; if yy<0 : goto 'saut'
;!jl saut
!mov r8,r13;[p.v_yy] ;var = PeekL(source_p+((yy*lg)+xx)*4)
!iMUL r8,[p.v_lg]
!add r8,r12;[p.v_xx]
!shl r8,2
!add r8,[p.v_source_p]
!mov ecx,[r8]
!saut:
!mov rdx,r11 ; pos=(cible_p+(lg*y)*4)
!shl rdx,2
!add rdx,[p.v_cible_p]
!mov rax,r9 ; PokeL(pos+x*4,var)
!shl rax,2
!add rax,rdx
!mov [rax],ecx
!inc r9 ; x=x-1
!cmp r9,[p.v_lg]
!jb boucle_x ; Next x
!add r11,[p.v_lg] ; 'lg*y'
!inc r10 ; xyx+1
!cmp r10,[p.v_ht]
!jb boucle_y ; next y
Rest_Reg()
EndProcedure
;-------------------------------------------------------------------
UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=1200
Global imgy=800
If OpenWindow(0, 0, 0, imgx, imgy+16, "Rotate", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define source.q , cible.q , t.q , file$ , i , angle.l , mem_angle.l
file$ = OpenFileRequester("Image","","",0)
source=10
cible=20
If Not Load_Image(source,file$) ; <- commande differente de "LOADIMAGE"
MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
End
EndIf
ScrollBarGadget(1, 0, 0, 1200, 16, 0, 360, imgx/360 )
ResizeImage(source,imgx,imgy,#PB_Image_Smooth)
CreateImage(cible,imgx,imgy,32) ; l'image doit entre en mode 32bits
mem_angle=1
Repeat
angle=GetGadgetState(1)
If angle<>mem_angle
t=ElapsedMilliseconds()
angle=GetGadgetState(1)
Filter_Rotate_pb(source,cible,angle) ; <--- par defaut , version purebasic
t=ElapsedMilliseconds()-t
StartDrawing(WindowOutput(0))
DrawImage(ImageID(cible),0,16)
DrawText(5,5+16,Str(t))
StopDrawing()
mem_angle = angle
EndIf
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf