filtre OilPainting

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

filtre OilPainting

Message par manababel »

voici la version asm 64bits du filtre OilPainting
il devrait fonctionner sur la plupart des pc

Code : Tout sélectionner

EnableExplicit

CompilerIf #PB_Compiler_Thread = #False
   CompilerError "Enable Thread Safe mode!"
CompilerEndIf

UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=800
Global imgy=600


Global ndt_max=CountCPUs(#PB_System_ProcessCPUs )
Global ndt=ndt_max
If ndt < 1 : ndt = 1 :EndIf

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

Global Dim nr.l(256 + 256 * ndt_max)
Global Dim ng.l(256 + 256 * ndt_max)
Global Dim nb.l(256 + 256 * ndt_max)
Global Dim it.l(256 + 256 * ndt_max)

; charge une image et la convertie en 32bit
;-------------------------------------------------------------------
Procedure load_image(nom,file$)
  Protected nom_p.i , temps_p.i , x.l , y.l , r.l,g.l,b.l , i.l
  Protected lg.l , ht.l , depth.l , temps.i  , dif.l , dif1.l

  LoadImage(nom,file$)
  If Not IsImage(nom) : ProcedureReturn 0 : EndIf
   
  StartDrawing(ImageOutput(nom))
  Depth=OutputDepth()
  StopDrawing()

  If Depth=24
    CopyImage(nom,temps)
    FreeImage(nom)
    StartDrawing(ImageOutput(temps))
    temps_p = DrawingBuffer()
    lg = ImageWidth(temps)
    ht = ImageHeight(temps)
    dif = DrawingBufferPitch() - (lg*3)
    Debug dif
    StopDrawing()
    
  
    CreateImage(nom,lg,ht,32)
    StartDrawing(ImageOutput(nom))
    nom_p = DrawingBuffer()
    StopDrawing()
    
    For y=0 To ht-1
      For x=0 To lg-1
        i = ((y*lg)+x)*3
        r=PeekA(temps_p + i + 2 + dif1)
        g=PeekA(temps_p + i + 1 + dif1)
        b=PeekA(temps_p + i + 0 + dif1)
        PokeL(nom_p + ((y*lg)+x)*4 , r<<16 + g<<8 + b)
      Next
      dif1 = dif1 + dif
    Next
    
    FreeImage(temps) ; supprime l'image 24bits
    
  EndIf

  ProcedureReturn 1
EndProcedure
;-------------------------------------------------------------------

Macro sp(source,cible)
  Protected  lg , ht , lg1 , ht1 , taille
  Protected cible_p , source_p

  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht1 = ImageHeight(cible)
  lg1 = ImageWidth(cible)
  StopDrawing()

  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht = ImageHeight(source)
  lg = ImageWidth(source)
  StopDrawing()

  If lg<>lg1 Or ht<>ht1 : ProcedureReturn : EndIf
  taille = lg * ht
EndMacro

Macro returnARGB(pixel,a,r,g,b)
  a=(pixel & $ff000000)>>24
  r=(pixel & $ff0000)>>16
  g=(pixel & $ff00)>>8
  b=(pixel & $ff)
EndMacro

Macro clamp(var,min,max)
  If var<min : var = min : EndIf
  If var>max : var = max : EndIf
EndMacro

;-------------------------------------------------------------------

Procedure OilPainting_sp(i)
  
  Protected i2.l = 0
  Protected source.q , cible.q , start.q , stop.q , radius.q , intensity.q
  Protected x.q,y.q 
  Protected pit.l , pnr.l , png.l , pnb.l
  
  pit=it()
  pnr=nr()
  png=ng()
  pnb=nb()
  
  source=param(i)\source
  cible=param(i)\cible
  start=param(i)\start
  stop=param(i)\stop
  radius=param(i)\radius
  intensity=param(i)\intensity
  
  If intensity<1 : intensity=1 :EndIf
  
  sp(source,cible)
  
  If stop > (ht-1) : stop= ht-1 : EndIf
  
  i = (i * 256)*4
  
  For y=start To stop
    
    !mov r11,[p.v_pit]
    !mov r12,[p.v_pnr]
    !mov r13,[p.v_png]
    !mov r14,[p.v_pnb]
    !add r11,[p.v_i]
    !add r12,[p.v_i]
    !add r13,[p.v_i]
    !add r14,[p.v_i]
    
    !xor rax,rax ; For j=0 To intensity : nr(j)=0 : ng(j)=0 : nb(j)=0 : it(j)=0 : Next
    !xor rbx,rbx
    !mov rcx,[p.v_intensity]
    !OilPainting_reset:
      !mov [r11+rbx],eax
      !mov [r12+rbx],eax
      !mov [r13+rbx],eax
      !mov [r14+rbx],eax
      !add rbx,4
      !dec rcx
    !jnz OilPainting_reset
     
    !mov rbx,[p.v_radius] ; For yy=-radius To radius  
    !neg rbx
    !OilPainting_saut_yy1:
      !mov r15,[p.v_radius] ; For xx=-radius To radius
      !neg r15
      !OilPainting_saut_xx1:
        !xor rax,rax
        !mov r8,r15;[p.v_xx]
        !cmp r8,[p.v_lg] ;clamp(px,0,lg-1)
        !cmovae r8,rax
        ;py=yy+y
        !mov r9,rbx;[p.v_yy]
        !add r9,[p.v_y]
        !cmp r9,[p.v_ht] ;clamp(py,0,ht-1)
        !cmovae r9,rax
        ;rgb = PeekL(source_p+((py*lg+px)<<2))
        !mov r10,r9 ; r9=[p.v_py]
        !imul r10,[p.v_lg]
        !add r10,r8; r8 = [p.v_px]
        !shl r10,2
        !add r10,[p.v_source_p]
        !mov eax,[r10] ; eax = argb
        ;ReturnARGB( rgb , index , r , g , b )
        !mov edx,eax
        !shr edx,24
        !and rdx,$ff ; rdx = index
        ;nb(index) = (nb(index) + b)
        !xor ecx,ecx
        !mov cl,al
        !add [r14+rdx*4],ecx     
        !shr eax,8
        ;ng(index) = (ng(index) + g)
        !mov cl,al
        !add [r13+rdx*4],ecx     
        !shr eax,8
        ;nr(index) = (nr(index) + r)
        !mov cl,al
        !add [r12+rdx*4],ecx     
        ;it(index) = (it(index) + 1)
        !mov cl,1
        !add [r11+rdx*4],ecx 
      !inc r15 ;Next
      !cmp r15,[p.v_radius]
      !jle OilPainting_saut_xx1
    !inc rbx;Next
    !cmp rbx, [p.v_radius]
    !jle OilPainting_saut_yy1
    
    !xor r15,r15 
    !OilPainting_saut_x1:
    ;For x=0 To lg-1 ; -----------------------------------------------------------------------------------------------------------
  
      !mov r8,[p.v_radius] ;For yy=-radius To radius ; -------------------------------------------------------------
      !neg r8
      !OilPainting_saut_y1:
        
        ;px=x-radius
        !xor rax,rax
        !mov rcx,r15 ; [p.v_x]
        !sub rcx,[p.v_radius]
        !cmp rcx,[p.v_lg] ;clamp(px,0,lg-1)
        !cmovae rcx,rax ; rcx=px
        ;py=yy+y
        !mov r9,r8;r8 = [p.v_yy]
        !add r9,[p.v_y]
        !cmp r9,[p.v_ht] ;clamp(py,0,ht-1)
        !cmovae r9,rax ; r9=py
        ;rgb = PeekL(source_p+((py*lg+px)<<2))
        !mov r10,r9
        !imul r10,[p.v_lg]
        !add r10,rcx;[p.v_px]
        !shl r10,2
        !add r10,[p.v_source_p]
        !mov eax,[r10] ; eax = argb
        ;ReturnARGB( rgb , index , r , g , b )
        !mov edx,eax
        !shr edx,24
        !and rdx,$ff ; rdx = index
        ;nb(index) = (nb(index) - b)
        !xor ecx,ecx
        !mov cl,al
        !sub [r14+rdx*4],ecx     
        !shr eax,8
        ;ng(index) = (ng(index) - g)
        !mov cl,al
        !sub [r13+rdx*4],ecx     
        !shr eax,8
        ;nr(index) = (nr(index) - r)
        !mov cl,al
        !sub [r12+rdx*4],ecx     
        ;it(index) = (it(index) - 1)
        !mov cl,1
        !sub [r11+rdx*4],ecx         
        
       
        ;px=x+radius+1
        !xor rax,rax
        !mov rcx,r15 ;[p.v_x]
        !add rcx,[p.v_radius]
        !inc rcx
        !cmp rcx,[p.v_lg] ;clamp(px,0,lg-1)
        !cmovae rcx,rax
        ;rgb = PeekL(source_p+((py*lg+px)<<2))
        !mov r10,r9; r9 = [p.v_py] = py=yy+y
        !imul r10,[p.v_lg]
        !add r10,rcx; rcx=[p.v_px]
        !shl r10,2
        !add r10,[p.v_source_p]
        !mov eax,[r10] ; eax = argb
        ;ReturnARGB( rgb , index , r , g , b )
        !mov edx,eax
        !shr edx,24
        !and rdx,$ff ; rdx = index
        ;nb(index) = (nb(index) + b)
        !xor ecx,ecx
        !mov cl,al
        !add [r14+rdx*4],ecx     
        !shr eax,8
        ;ng(index) = (ng(index) + g)
        !mov cl,al
        !add [r13+rdx*4],ecx     
        !shr eax,8
        ;nr(index) = (nr(index) + r)
        !mov cl,al
        !add [r12+rdx*4],ecx     
        ;it(index) = (it(index) + 1)
        !mov cl,1
        !add [r11+rdx*4],ecx 
        
      !inc r8;Next
      !cmp r8,[p.v_radius]
      !jle OilPainting_saut_y1 ; -------------------------------------------------------------

        
      !xor rax,rax; j=0
      !xor r8,r8 ; r=0
      !xor r9,r9 ; g=0
      !xor r10,r10; b=0
      !OilPainting_saut_y2: ;For j=0 To intensity
        !mov edx,[r11+rax*4] ; edx = it(j)
        !cmp edx,[r11+r8*4] ; cmp it(j) , it(r)
        !cmovg r8,rax ; if  it(j) > it(r) : r = j
        !cmp edx,[r11+r9*4]
        !cmovg r9,rax
        !cmp edx,[r11+r10*4]
        !cmovg r10,rax
      !inc rax ;Next
      !cmp rax,[p.v_intensity]
      !jbe OilPainting_saut_y2     
      
      !xor rbx,rbx
      !mov ecx,[r11+r8*4] ; If it(r)>0 : r=nr(r)/(it(r)) : EndIf
      !cmp ecx,0
      !jz OilPainting_saut_r
        !mov eax,[r12+r8*4] ; eax = nr(r)
        !cqo
        !idiv ecx
        !mov bl,al
        !shl ebx,16
      !OilPainting_saut_r:
      
      !mov ecx,[r11+r9*4] ; If it(g)>0 : g=ng(g)/(it(g)) : EndIf
      !cmp ecx,0
      !jz OilPainting_saut_g
        !mov eax,[r13+r9*4] ; eax = ng(g) 
        !cqo
        !idiv ecx
        !mov bh,al
      !OilPainting_saut_g:
        
      !mov ecx,[r11+r10*4] ; If it(b)>0 : b=nb(b)/(it(b)) : EndIf
      !cmp ecx,0
      !jz OilPainting_saut_b
        !mov eax,[r14+r10*4] ; eax = nb(b) 
        !cqo
        !idiv ecx
        !mov bl,al
      !OilPainting_saut_b:       
      
      ;PokeL(cible_p+((y*lg+x)<<2), b)
      !xor rax,rax
      !mov eax,[p.v_y]
      !imul eax,[p.v_lg]
      !add eax,r15d;[p.v_x]
      !shl eax,2
      !add rax,[p.v_cible_p]
      !mov [rax],ebx
      
    !inc r15
    !cmp r15,[p.v_lg]
    !jb OilPainting_saut_x1
    ;Next ; -----------------------------------------------------------------------------------------------------------    
  Next
         
EndProcedure

;-------------------------------------------------------------------
Procedure OilPainting(source.i,cible.i,radius.l,intensity.l)
 
  Protected div.l , i.l , x.l , y.l
  Protected rgb.l , a.l , r.l , g.l , b.l
  Protected tt.l
  
  sp(source,cible)
 
  For y=0 To ht-1
    For x=0 To lg-1
      rgb = PeekL(source_p+((y*lg+x)<<2))
      Returnargb( rgb , a , r , g , b )
      a = (( r + g + b ) * 85)>>8
      a = (( a * intensity )>>8) & 255
      PokeL(source_p+((y*lg+x)<<2),a<<24 + (rgb & $00ffffff))
    Next
  Next
 
  div=ht/ndt

  For i=0 To ndt-1
    Param(i)\source=source
    Param(i)\cible=cible
    Param(i)\radius=radius
    Param(i)\intensity=intensity
    Param(i)\start=i*div
    If i = (ndt-1) 
      Param(i)\stop=ht-1
    Else
      Param(i)\stop=(i*div)+div-1
    EndIf
    
    Thread(i)=CreateThread(@OilPainting_sp(),i)
  Next
 
  For i=0 To ndt-1
    If Thread(i) : WaitThread(thread(i)):EndIf
  Next
 
EndProcedure

;-------------------------------------------------------------------

UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=800
Global imgy=600

If OpenWindow(0, 0, 0, imgx, imgy, "OilPainting", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define source.i=0 , cible.i=0 , t.i , file$ , nom$ , quit.l
  Define ht1.l , lg1.l
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
      MenuItem( 1, "Load")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
   
  ScrollBarGadget(100, 50, 0, 250, 18, 0, 10, 1)
  ScrollBarGadget(101, 400, 0, 250, 18, 0, 255, 1)
   
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
       
      Case #PB_Event_Gadget
        Select EventGadget() 
          Case 100 , 101
            t=ElapsedMilliseconds()
            OilPainting(source,cible,GetGadgetState(100),GetGadgetState(101))
            t=ElapsedMilliseconds()-t
        EndSelect
       
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1 
            If source = 0
              source = 10
            Else
              FreeImage((source))
              FreeImage((cible))
              cible = 0
            EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              If cible = 0 And source = 10 
                cible = 20
                CopyImage(source,cible)
              EndIf
              
              OilPainting(source,cible,GetGadgetState(100),GetGadgetState(101))
            EndIf
           
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf
          Case 3
            ;SaveFileRequester("Save JPG", "", "", 0)
            ;If nom$ <> "" : SaveImage(cible, nom$+".jpg" ,#PB_ImagePlugin_JPEG ,10 ) : EndIf
          Case 4
            SetClipboardImage(cible)
          Case 5
            quit = 1
        EndSelect     
    EndSelect
   
    StartDrawing(WindowOutput(0))
    If cible<>0
      DrawImage(ImageID(cible),0,20)
    EndIf
    DrawText(5,2,Str(t)+"   ")
    StopDrawing()
   
  Until Quit = 1
 
EndIf
Dernière modification par manababel le mer. 24/févr./2021 20:30, modifié 1 fois.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: filtre OilPainting

Message par Kwai chang caine »

Merci Manababel 8)
J'ai une erreur "GetmodulehandleW" en X64 et aussi en x86 "FOR ne supporte pas les variables de type quad" (ce qui doit être normal) :|
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: filtre OilPainting

Message par manababel »

bonjour Kain ,
je ne sais pas d'ou vient cette erreur .
le programme en asm est une copie du programme en pb .
il n'appelle aucune fonctions.

en x86 , c'est normal que ca ne fonctionne pas , c'est uniquement en x64.

voici une version avec sauvegarde des registres .( je ne suis pas sur que la sauvegarde des registres marche en multi-thread )

Code : Tout sélectionner

EnableExplicit

CompilerIf #PB_Compiler_Thread = #False
   CompilerError "Enable Thread Safe mode!"
CompilerEndIf

UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=800
Global imgy=600


Global ndt_max=CountCPUs(#PB_System_ProcessCPUs )
Global ndt=ndt_max
If ndt < 1 : ndt = 1 :EndIf

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

Global Dim nr.l(256 + 256 * ndt_max)
Global Dim ng.l(256 + 256 * ndt_max)
Global Dim nb.l(256 + 256 * ndt_max)
Global Dim it.l(256 + 256 * ndt_max)

Global Dim Reg_memory.q(4*344 + (4*334)*ndt_max)
;-------------------------------------------------------------------
; sauvegarde de registres
Macro Save_reg(i)
  Protected s
  s=@reg_memory() + (4*334)*i
  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(i)
  ; restore les registres
  s=@reg_memory(i) + (4*334)*i
  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 nom_p.i , temps_p.i , x.l , y.l , r.l,g.l,b.l , i.l
  Protected lg.l , ht.l , depth.l , temps.i  , dif.l , dif1.l

  LoadImage(nom,file$)
  If Not IsImage(nom) : ProcedureReturn 0 : EndIf
   
  StartDrawing(ImageOutput(nom))
  Depth=OutputDepth()
  StopDrawing()

  If Depth=24
    CopyImage(nom,temps)
    FreeImage(nom)
    StartDrawing(ImageOutput(temps))
    temps_p = DrawingBuffer()
    lg = ImageWidth(temps)
    ht = ImageHeight(temps)
    dif = DrawingBufferPitch() - (lg*3)
    Debug dif
    StopDrawing()
    
  
    CreateImage(nom,lg,ht,32)
    StartDrawing(ImageOutput(nom))
    nom_p = DrawingBuffer()
    StopDrawing()
    
    For y=0 To ht-1
      For x=0 To lg-1
        i = ((y*lg)+x)*3
        r=PeekA(temps_p + i + 2 + dif1)
        g=PeekA(temps_p + i + 1 + dif1)
        b=PeekA(temps_p + i + 0 + dif1)
        PokeL(nom_p + ((y*lg)+x)*4 , r<<16 + g<<8 + b)
      Next
      dif1 = dif1 + dif
    Next
    
    FreeImage(temps) ; supprime l'image 24bits
    
  EndIf

  ProcedureReturn 1
EndProcedure
;-------------------------------------------------------------------

Macro sp(source,cible)
  Protected  lg , ht , lg1 , ht1 , taille
  Protected cible_p , source_p

  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht1 = ImageHeight(cible)
  lg1 = ImageWidth(cible)
  StopDrawing()

  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht = ImageHeight(source)
  lg = ImageWidth(source)
  StopDrawing()

  If lg<>lg1 Or ht<>ht1 : ProcedureReturn : EndIf
  taille = lg * ht
EndMacro

Macro returnARGB(pixel,a,r,g,b)
  a=(pixel & $ff000000)>>24
  r=(pixel & $ff0000)>>16
  g=(pixel & $ff00)>>8
  b=(pixel & $ff)
EndMacro

Macro clamp(var,min,max)
  If var<min : var = min : EndIf
  If var>max : var = max : EndIf
EndMacro

;-------------------------------------------------------------------

Procedure OilPainting_sp(i)
 
  Protected i2.l = 0
  Protected source.q , cible.q , start.q , stop.q , radius.q , intensity.q
  Protected x.q,y.q
  Protected pit.l , pnr.l , png.l , pnb.l
  Protected save_i.q = i
  
  pit=it()
  pnr=nr()
  png=ng()
  pnb=nb()
 
  source=param(i)\source
  cible=param(i)\cible
  start=param(i)\start
  stop=param(i)\stop
  radius=param(i)\radius
  intensity=param(i)\intensity
 
  If intensity<1 : intensity=1 :EndIf
 
  sp(source,cible)
 
  If stop > (ht-1) : stop= ht-1 : EndIf
  
  
  i = (i * 256)*4
  
  Save_reg(save_i)
  
  For y=start To stop
   
    !mov r11,[p.v_pit]
    !mov r12,[p.v_pnr]
    !mov r13,[p.v_png]
    !mov r14,[p.v_pnb]
    !add r11,[p.v_i]
    !add r12,[p.v_i]
    !add r13,[p.v_i]
    !add r14,[p.v_i]
   
    !xor rax,rax ; For j=0 To intensity : nr(j)=0 : ng(j)=0 : nb(j)=0 : it(j)=0 : Next
    !xor rbx,rbx
    !mov rcx,[p.v_intensity]
    !OilPainting_reset:
      !mov [r11+rbx],eax
      !mov [r12+rbx],eax
      !mov [r13+rbx],eax
      !mov [r14+rbx],eax
      !add rbx,4
      !dec rcx
    !jnz OilPainting_reset
     
    !mov rbx,[p.v_radius] ; For yy=-radius To radius 
    !neg rbx
    !OilPainting_saut_yy1:
      !mov r15,[p.v_radius] ; For xx=-radius To radius
      !neg r15
      !OilPainting_saut_xx1:
        !xor rax,rax
        !mov r8,r15;[p.v_xx]
        !cmp r8,[p.v_lg] ;clamp(px,0,lg-1)
        !cmovae r8,rax
        ;py=yy+y
        !mov r9,rbx;[p.v_yy]
        !add r9,[p.v_y]
        !cmp r9,[p.v_ht] ;clamp(py,0,ht-1)
        !cmovae r9,rax
        ;rgb = PeekL(source_p+((py*lg+px)<<2))
        !mov r10,r9 ; r9=[p.v_py]
        !imul r10,[p.v_lg]
        !add r10,r8; r8 = [p.v_px]
        !shl r10,2
        !add r10,[p.v_source_p]
        !mov eax,[r10] ; eax = argb
        ;ReturnARGB( rgb , index , r , g , b )
        !mov edx,eax
        !shr edx,24
        !and rdx,$ff ; rdx = index
        ;nb(index) = (nb(index) + b)
        !xor ecx,ecx
        !mov cl,al
        !add [r14+rdx*4],ecx     
        !shr eax,8
        ;ng(index) = (ng(index) + g)
        !mov cl,al
        !add [r13+rdx*4],ecx     
        !shr eax,8
        ;nr(index) = (nr(index) + r)
        !mov cl,al
        !add [r12+rdx*4],ecx     
        ;it(index) = (it(index) + 1)
        !mov cl,1
        !add [r11+rdx*4],ecx
      !inc r15 ;Next
      !cmp r15,[p.v_radius]
      !jle OilPainting_saut_xx1
    !inc rbx;Next
    !cmp rbx, [p.v_radius]
    !jle OilPainting_saut_yy1
   
    !xor r15,r15
    !OilPainting_saut_x1:
    ;For x=0 To lg-1 ; -----------------------------------------------------------------------------------------------------------
 
      !mov r8,[p.v_radius] ;For yy=-radius To radius ; -------------------------------------------------------------
      !neg r8
      !OilPainting_saut_y1:
       
        ;px=x-radius
        !xor rax,rax
        !mov rcx,r15 ; [p.v_x]
        !sub rcx,[p.v_radius]
        !cmp rcx,[p.v_lg] ;clamp(px,0,lg-1)
        !cmovae rcx,rax ; rcx=px
        ;py=yy+y
        !mov r9,r8;r8 = [p.v_yy]
        !add r9,[p.v_y]
        !cmp r9,[p.v_ht] ;clamp(py,0,ht-1)
        !cmovae r9,rax ; r9=py
        ;rgb = PeekL(source_p+((py*lg+px)<<2))
        !mov r10,r9
        !imul r10,[p.v_lg]
        !add r10,rcx;[p.v_px]
        !shl r10,2
        !add r10,[p.v_source_p]
        !mov eax,[r10] ; eax = argb
        ;ReturnARGB( rgb , index , r , g , b )
        !mov edx,eax
        !shr edx,24
        !and rdx,$ff ; rdx = index
        ;nb(index) = (nb(index) - b)
        !xor ecx,ecx
        !mov cl,al
        !sub [r14+rdx*4],ecx     
        !shr eax,8
        ;ng(index) = (ng(index) - g)
        !mov cl,al
        !sub [r13+rdx*4],ecx     
        !shr eax,8
        ;nr(index) = (nr(index) - r)
        !mov cl,al
        !sub [r12+rdx*4],ecx     
        ;it(index) = (it(index) - 1)
        !mov cl,1
        !sub [r11+rdx*4],ecx         
       
       
        ;px=x+radius+1
        !xor rax,rax
        !mov rcx,r15 ;[p.v_x]
        !add rcx,[p.v_radius]
        !inc rcx
        !cmp rcx,[p.v_lg] ;clamp(px,0,lg-1)
        !cmovae rcx,rax
        ;rgb = PeekL(source_p+((py*lg+px)<<2))
        !mov r10,r9; r9 = [p.v_py] = py=yy+y
        !imul r10,[p.v_lg]
        !add r10,rcx; rcx=[p.v_px]
        !shl r10,2
        !add r10,[p.v_source_p]
        !mov eax,[r10] ; eax = argb
        ;ReturnARGB( rgb , index , r , g , b )
        !mov edx,eax
        !shr edx,24
        !and rdx,$ff ; rdx = index
        ;nb(index) = (nb(index) + b)
        !xor ecx,ecx
        !mov cl,al
        !add [r14+rdx*4],ecx     
        !shr eax,8
        ;ng(index) = (ng(index) + g)
        !mov cl,al
        !add [r13+rdx*4],ecx     
        !shr eax,8
        ;nr(index) = (nr(index) + r)
        !mov cl,al
        !add [r12+rdx*4],ecx     
        ;it(index) = (it(index) + 1)
        !mov cl,1
        !add [r11+rdx*4],ecx
       
      !inc r8;Next
      !cmp r8,[p.v_radius]
      !jle OilPainting_saut_y1 ; -------------------------------------------------------------

       
      !xor rax,rax; j=0
      !xor r8,r8 ; r=0
      !xor r9,r9 ; g=0
      !xor r10,r10; b=0
      !OilPainting_saut_y2: ;For j=0 To intensity
        !mov edx,[r11+rax*4] ; edx = it(j)
        !cmp edx,[r11+r8*4] ; cmp it(j) , it(r)
        !cmovg r8,rax ; if  it(j) > it(r) : r = j
        !cmp edx,[r11+r9*4]
        !cmovg r9,rax
        !cmp edx,[r11+r10*4]
        !cmovg r10,rax
      !inc rax ;Next
      !cmp rax,[p.v_intensity]
      !jbe OilPainting_saut_y2     
     
      !xor rbx,rbx
      !mov ecx,[r11+r8*4] ; If it(r)>0 : r=nr(r)/(it(r)) : EndIf
      !cmp ecx,0
      !jz OilPainting_saut_r
        !mov eax,[r12+r8*4] ; eax = nr(r)
        !cqo
        !idiv ecx
        !mov bl,al
        !shl ebx,16
      !OilPainting_saut_r:
     
      !mov ecx,[r11+r9*4] ; If it(g)>0 : g=ng(g)/(it(g)) : EndIf
      !cmp ecx,0
      !jz OilPainting_saut_g
        !mov eax,[r13+r9*4] ; eax = ng(g)
        !cqo
        !idiv ecx
        !mov bh,al
      !OilPainting_saut_g:
       
      !mov ecx,[r11+r10*4] ; If it(b)>0 : b=nb(b)/(it(b)) : EndIf
      !cmp ecx,0
      !jz OilPainting_saut_b
        !mov eax,[r14+r10*4] ; eax = nb(b)
        !cqo
        !idiv ecx
        !mov bl,al
      !OilPainting_saut_b:       
     
      ;PokeL(cible_p+((y*lg+x)<<2), b)
      !xor rax,rax
      !mov eax,[p.v_y]
      !imul eax,[p.v_lg]
      !add eax,r15d;[p.v_x]
      !shl eax,2
      !add rax,[p.v_cible_p]
      !mov [rax],ebx
     
    !inc r15
    !cmp r15,[p.v_lg]
    !jb OilPainting_saut_x1
    ;Next ; -----------------------------------------------------------------------------------------------------------   
  Next
  
  Rest_Reg(save_i)
EndProcedure

;-------------------------------------------------------------------
Procedure OilPainting(source.i,cible.i,radius.l,intensity.l)

  Protected div.l , i.l , x.l , y.l
  Protected rgb.l , a.l , r.l , g.l , b.l
  Protected tt.l
 
  sp(source,cible)

  For y=0 To ht-1
    For x=0 To lg-1
      rgb = PeekL(source_p+((y*lg+x)<<2))
      Returnargb( rgb , a , r , g , b )
      a = (( r + g + b ) * 85)>>8
      a = (( a * intensity )>>8) & 255
      PokeL(source_p+((y*lg+x)<<2),a<<24 + (rgb & $00ffffff))
    Next
  Next

  div=ht/ndt

  For i=0 To ndt-1
    Param(i)\source=source
    Param(i)\cible=cible
    Param(i)\radius=radius
    Param(i)\intensity=intensity
    Param(i)\start=i*div
    If i = (ndt-1)
      Param(i)\stop=ht-1
    Else
      Param(i)\stop=(i*div)+div-1
    EndIf
   
    Thread(i)=CreateThread(@OilPainting_sp(),i)
  Next

  For i=0 To ndt-1
    If Thread(i) : WaitThread(thread(i)):EndIf
  Next

EndProcedure

;-------------------------------------------------------------------

If OpenWindow(0, 0, 0, imgx, imgy, "OilPainting", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define source.i=0 , cible.i=0 , t.i , file$ , nom$ , quit.l
  Define ht1.l , lg1.l
 
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
      MenuItem( 1, "Load")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
   
  ScrollBarGadget(100, 50, 0, 250, 18, 0, 10, 1)
  ScrollBarGadget(101, 400, 0, 250, 18, 0, 255, 1)
   
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
       
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 100 , 101
            t=ElapsedMilliseconds()
            OilPainting(source,cible,GetGadgetState(100),GetGadgetState(101))
            t=ElapsedMilliseconds()-t
        EndSelect
       
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            If source = 0
              source = 10
            Else
              FreeImage((source))
              FreeImage((cible))
              cible = 0
            EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              If cible = 0 And source = 10
                cible = 20
                CopyImage(source,cible)
              EndIf
             
              OilPainting(source,cible,GetGadgetState(100),GetGadgetState(101))
            EndIf
           
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf
          Case 3
            ;SaveFileRequester("Save JPG", "", "", 0)
            ;If nom$ <> "" : SaveImage(cible, nom$+".jpg" ,#PB_ImagePlugin_JPEG ,10 ) : EndIf
          Case 4
            SetClipboardImage(cible)
          Case 5
            quit = 1
        EndSelect     
    EndSelect
   
    StartDrawing(WindowOutput(0))
    If cible<>0
      DrawImage(ImageID(cible),0,20)
    EndIf
    DrawText(5,2,Str(t)+"   ")
    StopDrawing()
   
  Until Quit = 1

EndIf
Dernière modification par manababel le mer. 24/févr./2021 20:31, modifié 1 fois.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: filtre OilPainting

Message par Kwai chang caine »

Bah si toi, artisan de l'ASM tu sais pas 8O
Compte pas sur moi, technicien de surface de PB pour t'aider :mrgreen: :oops:
Ca fait pareil avec ton nouveau code :| je dois encore merdouiller "cake" part :oops:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: filtre OilPainting

Message par djes »

Hello manababel, je pense qu'il faut que tu utilises DrawingBufferPitch() car les buffers d'image sont parfois alignés sur 16 pixels (notamment les jpeg).
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: filtre OilPainting

Message par manababel »

merci pour la commande DrawingBufferPitch() , je ne connaissais pas .

le programme est modifier , ça a marcher avec les quelque testes que j'ai fais.

je ne pense pas que le problème de Kwai vienne du format de l'image , si c’était le cas , l'erreur serait un "acces memoire invalide"
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: filtre OilPainting

Message par djes »

Non, c'est juste qu'en testant, mon image avait un joli effet de shearing (comme aurait dit dpaint). Super code au passage, comme d'habitude !
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: filtre OilPainting

Message par Kwai chang caine »

mASMter a écrit :je ne pense pas que le problème de Kwai vienne du format de l'image
Non moi non plus....son probléme vient plutôt de la grosse boule qui sert juste à équilibrer ses deux épaules :mrgreen:
Je suis sincèrement désolé de faire chier le monde, car comme dab j'suis le seul chez qui ça marche pas :oops:

X64

Image

X86

Image

C'est peut être à cause de mon PB, qui est mal configuré quelque part, je le bidouille tellement....et l'ASM est si strict... 8O
Ce qui est sûr c'est que je m'en sert tous les jours et je n'ai pas d'autres problèmes, faut dire que je lance quasi jamais d'ASM
Si c'est juste pour moi, te casse pas la tête, je suis un cas désespéré :|
Le seul truc positif de cette histoire, c'est que ça m'a permis d'écrire dans la sacro sainte rubrique ASM 8O , c'est déjà un rêve pour moi, rien que pour ça, j'aime encore plus PB et FD 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: filtre OilPainting

Message par Micoute »

Il vaudrait mieux utiliser une boucle While ... Wend.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: filtre OilPainting

Message par manababel »

le programme ne fonctionne pas en x86 .

voici le programme sans la boucle for/next en PB.

Code : Tout sélectionner

EnableExplicit

CompilerIf #PB_Compiler_Thread = #False
   CompilerError "Enable Thread Safe mode!"
CompilerEndIf

UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=800
Global imgy=600


Global ndt_max=CountCPUs(#PB_System_ProcessCPUs )
Global ndt=ndt_max
If ndt < 1 : ndt = 1 :EndIf

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

Global Dim nr.l(256 + 256 * ndt_max)
Global Dim ng.l(256 + 256 * ndt_max)
Global Dim nb.l(256 + 256 * ndt_max)
Global Dim it.l(256 + 256 * ndt_max)

Global Dim Reg_memory.q(4*344 + (4*334)*ndt_max)
;-------------------------------------------------------------------
; sauvegarde de registres
Macro Save_reg(i)
  Protected s
  s=@reg_memory() + (4*334)*i
  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(i)
  ; restore les registres
  s=@reg_memory(i) + (4*334)*i
  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 nom_p.i , temps_p.i , x.l , y.l , r.l,g.l,b.l , i.l
  Protected lg.l , ht.l , depth.l , temps.i  , dif.l , dif1.l

  LoadImage(nom,file$)
  If Not IsImage(nom) : ProcedureReturn 0 : EndIf
   
  StartDrawing(ImageOutput(nom))
  Depth=OutputDepth()
  StopDrawing()

  If Depth=24
    CopyImage(nom,temps)
    FreeImage(nom)
    StartDrawing(ImageOutput(temps))
    temps_p = DrawingBuffer()
    lg = ImageWidth(temps)
    ht = ImageHeight(temps)
    dif = DrawingBufferPitch() - (lg*3)
    Debug dif
    StopDrawing()
    
  
    CreateImage(nom,lg,ht,32)
    StartDrawing(ImageOutput(nom))
    nom_p = DrawingBuffer()
    StopDrawing()
    
    For y=0 To ht-1
      For x=0 To lg-1
        i = ((y*lg)+x)*3
        r=PeekA(temps_p + i + 2 + dif1)
        g=PeekA(temps_p + i + 1 + dif1)
        b=PeekA(temps_p + i + 0 + dif1)
        PokeL(nom_p + ((y*lg)+x)*4 , r<<16 + g<<8 + b)
      Next
      dif1 = dif1 + dif
    Next
    
    FreeImage(temps) ; supprime l'image 24bits
    
  EndIf

  ProcedureReturn 1
EndProcedure
;-------------------------------------------------------------------

Macro sp(source,cible)
  Protected  lg , ht , lg1 , ht1 , taille
  Protected cible_p , source_p

  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht1 = ImageHeight(cible)
  lg1 = ImageWidth(cible)
  StopDrawing()

  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht = ImageHeight(source)
  lg = ImageWidth(source)
  StopDrawing()

  If lg<>lg1 Or ht<>ht1 : ProcedureReturn : EndIf
  taille = lg * ht
EndMacro

Macro returnARGB(pixel,a,r,g,b)
  a=(pixel & $ff000000)>>24
  r=(pixel & $ff0000)>>16
  g=(pixel & $ff00)>>8
  b=(pixel & $ff)
EndMacro

Macro clamp(var,min,max)
  If var<min : var = min : EndIf
  If var>max : var = max : EndIf
EndMacro

;-------------------------------------------------------------------

Procedure OilPainting_sp(i)

  Protected i2.l = 0
  Protected source.q , cible.q , start.q , stop.q , radius.q , intensity.q
  Protected x.q,y.q
  Protected pit.l , pnr.l , png.l , pnb.l
  Protected save_i.q = i
 
  pit=it()
  pnr=nr()
  png=ng()
  pnb=nb()

  source=param(i)\source
  cible=param(i)\cible
  start=param(i)\start
  stop=param(i)\stop
  radius=param(i)\radius
  intensity=param(i)\intensity

  If intensity<1 : intensity=1 :EndIf

  sp(source,cible)

  If stop > (ht-1) : stop= ht-1 : EndIf
 
 
  i = (i * 256)*4
 
  Save_reg(save_i)
 
  ;For y=start To stop
  !mov rsi,[p.v_start]
  !OilPainting_saut_boucle1:
  
    !mov r11,[p.v_pit]
    !mov r12,[p.v_pnr]
    !mov r13,[p.v_png]
    !mov r14,[p.v_pnb]
    !add r11,[p.v_i]
    !add r12,[p.v_i]
    !add r13,[p.v_i]
    !add r14,[p.v_i]
   
    !xor rax,rax ; For j=0 To intensity : nr(j)=0 : ng(j)=0 : nb(j)=0 : it(j)=0 : Next
    !xor rbx,rbx
    !mov rcx,[p.v_intensity]
    !OilPainting_reset:
      !mov [r11+rbx],eax
      !mov [r12+rbx],eax
      !mov [r13+rbx],eax
      !mov [r14+rbx],eax
      !add rbx,4
      !dec rcx
    !jnz OilPainting_reset
     
    !mov rbx,[p.v_radius] ; For yy=-radius To radius
    !neg rbx
    !OilPainting_saut_yy1:
      !mov r15,[p.v_radius] ; For xx=-radius To radius
      !neg r15
      !OilPainting_saut_xx1:
        !xor rax,rax
        !mov r8,r15;[p.v_xx]
        !cmp r8,[p.v_lg] ;clamp(px,0,lg-1)
        !cmovae r8,rax
        ;py=yy+y
        !mov r9,rbx;[p.v_yy]
        !add r9,rsi;[p.v_y]
        !cmp r9,[p.v_ht] ;clamp(py,0,ht-1)
        !cmovae r9,rax
        ;rgb = PeekL(source_p+((py*lg+px)<<2))
        !mov r10,r9 ; r9=[p.v_py]
        !imul r10,[p.v_lg]
        !add r10,r8; r8 = [p.v_px]
        !shl r10,2
        !add r10,[p.v_source_p]
        !mov eax,[r10] ; eax = argb
        ;ReturnARGB( rgb , index , r , g , b )
        !mov edx,eax
        !shr edx,24
        !and rdx,$ff ; rdx = index
        ;nb(index) = (nb(index) + b)
        !xor ecx,ecx
        !mov cl,al
        !add [r14+rdx*4],ecx     
        !shr eax,8
        ;ng(index) = (ng(index) + g)
        !mov cl,al
        !add [r13+rdx*4],ecx     
        !shr eax,8
        ;nr(index) = (nr(index) + r)
        !mov cl,al
        !add [r12+rdx*4],ecx     
        ;it(index) = (it(index) + 1)
        !mov cl,1
        !add [r11+rdx*4],ecx
      !inc r15 ;Next
      !cmp r15,[p.v_radius]
      !jle OilPainting_saut_xx1
    !inc rbx;Next
    !cmp rbx, [p.v_radius]
    !jle OilPainting_saut_yy1
   
    !xor r15,r15
    !OilPainting_saut_x1:
    ;For x=0 To lg-1 ; -----------------------------------------------------------------------------------------------------------

      !mov r8,[p.v_radius] ;For yy=-radius To radius ; -------------------------------------------------------------
      !neg r8
      !OilPainting_saut_y1:
       
        ;px=x-radius
        !xor rax,rax
        !mov rcx,r15 ; [p.v_x]
        !sub rcx,[p.v_radius]
        !cmp rcx,[p.v_lg] ;clamp(px,0,lg-1)
        !cmovae rcx,rax ; rcx=px
        ;py=yy+y
        !mov r9,r8;r8 = [p.v_yy]
        !add r9,rsi;[p.v_y]
        !cmp r9,[p.v_ht] ;clamp(py,0,ht-1)
        !cmovae r9,rax ; r9=py
        ;rgb = PeekL(source_p+((py*lg+px)<<2))
        !mov r10,r9
        !imul r10,[p.v_lg]
        !add r10,rcx;[p.v_px]
        !shl r10,2
        !add r10,[p.v_source_p]
        !mov eax,[r10] ; eax = argb
        ;ReturnARGB( rgb , index , r , g , b )
        !mov edx,eax
        !shr edx,24
        !and rdx,$ff ; rdx = index
        ;nb(index) = (nb(index) - b)
        !xor ecx,ecx
        !mov cl,al
        !sub [r14+rdx*4],ecx     
        !shr eax,8
        ;ng(index) = (ng(index) - g)
        !mov cl,al
        !sub [r13+rdx*4],ecx     
        !shr eax,8
        ;nr(index) = (nr(index) - r)
        !mov cl,al
        !sub [r12+rdx*4],ecx     
        ;it(index) = (it(index) - 1)
        !mov cl,1
        !sub [r11+rdx*4],ecx         
       
       
        ;px=x+radius+1
        !xor rax,rax
        !mov rcx,r15 ;[p.v_x]
        !add rcx,[p.v_radius]
        !inc rcx
        !cmp rcx,[p.v_lg] ;clamp(px,0,lg-1)
        !cmovae rcx,rax
        ;rgb = PeekL(source_p+((py*lg+px)<<2))
        !mov r10,r9; r9 = [p.v_py] = py=yy+y
        !imul r10,[p.v_lg]
        !add r10,rcx; rcx=[p.v_px]
        !shl r10,2
        !add r10,[p.v_source_p]
        !mov eax,[r10] ; eax = argb
        ;ReturnARGB( rgb , index , r , g , b )
        !mov edx,eax
        !shr edx,24
        !and rdx,$ff ; rdx = index
        ;nb(index) = (nb(index) + b)
        !xor ecx,ecx
        !mov cl,al
        !add [r14+rdx*4],ecx     
        !shr eax,8
        ;ng(index) = (ng(index) + g)
        !mov cl,al
        !add [r13+rdx*4],ecx     
        !shr eax,8
        ;nr(index) = (nr(index) + r)
        !mov cl,al
        !add [r12+rdx*4],ecx     
        ;it(index) = (it(index) + 1)
        !mov cl,1
        !add [r11+rdx*4],ecx
       
      !inc r8;Next
      !cmp r8,[p.v_radius]
      !jle OilPainting_saut_y1 ; -------------------------------------------------------------

       
      !xor rax,rax; j=0
      !xor r8,r8 ; r=0
      !xor r9,r9 ; g=0
      !xor r10,r10; b=0
      !OilPainting_saut_y2: ;For j=0 To intensity
        !mov edx,[r11+rax*4] ; edx = it(j)
        !cmp edx,[r11+r8*4] ; cmp it(j) , it(r)
        !cmovg r8,rax ; if  it(j) > it(r) : r = j
        !cmp edx,[r11+r9*4]
        !cmovg r9,rax
        !cmp edx,[r11+r10*4]
        !cmovg r10,rax
      !inc rax ;Next
      !cmp rax,[p.v_intensity]
      !jbe OilPainting_saut_y2     
     
      !xor rbx,rbx
      !mov ecx,[r11+r8*4] ; If it(r)>0 : r=nr(r)/(it(r)) : EndIf
      !cmp ecx,0
      !jz OilPainting_saut_r
        !mov eax,[r12+r8*4] ; eax = nr(r)
        !cqo
        !idiv ecx
        !mov bl,al
        !shl ebx,16
      !OilPainting_saut_r:
     
      !mov ecx,[r11+r9*4] ; If it(g)>0 : g=ng(g)/(it(g)) : EndIf
      !cmp ecx,0
      !jz OilPainting_saut_g
        !mov eax,[r13+r9*4] ; eax = ng(g)
        !cqo
        !idiv ecx
        !mov bh,al
      !OilPainting_saut_g:
       
      !mov ecx,[r11+r10*4] ; If it(b)>0 : b=nb(b)/(it(b)) : EndIf
      !cmp ecx,0
      !jz OilPainting_saut_b
        !mov eax,[r14+r10*4] ; eax = nb(b)
        !cqo
        !idiv ecx
        !mov bl,al
      !OilPainting_saut_b:       
     
      ;PokeL(cible_p+((y*lg+x)<<2), b)
      !xor rax,rax
      !mov eax,esi;[p.v_y]
      !imul eax,[p.v_lg]
      !add eax,r15d;[p.v_x]
      !shl eax,2
      !add rax,[p.v_cible_p]
      !mov [rax],ebx
     
    !inc r15
    !cmp r15,[p.v_lg]
    !jb OilPainting_saut_x1
    ;Next ; ----------------------------------------------------------------------------------------------------------- 
    
    !inc rsi
    !cmp rsi,[p.v_stop]
  !jb OilPainting_saut_boucle1
  ;Next
 
  Rest_Reg(save_i)
EndProcedure

;-------------------------------------------------------------------
Procedure OilPainting(source.i,cible.i,radius.l,intensity.l)

  Protected div.l , i.l , x.l , y.l
  Protected rgb.l , a.l , r.l , g.l , b.l
  Protected tt.l

  sp(source,cible)

  For y=0 To ht-1
    For x=0 To lg-1
      rgb = PeekL(source_p+((y*lg+x)<<2))
      Returnargb( rgb , a , r , g , b )
      a = (( r + g + b ) * 85)>>8
      a = (( a * intensity )>>8) & 255
      PokeL(source_p+((y*lg+x)<<2),a<<24 + (rgb & $00ffffff))
    Next
  Next

  div=ht/ndt

  For i=0 To ndt-1
    Param(i)\source=source
    Param(i)\cible=cible
    Param(i)\radius=radius
    Param(i)\intensity=intensity
    Param(i)\start=i*div
    If i = (ndt-1)
      Param(i)\stop=ht-1
    Else
      Param(i)\stop=(i*div)+div-1
    EndIf
   
    Thread(i)=CreateThread(@OilPainting_sp(),i)
  Next

  For i=0 To ndt-1
    If Thread(i) : WaitThread(thread(i)):EndIf
  Next

EndProcedure

;-------------------------------------------------------------------

If OpenWindow(0, 0, 0, imgx, imgy, "OilPainting", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define source.i=0 , cible.i=0 , t.i , file$ , nom$ , quit.l
  Define ht1.l , lg1.l

  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
      MenuItem( 1, "Load")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
   
  ScrollBarGadget(100, 50, 0, 250, 18, 0, 10, 1)
  ScrollBarGadget(101, 400, 0, 250, 18, 0, 255, 1)
   
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
       
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 100 , 101
            t=ElapsedMilliseconds()
            OilPainting(source,cible,GetGadgetState(100),GetGadgetState(101))
            t=ElapsedMilliseconds()-t
        EndSelect
       
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            If source = 0
              source = 10
            Else
              FreeImage((source))
              FreeImage((cible))
              cible = 0
            EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              If cible = 0 And source = 10
                cible = 20
                CopyImage(source,cible)
              EndIf
             
              OilPainting(source,cible,GetGadgetState(100),GetGadgetState(101))
            EndIf
           
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf
          Case 3
            ;SaveFileRequester("Save JPG", "", "", 0)
            ;If nom$ <> "" : SaveImage(cible, nom$+".jpg" ,#PB_ImagePlugin_JPEG ,10 ) : EndIf
          Case 4
            SetClipboardImage(cible)
          Case 5
            quit = 1
        EndSelect     
    EndSelect
   
    StartDrawing(WindowOutput(0))
    If cible<>0
      DrawImage(ImageID(cible),0,20)
    EndIf
    DrawText(5,2,Str(t)+"   ")
    StopDrawing()
   
  Until Quit = 1

EndIf
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: filtre OilPainting

Message par Kwai chang caine »

Comme tu as supprimé la boucle for/next j'ai la même erreur, mais cette fois il ne s'arrête pas sur la ligne "For", d'ailleurs il ne s'arrête plus nulle part 8O
Alors j'ai pensé à essayer sur une autre version la 5.72, et c'est kifkif :|
Mais j'ai trouvé mon problème, apparemment ma version X64 ne marche pas quand je veux utiliser le compilateur X64 avec mon IDE X86 8O
Je croyais qu'on pouvait faire ça.....faudra que je cherche pourquoi
En fait j'ai trouvé le probleme en lançant le code d'un autre, et en trouvant la même erreur car j'avais oublié de remettre le compilo X86 sans le faire exprès :idea:

En tout cas, merci d'avoir essayé, et excuse moi :oops:
Quand je te dis que je suis un cas désespéré :mrgreen:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
venom
Messages : 3071
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: filtre OilPainting

Message par venom »

Normalement si tu as bien configuré ton IDE dans les options du compilateur tu choisi le compilateur x64 ou x86 après l'ide lancer n'a pas d'importance (du moins je pense)








@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: filtre OilPainting

Message par Kwai chang caine »

Bah c'est ce que je croyais 8O , mais chez moi ça plante, faudrait que je réinstalle tout :oops:
Merci de ta réponse 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Répondre