C'est juste une convolution avec deux matrices.
Par défaut , si vous lancez le programme , c'est la version PB qui est exécuter.
Remplacez le ligne "Filter_Roberts_pb(source,cible)" par "Filter_Roberts_asm(source,cible)" , pour la version ASM.
la méthode "Roberts" est l'une des plus simple (codage) est rapide
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_Roberts_pb(source.q,cible.q,mul.l=1)
Protected pixel1.l , pixel2.l , pixel3.l , pixel4.l , pixel5.l , pixel6.l
Protected r , g , b , r1 , g1 , b1 , r2 , g2 , b2 , r3 , g3 , b3 , r4 , g4 , b4 , r5 , g5 , b5 , r6 , g6 , b6
Protected x , y
Protected pos2 , pos4 , pos5 , pos6
sp(source,cible)
For y = 0 To ht - 3 Step 2
pixel1 = PeekL(source_p + ( y * lg * 4 ))
pixel3 = PeekL(source_p + ((y + 1 )* lg * 4))
pixel5 = PeekL(source_p + (( (y + 2 )* lg ) + x) * 4)
For x = 0 To lg -2
pos2 = (( y * lg ) + x + 1) * 4
pos4 = (( (y + 1 )* lg ) + x + 1) * 4
pos6 = (( (y + 2 )* lg ) + x + 1) * 4
returnRGB(pixel1,r1,g1,b1)
returnRGB(pixel3,r3,g3,b3)
returnRGB(pixel5,r5,g5,b5)
pixel2=PeekL(source_p + pos2)
returnRGB(pixel2,r2,g2,b2)
pixel4=PeekL(source_p + pos4)
returnRGB(pixel4,r4,g4,b4)
pixel6=PeekL(source_p + pos6)
returnRGB(pixel6,r6,g6,b6)
r = (Abs(r1 - r4) + Abs(r2 - r3)) * mul
g = (Abs(g1 - g4) + Abs(g2 - g3)) * mul
b = (Abs(b1 - b4) + Abs(b2 - b3)) * mul
If r>255:r=255:EndIf
If g>255:g=255:EndIf
If b>255:b=255:EndIf
PokeL(cible_p + pos2 - 4 ,r<<16 + g<<8 + b)
r = (Abs(r3 - r6) + Abs(r4 - r5)) * mul
g = (Abs(g3 - g6) + Abs(g4 - g5)) * mul
b = (Abs(b3 - b6) + Abs(b4 - b5)) * mul
If r>255:r=255:EndIf
If g>255:g=255:EndIf
If b>255:b=255:EndIf
PokeL(cible_p + pos4 - 4,r<<16 + g<<8 + b)
pixel1 = pixel2
pixel3 = pixel4
pixel5 = pixel6
Next
Next
EndProcedure
;-------------------------------------------------------------------
Procedure Filter_Roberts_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]
!mov r15,[p.v_lg]
!shl r15,2 ; LG = LG x 4
!pxor xmm0,xmm0 ; xmm0 = 0
!mov eax,[p.v_mul] ; eax = 0|0|0|mul : (4x8 bits)
!imul eax,$10101 ; eax = 0|mul|mul|mul : (4x8 bits)
!movd xmm15,eax ; xmm15 = eax
!punpcklbw xmm15,xmm0 ; xmm15 = 00|0mul|0mul|0mul : (4x16 bits)
!xor r13,r13 ; r13 = 0
!mov r13d,[p.v_ht]
!sub r13,3
!robert_boucle_y: ; for y = 0 to (HT - (3+1)) : r13 = y
!mov rsi,r12 ; rsi = [p.v_source_p]
!mov rdi,r11 ; rdi = [p.v_cible_p]
!add r12,r15
!add r11,r15
!movd xmm1,[rsi] ; xmm1 = pixel1
!add rsi,r15
!movd xmm3,[rsi] ; xmm3 = pixel3
!sub rsi,r15
!punpcklbw xmm1,xmm0 ; xmm1 = 00a1 00r1 aag1 00b1 : 8 bits vers 16 bits
!punpcklbw xmm3,xmm0 ; xmm3 = 00a3 00r3 aag3 00b3 : 8 bits vers 16 bits
!xor r14,r14
!mov r14d,[p.v_lg]
!sub r14,2
!robert_boucle_x: ; for x = 0 to (LG - (2+1)) : r14 = x
!movd xmm2,[rsi+4] ; xmm2 = pixel2
!add rsi,r15
!movd xmm4,[rsi+4] ; xmm4 = pixel4
!sub rsi,r15
!punpcklbw xmm2,xmm0 ; xmm2 = 00a2 00r2 aag2 00b2 : 8 bits vers 16 bits
!punpcklbw xmm4,xmm0 ; xmm4 = 00a4 00r4 aag4 00b4 : 8 bits vers 16 bits
!movups xmm10,xmm1 ; xmm10 = pixel1
!psubsw xmm10,xmm4 ; xmm10 = pixel1 - pixel4
!pabsw xmm10,xmm10 ; xmm10 = abs(xmm10)
!movups xmm12,xmm2 ; xmm12 = pixel2
!psubsw xmm12,xmm3 ; xmm12 = pixel2 - pixel3
!pabsw xmm12,xmm12 ; xmm12 = abs(xmm12)
!paddsw xmm10,xmm12 ; xmm10 = xmm10 + xmm12
!pmullw xmm10,xmm15 ; xmm10 = xmm10 * mul
!packsswb xmm10,xmm0 ; xmm10 = argb ; 16 bits vers 8 bits
!movd [rdi],xmm10
!add rdi,4
!add rsi,4
!movups xmm1,xmm2 ; pixel1 = pixel2
!movups xmm3,xmm4 ; pixel3 = pixel4
!sub r14,1
!jnz robert_boucle_x
!sub r13,1
!jnz robert_boucle_y
DisableASM
Rest_Reg()
EndProcedure
;-------------------------------------------------------------------
UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=1200
Global imgy=800
If OpenWindow(0, 0, 0, imgx, imgy, "Roberts", #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_Roberts_pb(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