filtre détection de contour méthode roberts

Pour discuter de l'assembleur
manababel
Messages : 136
Inscription : jeu. 14/mai/2020 7:40

filtre détection de contour méthode roberts

Message par manababel »

Pour utiliser se filtre, il faut utiliser une image en niveau de gris.
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
Avatar de l’utilisateur
kernadec
Messages : 1594
Inscription : ven. 25/avr./2008 11:14

Re: filtre détection de contour méthode roberts

Message par kernadec »

bjr manababel
merci encore pour le partage
cordialement
manababel
Messages : 136
Inscription : jeu. 14/mai/2020 7:40

Re: filtre détection de contour méthode roberts

Message par manababel »

voici la version multi-thread

Code : Tout sélectionner

EnableExplicit

CompilerIf #PB_Compiler_Thread = #False
   CompilerError "Enable Thread Safe mode!"
 CompilerEndIf
 
Global ndt_max=CountCPUs(#PB_System_ProcessCPUs )
Global ndt=ndt_max -1
If ndt < 1 : ndt = 1 :EndIf
;If ndt >4 : ndt = 4 : EndIf ; au dessus de 4 threads , les performant diminues ( a tester )

Global Dim Thread(ndt_max+1)
Structure var
  source.q
  cible.q
  mul.l
  start.q
  stop.q
EndStructure
Global Dim param.var((ndt_max)*2+1)

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_sp(i)
  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
  Protected source , cible , mul , start , stop
  
  source=param(i)\source
  cible=param(i)\cible
  mul=param(i)\mul
  start=param(i)\start
  stop=param(i)\stop
  
  sp(source,cible)
  
  If start = 0 : start =1 : EndIf
  If stop >=(ht-3) : stop= ht-3:EndIf
  
  For y = start To stop 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_pb(source.q,cible.q,mul.f=1)
  
  Protected div , i
  
  sp(source,cible)
  div=ht/ndt
 
  For i=0 To ndt-1
    Param(i)\source=source
    Param(i)\cible=cible
    Param(i)\mul=mul
    Param(i)\start=i*div
    Param(i)\stop=(i*div)+div-1
    Thread(i)=CreateThread(@Filter_Roberts_pb_sp(),i)
  Next
  
  For i=0 To ndt-1
    If Thread(i) : WaitThread(thread(i)):EndIf
  Next
  
EndProcedure
;-------------------------------------------------------------------

Procedure Filter_Roberts_asm(source.q,cible.q,mul.f=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
 
  !VBROADCASTSS xmm15,[p.v_mul]
  
  !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

      !punpcklwd xmm10,xmm0 ; 16=>32bits
      !CVTDQ2PS xmm10,xmm10 ; float(x)
      !mulps xmm10,xmm15 ; 
      !CVTPS2DQ xmm10,xmm10 ; int(x)
      !packusdw xmm10,xmm0 ; 32=>16bits
      
      !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,1)  ; <= 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
Répondre