Code : Tout sélectionner
EnableExplicit
Global Dim Reg_memory.q(4*344)
; 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
taille = lg * ht
EndMacro
Macro clampRGB(r,g,b)
If r<0:r=0:EndIf
If g<0:g=0:EndIf
If b<0:b=0:EndIf
If r>255:r=255:EndIf
If g>255:g=255:EndIf
If b>255:b=255:EndIf
EndMacro
Macro returnRGB(pixel,r,g,b)
r=(pixel & $ff0000)>>16
g=(pixel & $ff00)>>8
b=(pixel & $ff)
EndMacro
;-------------------------------------------------------------------
; sauvegarde de registres
Macro Save_Reg()
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
;-------------------------------------------------------------------
Procedure Filter_Prewitt_pb(source.q,cible.q,mul.l=1)
Protected p , rgb
Protected r , g , b , r1,g1,b1 , r2,g2,b2 , r3,g3,b3 , r4,g4,b4 , r5,g5,b5 , r6,g6,b6 , r7,g7,b7 , r8,g8,b8 , r9,g9,b9
Protected x , y , ry,gy,by , rx,gx,bx
sp(source,cible)
For y=1 To ht-2
x=0
p=source_p+((y-1)*lg+x)<<2
rgb=PeekL(p)
returnRGB(rgb,r1,g1,b1)
p=source_p+((y-1)*lg+(x+1))<<2
rgb=PeekL(p)
returnRGB(rgb,r2,g2,b2)
p=source_p+((y-0)*lg+x)<<2
rgb=PeekL(p)
returnRGB(rgb,r4,g4,b4)
p=source_p+((y-0)*lg+(x+1))<<2
rgb=PeekL(p)
returnRGB(rgb,r5,g5,b5)
p=source_p+((y+1)*lg+x)<<2
rgb=PeekL(p)
returnRGB(rgb,r7,g7,b7)
p=source_p+((y+1)*lg+(x+1))<<2
rgb=PeekL(p)
returnRGB(rgb,r8,g8,b8)
For x=2 To lg-2
p=source_p+((y-1)*lg+x)<<2
rgb=PeekL(p)
returnRGB(rgb,r3,g3,b3)
p=source_p+((y-0)*lg+x)<<2
rgb=PeekL(p)
returnRGB(rgb,r6,g6,b6)
p=source_p+((y+1)*lg+x)<<2
rgb=PeekL(p)
returnRGB(rgb,r9,g9,b9)
ry=(r1 + r2 + r3) -( r7 + r8 + r9)
gy=(g1 + g2 + g3) -( g7 + g8 + g9)
by=(b1 + b2 + b3) -( b7 + b8 + b9)
rx=(r3 + r6 + r9)-(r1 + r4 + r7)
gx=(g3 + g6 + g9)-(g1 + g4 + g7)
bx=(b3 + b6 + b9)-(b1 + b4 + b7)
r=((Abs(rx)+Abs(ry))*mul)
g=((Abs(gx)+Abs(gy))*mul)
b=((Abs(bx)+Abs(by))*mul)
ClampRGB(r,g,b)
rgb=r<<16+g<<8+b
PokeL(cible_p+(lg*y+x)<<2,rgb)
r1=r2:r2=r3 : r4=r5:r5=r6 : r7=r8:r8=r9
g1=g2:g2=g3 : g4=g5:g5=g6 : g7=g8:g8=g9
b1=b2:b2=b3 : b4=b5:b5=b6 : b7=b8:b8=b9
Next
Next
EndProcedure
;-------------------------------------------------------------------
Procedure Filter_Prewitt_asm(source.q,cible.q,mul.l=1)
Protected s.q
sp(source,cible)
Save_Reg()
EnableASM
!mov r12,[p.v_source_p]
!mov r11,[p.v_cible_p]
!add r11,4
!mov r15,[p.v_lg]
!shl r15,2
!pxor xmm0,xmm0
!mov eax,[p.v_mul]
!imul eax,$10101
!movd xmm15,eax
!punpcklbw xmm15,xmm0
!xor rax,rax
!mov eax,[p.v_ht]
!mov r13,rax
!sub r13,3
!prewitt_boucle_y :
!mov rsi,r12
!mov rdi,r11
!add r12,r15
!add r11,r15
!movd xmm1,[rsi]
!movd xmm2,[rsi+4]
!add rsi,r15
!movd xmm4,[rsi]
!movd xmm5,[rsi+4]
!add rsi,r15
!movd xmm7,[rsi]
!movd xmm8,[rsi+4]
!sub rsi,r15
!sub rsi,r15
!punpcklbw xmm1,xmm0
!punpcklbw xmm2,xmm0
!punpcklbw xmm4,xmm0
!punpcklbw xmm5,xmm0
!punpcklbw xmm7,xmm0
!punpcklbw xmm8,xmm0
!xor rax,rax
!mov eax,[p.v_lg]
!mov r14,rax
!sub r14,2
!prewitt_boucle_x:
!movd xmm3,[rsi+8]
!add rsi,r15
!movd xmm6,[rsi+8]
!add rsi,r15
!movd xmm9,[rsi+8]
!sub rsi,r15
!sub rsi,r15
!punpcklbw xmm3,xmm0
!punpcklbw xmm6,xmm0
!punpcklbw xmm9,xmm0
!movups xmm10,xmm1 ; ry1 = |r1|g1|b1|
!paddsw xmm10,xmm2 ; ry1 = |r1+r2|g1+r2|b1+r2|
!paddsw xmm10,xmm3 ; ry1 = |r1+r2+r3|g1+g2+g3|b1+b2+b3|
!movups xmm11,xmm7 ; ry2 = |r7|g7|b7|
!paddsw xmm11,xmm8 ; ry2 = |r7+r8|g7+r8|b7+r8|
!paddsw xmm11,xmm9 ; ry2 = |r7+r8+r9|g7+g8+g9|b7+b8+b9|
!psubsw xmm10,xmm11 ; ry = ry1 - ry2
!pabsw xmm10,xmm10 ; ry = abs(ry)
!movups xmm12,xmm3 ; rx=(x3 + x6 + x9)-(x1 + x4 +x7)
!paddsw xmm12,xmm6
!paddsw xmm12,xmm9
!movups xmm13,xmm1
!paddsw xmm13,xmm4
!paddsw xmm13,xmm7
!psubsw xmm12,xmm13
!pabsw xmm12,xmm12 ; abs
!paddsw xmm10,xmm12 ; x=((rx+ry)*mul)
!pmullw xmm10,xmm15
!packuswb xmm10,xmm0
!movd [rdi],xmm10
!add rdi,4
!add rsi,4
!movaps xmm1,xmm2 ;r1=r2:r2=r3 : r4=r5:r5=r6 : r7=r8:r8=r9
!movaps xmm2,xmm3
!movaps xmm4,xmm5
!movaps xmm5,xmm6
!movaps xmm7,xmm8
!movaps xmm8,xmm9
!sub r14,1
!jnz prewitt_boucle_x
!sub r13,1
!jnz prewitt_boucle_y
DisableASM
Rest_Reg()
EndProcedure
;-------------------------------------------------------------------
UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=1200
Global imgy=800
If OpenWindow(0, 0, 0, imgx, imgy, "Prewitt", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define source.q , cible.q , t.q , file$ , i
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
ResizeImage(source,imgx,imgy,#PB_Image_Smooth)
CreateImage(cible,imgx,imgy,32) ; l'image doit entre en mode 32bits
t=ElapsedMilliseconds()
Filter_Prewitt_asm(source,cible) ; <= ramplacer par "Filter_Roberts_asm(source,cible)"
t=ElapsedMilliseconds()-t
StartDrawing(WindowOutput(0))
DrawImage(ImageID(cible),0,0)
DrawText(5,5,Str(t))
StopDrawing()
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf