Filtre graphique

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

Filtre graphique

Message par manababel »

Bonjour , je cree ce nouveau poste pour y mettre mes "nouvelles" routines.
il y aura le "filtre" est un programme de demo pour le tester.

par rapport aux programmes deja postés , il y a une option "masque" en plus,
qui permet de selectionner la zone a modifier

les inconvenients
- support seulement les processeurs 64bits (x64)
- obligation de travailler sur des images 32bits
- obligation d'ajouter une ligne "Global Dim param(256)" dans le programme principal

liste des filtres
-balance
-bend
-threshold
-boxblur
-Brightness
-color
-color_effect
-emboss
-contrast
-guillossien ( derniere mise a jour 14.07.2022)
-roberts
-prewitt
-sobel
-teinte
-convolution 3x3
-convolution 5x5
Dernière modification par manababel le sam. 16/juil./2022 19:21, modifié 3 fois.
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

filtre balance des couleur

; Balance.pbi"

Code : Tout sélectionner

;*******************************************************************************
;Titre      : Filter_Balance
;Date       : 06/03/2022
;Version PB : PureBasic 5.70 LTS
;             x64 seulement
;             Windows
;             linux - non testé
;             ios   - non testé
;
;Info       : ne fonctionne qu'avec des images 32bits ( source , cible et masque )
;             "la fonction "load_image" convertis les images 24bits en 32bits"    
;
;           : "Global Dim param(256)" est a declarer dans le programme principal
;*******************************************************************************

; NewPixel = ( BalanceLevel * Pixel ) / 256
; valeur min = 0
; valeur 'mediane' = 255
; valeur max = ? ( > 4096 )
;Filter_Balance( source , cible , rouge , vert , bleu )
;Filter_Balance( source , cible , rouge , vert , bleu , mask )

Procedure Filter_Balance_thread(i)
  
  Protected start,stop,p,s
  p=@param()
  start = (( param(3) * param(4) ) / param(5)) * i
  stop = (( param(3) * param(4) ) / param(5)) * ( i + 1 )
  If i = param(5) - 1
    If stop < (param(3) * param(4)) : stop = param(3) * param(4) : EndIf
  EndIf
  
  Protected Dim Reg_memory.q(6*8+ 4*16 ) ; (6 registes 64bits) + (4 registes 128bits)
  s=@reg_memory() ; sauvegarde des registes
  !mov rax,[p.v_s]
  !mov [rax+000],rcx
  !mov [rax+008],rdx
  !mov [rax+016],r8
  !mov [rax+024],r9
  !mov [rax+032],r10
  !mov [rax+040],r11
  !movdqu [rax+048],xmm0
  !movdqu [rax+064],xmm1
  !movdqu [rax+080],xmm2
  !movdqu [rax+096],xmm3
  
  !mov rax,[p.v_p]
  !mov rcx,[rax+16]
  !cmp rcx,0
  !jnz Filter_Balance_mask_thread_saut
    ; programme sans le mask
    !mov rcx,[rax+08] ; cible
    !mov rdx,[p.v_start]
    !pxor xmm0,xmm0
    !movq xmm1,[rax+48]  ; opt
    !punpcklwd xmm1,xmm0 ; coversion 16bits -> 32bits
    !mov rax,[rax+00] ; source
    !boucle_Filter_Balance_thread_01:
      !movd xmm2,[rax+rdx*4]
      !punpcklbw xmm2,xmm0 ; coversion 8bits -> 16bits (4X8 bits)->(4X32 bits)
      !punpcklwd xmm2,xmm0 ; coversion 16bits -> 32bits
      !pmulld xmm2,xmm1
      !psrld xmm2,8        ; >> 8
      !packusdw xmm2,xmm0  ; coversion 32bits -> 16bits
      !packuswb xmm2,xmm0  ; coversion 16bits -> 8bits
      !movd [rcx+rdx*4],xmm2
      !add rdx,1
      !cmp rdx,[p.v_stop]
    !jb boucle_Filter_Balance_thread_01 
  !jp Filter_Balance_mask_thread_end 
    
  ; programme avec le mask
  !Filter_Balance_mask_thread_saut:
    !mov rax,[p.v_p]
    !mov r8,[rax+16] ; mask
    !mov rcx,[rax+08] ; cible
    !mov rdx,[p.v_start]
    !pxor xmm0,xmm0
    !movq xmm1,[rax+48]  ; opt
    !punpcklwd xmm1,xmm0
    !mov rax,[rax+00] ; source
    !boucle_Filter_Balance_mask_thread_01:
      !mov r10d,[rax+rdx*4]
      !movd xmm2,[rax+rdx*4]
      !punpcklbw xmm2,xmm0
      !punpcklwd xmm2,xmm0
      !pmulld xmm2,xmm1
      !psrld xmm2,8
      !packusdw xmm2,xmm0
      !packuswb xmm2,xmm0
      !movd r9d,xmm2
      !mov r11d,[r8+rdx*4]
      !and r9d,r11d
      !xor r11d,$ffffffff
      !and r10d,r11d
      !or r10d,r9d
      !mov [rcx+rdx*4],r10d
      !add rdx,1
      !cmp rdx,[p.v_stop]
    !jb boucle_Filter_Balance_mask_thread_01 
    
  !Filter_Balance_mask_thread_end:
  !mov rax,[p.v_s] ; restaurtion des registres
  !mov rcx,[rax+000]
  !mov rdx,[rax+008]
  !mov r8,[rax+016]
  !mov r9,[rax+024]
  !mov r10,[rax+032]
  !mov r11,[rax+040]
  !movdqu xmm0,[rax+048]
  !movdqu xmm1,[rax+064]
  !movdqu xmm2,[rax+080]
  !movdqu xmm3,[rax+096]
  FreeArray(Reg_memory())
  
EndProcedure

    
Procedure Filter_Balance(Filter_Balance_source,Filter_Balance_cible,Filter_Balance_r,Filter_Balance_g,Filter_Balance_b,Filter_Balance_mask = 0)
  
  If Filter_Balance_cible = 0 Or Filter_Balance_source = 0 : ProcedureReturn : EndIf
  Protected thread , Psource , Pcible , Pmask , lg , ht , i
  
  thread=CountCPUs(#PB_System_CPUs)
  If thread<2:thread=1:EndIf
  
  Protected Dim tr.q(thread)
  
  StartDrawing(ImageOutput(Filter_Balance_source))
  Psource = DrawingBuffer()
  lg = ImageWidth(Filter_Balance_source)
  ht = ImageHeight(Filter_Balance_source) 
  StopDrawing()
  
  StartDrawing(ImageOutput(Filter_Balance_cible))
  Pcible = DrawingBuffer()
  StopDrawing()
  
  If Filter_Balance_mask <> 0
    StartDrawing(ImageOutput(Filter_Balance_mask))
    Pmask = DrawingBuffer()
    StopDrawing()
  EndIf
  
  param(0)=Psource
  param(1)=Pcible
  param(2)=Pmask
  param(3)=lg
  param(4)=ht
  param(5)=thread
  param(6)= ( Filter_Balance_r << 32 ) + ( Filter_Balance_g << 16 ) + Filter_Balance_b
  
  For i=0 To thread-1 : tr(i)=0 : Next
  For i=0 To thread-1
    While tr(i)=0   
        tr(i)=CreateThread(@Filter_Balance_thread(),i)
    Wend
  Next
  For i=0 To thread-1
    If IsThread(tr(i))>0 : WaitThread(tr(i)) : EndIf 
  Next
  
  FreeArray(tr())
  
  EndProcedure
Programme de test

Code : Tout sélectionner

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
  CompilerError "OS et processeurs 32 bits non supporté"
CompilerEndIf

CompilerIf #PB_Compiler_Thread = 0
  MessageRequester("multi-thread", "Option multi-thread non activé dans le compilateur"+Chr(13)+"cela peut entrainer des erreurs" ,#PB_MessageRequester_Info)
CompilerEndIf

;-- image plugins
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Global Dim param(256)

;-- include files
IncludeFile "filtres\Balance.pbi"

; 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)
    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
;------------------------------------------------------------------

;-- programme test
If OpenWindow(0, 0, 0, 800, 600, "balance", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
    MenuItem( 1, "Load Image")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
  MenuTitle("mask")
    MenuItem(6,"add mask")  
    
    TrackBarGadget(10, 10, 0, 512, 20, 0, 512 )
    TrackBarGadget(11, 10, 20, 512, 20, 0, 512 )
    TrackBarGadget(12, 10, 40, 512, 20, 0, 512 )
    SetGadgetState(10, 255)
    SetGadgetState(11, 255)
    SetGadgetState(12, 255)
   
  Repeat
    update = 0
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            var_r = GetGadgetState(10)
            update = 1
          Case 11
            var_g = GetGadgetState(11)
            update = 1
          Case 12
            var_b = GetGadgetState(12)
            update = 1

        EndSelect
                
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            source = 2
            If IsImage(source) : FreeImage(source) : EndIf
            If IsImage(cible) : FreeImage(cible) : cible = 0 : EndIf
            If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              source = 0
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              cible = 3
              If IsImage(cible) : FreeImage(cible) : EndIf
              CopyImage(source,cible)
              StartDrawing(WindowOutput(0))
              If IsImage(cible) : DrawImage(ImageID(cible),0,60) : EndIf
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
           EndIf
          
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf
            
          ;Case 3
            ;nom$ = SaveFileRequester("Save jpg", "", "", 0)
            ;If nom$ <> "" : SaveImage(cible, nom$+".jpg" ,#PB_ImagePlugin_JPEG ) : EndIf
            
          Case 4
            SetClipboardImage(cible)
            
          Case 5
            quit = 1
            
          Case 6
            If source <> 0
              StartDrawing(ImageOutput(source))
              Psource = DrawingBuffer()            
              lg = ImageWidth(source)            
              ht = ImageHeight(source) 
              StopDrawing()
              If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
              mask = 4
              CreateImage(mask,lg,ht,32)
              StartDrawing(ImageOutput(mask))
              Circle(lg/2,ht/2,ht/4,$ffffff)
              Box(lg/8,ht/8,lg/6,ht/6,$ffffff)
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
            EndIf
            
        EndSelect
      EndSelect
      
      If update = 1      
        t=ElapsedMilliseconds()
        Filter_Balance(source,cible,var_r,var_g,var_b,mask)
        t=ElapsedMilliseconds() - t
        
        StartDrawing(WindowOutput(0))
        If IsImage(cible)
          DrawImage(ImageID(cible),0,60)
          ;DrawText(750,5,Str(t)+"     ")
        EndIf
        StopDrawing()
      EndIf
      
      
  Until Event = #PB_Event_CloseWindow Or quit=1

  CloseWindow(0)

EndIf
Dernière modification par manababel le dim. 06/mars/2022 4:30, modifié 1 fois.
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

filtre bend ( similaire au filtre balance )

Bend.pbi

Code : Tout sélectionner

;*******************************************************************************
;Titre      : Filter_Bend
;Date       : 06/03/2022
;Version PB : PureBasic 5.70 LTS
;             x64 seulement
;             Windows
;             linux - non testé
;             ios   - non testé
;
;Info       : ne fonctionne qu'avec des images 32bits ( source , cible et masque )
;             "la fonction "load_image" convertis les images 24bits en 32bits"    
;
;           : "Global Dim param(256)" est a declarer dans le programme principal
;*******************************************************************************

; NewPixel = sin (i* (r-180) / 255.0 * 3.14 / 180.0 ) *127 + i
; valeur min = 0
; valeur 'mediane' = 180
; valeur max = 360
;Filter_Balance( source , cible , rouge , vert , bleu )
;Filter_Balance( source , cible , rouge , vert , bleu , mask )

Procedure Filter_Bend_thread(i)
  Protected start,stop,p,s
  p=@param()
  start = (( param(3) * param(4) ) / param(5)) * i
  stop = (( param(3) * param(4) ) / param(5)) * ( i + 1 )
  If i = param(5) - 1
    If stop < (param(3) * param(4)) : stop = param(3) * param(4) : EndIf
  EndIf

  Protected Dim Reg_memory.q(10*8) ; (10 registes 64bits)
  s=@reg_memory() ; sauvegarde des registes
  !mov rax,[p.v_s]
  !mov [rax+000],rbx
  !mov [rax+008],rcx
  !mov [rax+016],rdx
  !mov [rax+024],rdi
  !mov [rax+032],rsi
  !mov [rax+040],r8
  !mov [rax+048],r9
  !mov [rax+056],r10
  !mov [rax+064],r11
  !mov [rax+072],r12
  
  !mov rax,[p.v_p]  
  !mov rsi,[rax+00] ; source
  !mov rdi,[rax+08] ; cible
  !mov r11,[rax+16] ; mask
  !mov r8,[rax+48] ; palr
  !mov r9,[rax+56] ; palg
  !mov r10,[rax+64] ; palb
  !mov rdx,[p.v_start]
  !shl rdx,2
  !add rsi,rdx ; source = source + start
  !add rdi,rdx ; cible = cible + start
  !shr rdx,2
  !cmp r11,0
  !jnz Filter_Bend_mask_thread_saut
  
    !Boucle_Filter_Bend:
      !xor rax,rax
      !xor rbx,rbx
      !mov bl,[rsi+2]
      !mov al,[r8+rbx*8]
      !shl rax,8
      !mov bl,[rsi+1]
      !mov al,[r9+rbx*8]
      !shl rax,8
      !mov bl,[rsi+0]
      !mov al,[r10+rbx*8]
      !mov [rdi],eax
      !add rsi,4
      !add rdi,4  
      !inc rdx
      !cmp rdx,[p.v_stop]
    !jb Boucle_Filter_Bend  
  !jp Filter_Bend_mask_thread_end
    
  !Filter_Bend_mask_thread_saut:
    !Boucle_Filter_Bend_mask:
      !xor rax,rax
      !xor rbx,rbx
      !mov bl,[rsi+2]
      !mov al,[r8+rbx*8]
      !shl rax,8
      !mov bl,[rsi+1]
      !mov al,[r9+rbx*8]
      !shl rax,8
      !mov bl,[rsi+0]
      !mov al,[r10+rbx*8]
      
      !mov ebx,[rsi] 
      !mov r12d,[r11+rdx*4]
      !and eax,r12d
      !xor r12d,$ffffffff
      !and ebx,r12d 
      !or ebx,eax 
      !mov [rdi],ebx 
      
      !add rsi,4
      !add rdi,4  
      !inc rdx
      !cmp rdx,[p.v_stop]
    !jb Boucle_Filter_Bend_mask  
    
  !Filter_Bend_mask_thread_end:
  !mov rax,[p.v_s] ; restaurtion des registres
  !mov rbx,[rax+000]
  !mov rcx,[rax+008]
  !mov rdx,[rax+016]
  !mov rdi,[rax+024]
  !mov rsi,[rax+032]
  !mov r8,[rax+040]
  !mov r9,[rax+048]
  !mov r10,[rax+056]
  !mov r11,[rax+064]
  !mov r12,[rax+072]
  FreeArray(Reg_memory())
EndProcedure


Procedure Filter_Bend(Filter_Bend_source,Filter_Bend_cible,Filter_Bend_r,Filter_Bend_g,Filter_Bend_b,Filter_Bend_mask = 0)
  
  If Filter_Bend_cible = 0 Or Filter_Bend_source = 0 : ProcedureReturn : EndIf
  
  Protected thread , Psource , Pcible , Pmask , lg , ht , i , r1.f , g1.f , b1.f
  
  thread=CountCPUs(#PB_System_CPUs)
  If thread<2:thread=1:EndIf

  Protected Dim tr.q(thread)
  
  StartDrawing(ImageOutput(Filter_Bend_source))
  Psource = DrawingBuffer()
  lg = ImageWidth(Filter_Bend_source)
  ht = ImageHeight(Filter_Bend_source) 
  StopDrawing()
  
  StartDrawing(ImageOutput(Filter_Bend_cible))
  Pcible = DrawingBuffer()
  StopDrawing()
  
  If Filter_Bend_mask <> 0
    StartDrawing(ImageOutput(Filter_Bend_mask))
    Pmask = DrawingBuffer()
    StopDrawing()
  EndIf
  
  Filter_Bend_r=Filter_Bend_r-180
  Filter_Bend_g=Filter_Bend_g-180
  Filter_Bend_b=Filter_Bend_b-180
  
  r1=Filter_Bend_r/255.0*3.14/180.0
  g1=Filter_Bend_g/255.0*3.14/180.0
  b1=Filter_Bend_b/255.0*3.14/180.0
  
  Protected Dim tabr.q(255)
  Protected Dim tabg.q(255)
  Protected Dim tabb.q(255)
  Protected palr=@tabr()
  Protected palg=@tabg()
  Protected palb=@tabb()
  For i=0 To 255
    tabr(i)=Sin(i*r1)*127+i
    tabg(i)=Sin(i*g1)*127+i
    tabb(i)=Sin(i*b1)*127+i
    If tabr(i)<0 : tabr(i) = 0 : EndIf
    If tabg(i)<0 : tabg(i) = 0 : EndIf
    If tabb(i)<0 : tabb(i) = 0 : EndIf
    If tabr(i)>255 : tabr(i) = 255 : EndIf
    If tabg(i)>255 : tabg(i) = 255 : EndIf
    If tabb(i)>255 : tabb(i) = 255 : EndIf
  Next
  
  param(0)=Psource ;00
  param(1)=Pcible  ;08
  param(2)=Pmask   ;16
  param(3)=lg      ;24
  param(4)=ht      ;32
  param(5)=thread  ;40
  param(6)=@tabr() ;48
  param(7)=@tabg() ;56
  param(8)=@tabb() ;64
  
  For i=0 To thread-1 : tr(i)=0 : Next
  For i=0 To thread-1
    While tr(i)=0       
        tr(i)=CreateThread(@Filter_Bend_thread(),i)
    Wend
  Next
  For i=0 To thread-1
    If IsThread(tr(i))>0 : WaitThread(tr(i)) : EndIf 
  Next
  
  FreeArray(tr())
  FreeArray(tabr())
  FreeArray(tabg())
  FreeArray(tabb())
  EndProcedure
 
Programme de test

Code : Tout sélectionner

;-- image plugins
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Global Dim param(256)

;-- include files
IncludeFile "filtres\bend.pbi"

; 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)
    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
;------------------------------------------------------------------

;-- programme test
If OpenWindow(0, 0, 0, 800, 600, "bend", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
    MenuItem( 1, "Load Image")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
  MenuTitle("mask")
    MenuItem(6,"add mask")  
    
    TrackBarGadget(10, 10, 0, 512, 20, 0, 360 )
    TrackBarGadget(11, 10, 20, 512, 20, 0, 360 )
    TrackBarGadget(12, 10, 40, 512, 20, 0, 360 )
    SetGadgetState(10, 180)
    SetGadgetState(11, 180)
    SetGadgetState(12, 180)
    
  Repeat
    update = 0
    Event = WindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            var_r = GetGadgetState(10)
            update = 1
          Case 11
            var_g = GetGadgetState(11)
            update = 1
          Case 12
            var_b = GetGadgetState(12)
            update = 1

        EndSelect
                
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            source = 2
            If IsImage(source) : FreeImage(source) : EndIf
            If IsImage(cible) : FreeImage(cible) : cible = 0 : EndIf
            If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              source = 0
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              cible = 3
              If IsImage(cible) : FreeImage(cible) : EndIf
              CopyImage(source,cible)
              StartDrawing(WindowOutput(0))
              If IsImage(cible) : DrawImage(ImageID(cible),0,60) : EndIf
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
           EndIf
          
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf
            
          Case 4
            SetClipboardImage(cible)
            
          Case 5
            quit = 1
            
          Case 6
            If source <> 0
              StartDrawing(ImageOutput(source))
              Psource = DrawingBuffer()            
              lg = ImageWidth(source)            
              ht = ImageHeight(source) 
              StopDrawing()
              If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
              mask = 4
              CreateImage(mask,lg,ht,32)
              StartDrawing(ImageOutput(mask))
              Circle(lg/2,ht/2,ht/4,$ffffff)
              Box(lg/8,ht/8,lg/6,ht/6,$ffffff)
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
            EndIf
            
        EndSelect
      EndSelect
      
      If update = 1      
        t=ElapsedMilliseconds()
        Filter_Bend(source,cible,var_r,var_g,var_b,mask)
        t=ElapsedMilliseconds() - t
        
        StartDrawing(WindowOutput(0))
        If IsImage(cible)
          DrawImage(ImageID(cible),0,60)
          ;DrawText(750,5,Str(t)+"     ")
        EndIf
        StopDrawing()
      EndIf
      
      
  Until Event = #PB_Event_CloseWindow Or quit=1

  CloseWindow(0)

EndIf
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

filtre Black&White ( threshold filter )

BlackAndWhite.pbi

Code : Tout sélectionner

;*******************************************************************************
;Titre      : Filter_BlackAndWhite (threshold)
;Date       : 06/03/2022
;Version PB : PureBasic 5.70 LTS
;             x64 seulement
;             Windows
;             linux - non testé
;             ios   - non testé
;
;Info       : ne fonctionne qu'avec des images 32bits ( source , cible et masque )
;             "la fonction "load_image" convertis les images 24bits en 32bits"    
;
;           : "Global Dim param(256)" est a declarer dans le programme principal
;*******************************************************************************

; NewPixel = if pixel < seuil : pixel = 0 else pixel = 255 
; valeur min = 0
; valeur 'mediane' = 127
; valeur max = 255
;Filter_Balance( source , cible , rouge , vert , bleu )
;Filter_Balance( source , cible , rouge , vert , bleu , mask )

Procedure Filter_BlackAndWhite_thread(i)
  
  Protected start,stop,p,s
  p=@param()
  start = (( param(3) * param(4) ) / param(5)) * i
  stop = (( param(3) * param(4) ) / param(5)) * ( i + 1 )
  If i = param(5) - 1
    If stop < (param(3) * param(4)) : stop = param(3) * param(4) : EndIf
  EndIf
  
  Protected Dim Reg_memory.q(7*8+ 4*16 ) ; (7 registes 64bits) + (4 registes 128bits)
  s=@reg_memory() ; sauvegarde des registes
  !mov rax,[p.v_s]
  !mov [rax+000],r8
  !mov [rax+008],r9
  !mov [rax+016],r10
  !mov [rax+024],r11
  !mov [rax+032],r12
  !mov [rax+040],r13
  !mov [rax+048],rdx
  !movdqu [rax+056],xmm0
  !movdqu [rax+072],xmm1
  !movdqu [rax+088],xmm2
  !movdqu [rax+104],xmm3
  
  
  !mov rax,[p.v_p]
  !mov r8,[rax+00]  ; source
  !mov r9,[rax+08]  ; cible
  !mov r10,[rax+16]  ; mask
  !movd xmm1,[rax+48] ; opt
  !mov edx,$00808080
  !movd xmm0,edx
  !psubb xmm1,xmm0
  !mov eax,$007f7f7f
  !movd xmm3,eax  
  !mov rdx,[p.v_start] 
  
  !cmp r10,0
  !jnz Filter_BlackAndWhite_mask_saut
   
    !Filter_BlackAndWhite_thread:  
      !movd xmm0,[r8+rdx*4] 
      !psubb xmm0,xmm3  ; soustraction pour passer de (0 à 255) -> (-127 à 128)
      !pcmpgtb xmm0,xmm1 ; compare des valeurs entre -127 et 128 ( if xmm0 > xmm 1 ) return 255 else return 0 
      !movd [r9+rdx*4],xmm0 
      !inc rdx  
      !cmp rdx,[p.v_stop]
    !jb Filter_BlackAndWhite_thread  
    !jp Filter_BlackAndWhite_mask_end
    
  !Filter_BlackAndWhite_mask_saut:

    !Filter_BlackAndWhite_mask_thread:
      !mov r13d,[r8+rdx*4]
      !movd xmm0,r13d 
      !psubb xmm0,xmm3  ; soustraction pour passer de (0 à 255) -> (-127 à 128)
      !pcmpgtb xmm0,xmm1 ; compare des valeurs entre -127 et 128 ( if xmm0 > xmm 1 ) return 255 else return 0 
      
      !movd r12d,xmm0
      !mov r11d,[r10+rdx*4]
      !and r12d,r11d
      !xor r11d,$ffffffff
      !and r13d,r11d
      !or r13d,r12d
      
      !mov [r9+rdx*4],r13d 
      !inc rdx  
      !cmp rdx,[p.v_stop]
    !jb Filter_BlackAndWhite_mask_thread  
  
  !Filter_BlackAndWhite_mask_end:
  !mov rax,[p.v_s] ; restaurtion des registres
  !mov r8,[rax+000]
  !mov r9,[rax+008]
  !mov r10,[rax+016]
  !mov r11,[rax+024]
  !mov r12,[rax+032]
  !mov r13,[rax+040]
  !mov rdx,[rax+048]
  !movdqu xmm0,[rax+056]
  !movdqu xmm1,[rax+072]
  !movdqu xmm2,[rax+088]
  !movdqu xmm3,[rax+104]
  FreeArray(Reg_memory())
EndProcedure


Procedure Filter_BlackAndWhite(Filter_BlackAndWhite_source,Filter_BlackAndWhite_cible,Filter_BlackAndWhite_r,Filter_BlackAndWhite_g,Filter_BlackAndWhite_b,Filter_BlackAndWhite_mask = 0)
  
  If Filter_BlackAndWhite_cible = 0 Or Filter_BlackAndWhite_source = 0 : ProcedureReturn : EndIf
  Protected thread , Psource , Pcible , Pmask , lg , ht , i
  
  thread=CountCPUs(#PB_System_CPUs)
  If thread<2:thread=1:EndIf
  
  Protected Dim tr.q(thread)
  
  StartDrawing(ImageOutput(Filter_BlackAndWhite_source))
  Psource = DrawingBuffer()
  lg = ImageWidth(Filter_BlackAndWhite_source)
  ht = ImageHeight(Filter_BlackAndWhite_source) 
  StopDrawing()
  
  StartDrawing(ImageOutput(Filter_BlackAndWhite_cible))
  Pcible = DrawingBuffer()
  StopDrawing()
  
  If Filter_BlackAndWhite_mask <> 0
    StartDrawing(ImageOutput(Filter_BlackAndWhite_mask))
    Pmask = DrawingBuffer()
    StopDrawing()
  EndIf
  
  param(0)=Psource
  param(1)=Pcible
  param(2)=Pmask
  param(3)=lg
  param(4)=ht
  param(5)=thread
  param(6)= ( Filter_BlackAndWhite_r << 16 ) + ( Filter_BlackAndWhite_g << 8 ) + Filter_BlackAndWhite_b
  
  For i=0 To thread-1 : tr(i)=0 : Next
  For i=0 To thread-1
    While tr(i)=0   
        tr(i)=CreateThread(@Filter_BlackAndWhite_thread(),i)
    Wend
  Next
  For i=0 To thread-1
    If IsThread(tr(i))>0 : WaitThread(tr(i)) : EndIf 
  Next
  
  FreeArray(tr())
  
  EndProcedure
Programme de test

Code : Tout sélectionner

;-- image plugins
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Global Dim param(256)

;-- include files
IncludeFile "filtres\BlackAndWhite.pbi"

; 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)
    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
;------------------------------------------------------------------

;-- programme test
If OpenWindow(0, 0, 0, 800, 600, "Black&White", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
    MenuItem( 1, "Load Image")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
  MenuTitle("mask")
    MenuItem(6,"add mask")  
    
    TrackBarGadget(10, 10, 0, 512, 20, 0, 255 )
    TrackBarGadget(11, 10, 20, 512, 20, 0, 255 )
    TrackBarGadget(12, 10, 40, 512, 20, 0, 255 )
    TrackBarGadget(13, 10, 60, 512, 20, 0, 255 )
    SetGadgetState(10, 127)
    SetGadgetState(11, 127)
    SetGadgetState(12, 127)
    
  Repeat
    update = 0
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            var_r = GetGadgetState(10)
            update = 1
          Case 11
            var_g = GetGadgetState(11)
            update = 1
          Case 12
            var_b = GetGadgetState(12)
            update = 1
          Case 13
            var_r = GetGadgetState(13)
            var_g = GetGadgetState(13)
            var_b = GetGadgetState(13)
            update = 1
        EndSelect
                
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            source = 2
            If IsImage(source) : FreeImage(source) : EndIf
            If IsImage(cible) : FreeImage(cible) : cible = 0 : EndIf
            If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              source = 0
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              cible = 3
              If IsImage(cible) : FreeImage(cible) : EndIf
              CopyImage(source,cible)
              StartDrawing(WindowOutput(0))
              If IsImage(cible) : DrawImage(ImageID(cible),0,80) : EndIf
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
           EndIf
          
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf

          Case 4
            SetClipboardImage(cible)
            
          Case 5
            quit = 1
            
          Case 6
            If source <> 0
              StartDrawing(ImageOutput(source))
              Psource = DrawingBuffer()            
              lg = ImageWidth(source)            
              ht = ImageHeight(source) 
              StopDrawing()
              If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
              mask = 4
              CreateImage(mask,lg,ht,32)
              StartDrawing(ImageOutput(mask))
              Circle(lg/2,ht/2,ht/4,$ffffff)
              Box(lg/8,ht/8,lg/6,ht/6,$ffffff)
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
            EndIf
            
        EndSelect
      EndSelect
      
      If update = 1      
      t=ElapsedMilliseconds()
        Filter_BlackAndWhite(source,cible,var_r,var_g,var_b,mask)
        t=ElapsedMilliseconds() - t
        
        StartDrawing(WindowOutput(0))
        If IsImage(cible)
          DrawImage(ImageID(cible),0,80)
          DrawText(750,5,Str(t)+"     ")
        EndIf
        StopDrawing()
      EndIf
      
      
  Until Event = #PB_Event_CloseWindow Or quit=1

  CloseWindow(0)

EndIf
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

filtre Boxblur

BoxBlur.pbi

Code : Tout sélectionner

;*******************************************************************************
;Titre      : Filter_Boxblur
;Date       : 06/03/2022
;Version PB : PureBasic 5.70 LTS
;             x64 seulement
;             Windows
;             linux - non testé
;             ios   - non testé
;
;Info       : ne fonctionne qu'avec des images 32bits ( source , cible et masque )
;             "la fonction "load_image" convertis les images 24bits en 32bits"    
;
;           : "Global Dim param(256)" est a declarer dans le programme principal
;*******************************************************************************

; NewPixel = (pixel1 + pixel2 + pixelN) / N 
; scaleX
; scaleY
; pass ; nombre de passe , pour un flou correcte minimum 2
; loop ; "utilisé pour la jointure des textures" ( 0 ou 1 ) 

Procedure Filter_BoxBlur_sp1(i)
  
  Protected p , d.f , start , stop , y , pos 
  p=@param()
  
  d = 1 / param(10) ;dx
  start = ( param(4) / param(9) ) * i
  stop = ( param(4) / param(9) ) * (i + 1) - 1
  If i = (param(9) - 1) ; ndt
    If stop < ht : stop = param(4) - 1 : EndIf
  EndIf  

  ;d.f= 1 / dx
  !mov r9,[p.v_p]
  !mov r8,[r9+56];[p.v_tx]
  !pxor xmm3,xmm3
    For y=start To stop
      pos = param(1) + ( param(3) * y << 2 )

      !pxor xmm1,xmm1
      !pxor xmm2,xmm2
      For i=-param(5) To param(5)
        !mov rax,[p.v_i] ; var = PeekL( tab_tx + (i + rx) * 4 )
        !add rax,[r9+40];[p.v_rx]  ; (i + rx)
        !mov eax,[r8+rax*4] ; var = PeekL(pos + var * 4)
        !add rax,[p.v_pos]       ; r14 = (pos + var * 4)
        !movd xmm0,[rax]      ; peekl(pos + var * 4)       
        !punpcklbw xmm0,xmm3
        !punpcklwd xmm0,xmm3
        !paddd xmm2,xmm0
      Next
      
      !mov rcx,[p.v_y]
      !mov rax,[r9+24];[p.v_lg]
      !mul rcx
      !shl rax,2
      !add rax,[r9+16];[p.v_tempo]
      !mov rcx,rax
      
      !xor rdx,rdx
      !Filter_BoxBlur_bouclex:       ;For x = 0 To (lg - 1)
        !mov eax,[r8+rdx*4] ; tx(x)
        !add rax,[p.v_pos]       ; pos + var * 4
        !movd xmm0,[rax]     ; PeekL(pos + var << 4)
        !punpcklbw xmm0,xmm3
        !punpcklwd xmm0,xmm3
        
        !mov rax,rdx        ; [p.v_x]
        !add rax,[r9+80];[p.v_dx]   ; (x + dx ) 
        !mov eax,[r8+rax*4] ; PeekL(tab_tx + (x + dx) * 4 ) 
        !add rax,[p.v_pos]
        !movd xmm1,[rax]     ; (pos + var * 4)
        !punpcklbw xmm1,xmm3
        !punpcklwd xmm1,xmm3
        
        !psubd xmm2,xmm0
        !paddd xmm2,xmm1
        
        !movdqu xmm0,xmm2
        !cvtdq2ps xmm0,xmm0
        !movd xmm1,[p.v_d]
        !pshufd xmm1,xmm1,0
        !mulps xmm0,xmm1
        !cvtps2dq xmm0,xmm0
        !packusdw xmm0,xmm3
        !packuswb xmm0,xmm3
        
        !movd [rcx],xmm0
        !add rcx,4
        
        !inc rdx
        !cmp rdx,[r9+24];[p.v_lg]
      !jb Filter_BoxBlur_bouclex       ;Next 

  Next 
    
EndProcedure
  
Procedure Filter_BoxBlur_sp2(i)
    
  Protected p , d.f , start , stop , x , pos , var.q
  p=@param()
  
  var = 0
  d.f= 1 / param(11)
  start = ( param(4) / param(9) ) * i
  stop = ( param(4) / param(9) ) * (i + 1)-1
  If i = (param(9) - 1)
    If stop < param(3) : stop = param(3) - 1 : EndIf
  EndIf  
  
  !mov [p.v_var],r10
  !mov r10,[p.v_p]
  !mov r8,[r10+64];[p.v_ty]
  !pxor xmm3,xmm3
    For x=start To stop
      pos = param(2) + x*4 ; tempo

      !pxor xmm1,xmm1
      !pxor xmm2,xmm2
      For i=-param(6) To param(6)
        !mov rax,[p.v_i] ; var = PeekL( tab_tx + (i + rx) * 4 )
        !add rax,[r10+48];[p.v_ry]  ; (i + ry)
        !mov eax,[r8+rax*4] ; var = PeekL(pos + var * 4)   
        !add rax,[p.v_pos]       ; r14 = (pos + var * 4)
        !movd xmm0,[rax]      ; peekl(pos + var * 4)       
        !punpcklbw xmm0,xmm1
        !punpcklwd xmm0,xmm1
        !paddd xmm2,xmm0
      Next

      !mov rcx,[p.v_x]
      !shl rcx,2
      !add rcx,[r10+08];[p.v_cible]
      
      !xor r9,r9
      !Filter_BoxBlur_boucley:       ;For x = 0 To (lg - 1)
        !mov eax,[r8+r9*4] ; PeekL(tab_ty + y * 4 )
        !add rax,[p.v_pos]       ; pos + var * 4
        !movd xmm0,[rax]     ; PeekL(pos + var << 4)
        !punpcklbw xmm0,xmm3
        !punpcklwd xmm0,xmm3
        
        !mov rax,r9;[p.v_y]
        !add rax,[r10+88];[p.v_dy]   ; (y + dy ) 
        !mov eax,[r8+rax*4] ; PeekL(tab_tx + y * 4 )
        !add rax,[p.v_pos]
        !movd xmm1,[rax]     ; (pos + var * 4)
        
        !punpcklbw xmm1,xmm3
        !punpcklwd xmm1,xmm3
        !psubd xmm2,xmm0
        !paddd xmm2,xmm1
        !movdqu xmm0,xmm2
        !cvtdq2ps xmm0,xmm0
        !movd xmm1,[p.v_d]
        !pshufd xmm1,xmm1,0
        !mulps xmm0,xmm1 ;r1=r*d
        !cvtps2dq xmm0,xmm0
        !packusdw xmm0,xmm3
        !packuswb xmm0,xmm3
        
        !movd [rcx],xmm0
        !mov rax,[r10+24];[p.v_lg]
        !shl rax,2
        !add rcx,rax
        
        !inc r9
        !cmp r9,[r10+32];[p.v_ht]
      !jb Filter_BoxBlur_boucley       ;Next 

    Next
    !mov r10,[p.v_var]
EndProcedure  
  


Procedure Filter_BoxBlur(Filter_BoxBlur_source,Filter_BoxBlur_cible,Filter_BoxBlur_rx,Filter_BoxBlur_ry,Filter_BoxBlur_pass=2,Filter_BoxBlur_loop=0,Filter_BoxBlur_mask=0)
  
  Protected Psource , Pcible , Ptempo , lg , ht , dx , dy , k , i , thread ,taille , s
  If Filter_BoxBlur_rx < 1 : Filter_BoxBlur_rx = 1 : EndIf
  If Filter_BoxBlur_ry < 1 : Filter_BoxBlur_ry = 1 : EndIf
  If Filter_BoxBlur_pass < 1 : Filter_BoxBlur_pass = 1 : EndIf
  If Filter_BoxBlur_pass > 5 : Filter_BoxBlur_pass = 5 : EndIf
  
  If Filter_BoxBlur_cible = 0 Or Filter_BoxBlur_source = 0 : ProcedureReturn : EndIf
  
  thread=CountCPUs(#PB_System_CPUs)
  If thread<2:thread=1:EndIf

  Protected Dim tr.q(thread)
  
  StartDrawing(ImageOutput(Filter_BoxBlur_source))
  Psource = DrawingBuffer()
  lg = ImageWidth(Filter_BoxBlur_source)
  ht = ImageHeight(Filter_BoxBlur_source) 
  StopDrawing()
  
  StartDrawing(ImageOutput(Filter_BoxBlur_cible))
  Pcible = DrawingBuffer()
  StopDrawing()
  
  If Filter_BoxBlur_mask <> 0
    StartDrawing(ImageOutput(Filter_BoxBlur_mask))
    Pmask = DrawingBuffer()
    StopDrawing()
  EndIf
  
  Ptempo=AllocateMemory(lg*ht*4)
  CopyMemory(Psource , Pcible , lg*ht*4)
  
  dx = (Filter_BoxBlur_rx * 2)+1
  dy = (Filter_BoxBlur_ry * 2)+1
  
  Protected Dim tx.l(lg + dx + 1)
  Protected Dim ty.l(ht + dy + 1)
  
  If Filter_BoxBlur_loop 
    For i=0 To lg + dx
      px = i - Filter_BoxBlur_rx
      If px< 0 : px = lg - Filter_BoxBlur_rx + i : EndIf
      If px > ( lg - 1 ) : px = i - Filter_BoxBlur_rx - lg : EndIf
      tx(i) = px * 4
    Next
    For i=0 To ht + dy
      py = i - Filter_BoxBlur_ry
      If py < 0 : py = ht - Filter_BoxBlur_ry + i : EndIf
      If py > ( ht - 1 ) : py = i - Filter_BoxBlur_ry - ht : EndIf
      ty(i) = py * lg * 4
    Next 
  Else
    For i=0 To lg + dx
      px = i - Filter_BoxBlur_rx
      If px< 0 : px = 0 : EndIf
      If px > ( lg - 1 ) : px = lg - 1 : EndIf
      tx(i)= px * 4
    Next
    For i=0 To ht + dy
      py = i - Filter_BoxBlur_ry
      If py< 0 : py = 0 : EndIf
      If py > ( ht - 1 ) : py = ht - 1 : EndIf
      ty(i)= py * lg * 4
    Next
  EndIf
  
  param(1)=Pcible
  param(2)=Ptempo
  param(3)=lg
  param(4)=ht
  param(5)=Filter_BoxBlur_rx
  param(6)=Filter_BoxBlur_ry
  param(7)=@tx()
  param(8)=@ty()
  param(9)=thread
  param(10)=dx
  param(11)=dy
    
  For k = 1  To Filter_BoxBlur_pass
    
    For i=0 To thread-1 : tr(i)=0 : Next
    
    For i=0 To thread-1
      While tr(i)=0
        tr(i)=CreateThread(@Filter_BoxBlur_sp1(),i)
      Wend
    Next
    
    For i=0 To thread-1
      If IsThread(tr(i))>0
        WaitThread(tr(i))
      EndIf 
    Next
    
    
    For i=0 To thread-1
      tr(i)=0
    Next
    
    For i=0 To thread-1  
      While tr(i)=0
        tr(i)=CreateThread(@Filter_BoxBlur_sp2(),i)
      Wend
    Next
    
    For i=0 To thread-1
      If IsThread(tr(i))>0
        WaitThread(tr(i))
      EndIf 
    Next
    
  Next
  
 
  Protected Dim Reg_memory.q(3*8)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !mov [rax+000],r10
  !mov [rax+008],r11
  !mov [rax+016],r12
  
  If Filter_BoxBlur_mask<>0
    
    taille = lg * ht
    !mov rcx,[p.v_Pmask]
    !mov r8,[p.v_Psource]
    !mov r9,[p.v_Pcible]
    !xor rdx,rdx
    !saut01:
      !mov r10d,[rcx+rdx*4];,[p.v_Pmask]
      !mov r11d,[r8+rdx*4];r8,[p.v_Psource]
      !mov r12d,[r9+rdx*4];,[p.v_Pcible]
     
      !and r12d,r10d
      !xor r10d,$ffffffff
      !and r11d,r10d
      !or r11d,r12d
      !mov [r9+rdx*4],r11d
     
      !inc rdx
      !cmp rdx,[p.v_taille]
    !jb saut01
     
    !mov rax,[p.v_s]
    !mov r10,[rax+000]
    !mov r11,[rax+008]
    !mov r12,[rax+016]
  
    FreeArray(Reg_memory())
    
  EndIf
  
 
  FreeArray(tr())
  FreeArray(tx())
  FreeArray(ty())
  FreeMemory(Ptempo)
    
EndProcedure
Programme de test

Code : Tout sélectionner

;-- image plugins
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Global Dim param(256)

;-- include files
IncludeFile "filtres\boxblur.pbi"

; 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)
    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
;------------------------------------------------------------------

;-- programme test
If OpenWindow(0, 0, 0, 800, 800, "BoxBlur", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
    MenuItem( 1, "Load Image")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
  MenuTitle("mask")
    MenuItem(6,"new mask")  
    
    TrackBarGadget(10, 10, 0, 512, 20, 0, 200 )
    TrackBarGadget(11, 10, 20, 512, 20, 0, 200 )
    TrackBarGadget(12, 10, 40, 512, 20, 1, 5 )
    TrackBarGadget(13, 10, 60, 512, 20, 0, 1 )
   
  Repeat
    update = 0
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            rx = GetGadgetState(10)
            update = 1
          Case 11
            ry = GetGadgetState(11)
            update = 1
          Case 12
            pass = GetGadgetState(12)
            update = 1
          Case 13
            loop = GetGadgetState(13)
            update = 1

        EndSelect
                
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            source = 2
            If IsImage(source) : FreeImage(source) : EndIf
            If IsImage(cible) : FreeImage(cible) : cible = 0 : EndIf
            If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              source = 0
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              cible = 3
              If IsImage(cible) : FreeImage(cible) : EndIf
              CopyImage(source,cible)
              StartDrawing(WindowOutput(0))
              If IsImage(cible) : DrawImage(ImageID(cible),0,80) : EndIf
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
           EndIf
          
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf

          Case 4
            SetClipboardImage(cible)
            
          Case 5
            quit = 1
            
          Case 6
            If source <> 0
              StartDrawing(ImageOutput(source))
              Psource = DrawingBuffer()            
              lg = ImageWidth(source)            
              ht = ImageHeight(source) 
              StopDrawing()
              If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
              mask = 4
              CreateImage(mask,lg,ht,32)
              StartDrawing(ImageOutput(mask))
              Circle(lg/2,ht/2,ht/4,$ffffff)
              Box(lg/8,ht/8,lg/6,ht/6,$ffffff)
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
            EndIf
            
        EndSelect
      EndSelect
      
      If update = 1      
      t=ElapsedMilliseconds()
      Filter_BoxBlur(source,cible,rx,ry,pass,loop,mask)

        t=ElapsedMilliseconds() - t
        
        StartDrawing(WindowOutput(0))
        If IsImage(cible)
          DrawImage(ImageID(cible),0,80)
          DrawText(750,5,Str(t)+"     ")
        EndIf
        StopDrawing()
      EndIf
      
      
  Until Event = #PB_Event_CloseWindow Or quit=1

  CloseWindow(0)

EndIf
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

filtre Brightness ( similaire au filtre balance )

Brightness.pbi

Code : Tout sélectionner

;*******************************************************************************
;Titre      : Filter_Brightness
;Date       : 06/03/2022
;Version PB : PureBasic 5.70 LTS
;             x64 seulement
;             Windows
;             linux - non testé
;             ios   - non testé
;
;Info       : ne fonctionne qu'avec des images 32bits ( source , cible et masque )
;             "la fonction "load_image" convertis les images 24bits en 32bits"    
;
;           : "Global Dim param(256)" est a declarer dans le programme principal
;*******************************************************************************

; NewPixel = Ncolor = color + modif
; valeur min = 0
; valeur 'mediane' = 255
; valeur max = 512
;Filter_Balance( source , cible , rouge , vert , bleu )
;Filter_Balance( source , cible , rouge , vert , bleu , mask )

; new_color = pixel + modif
; modif = (-255 -> 255)


Procedure Filter_Brightness_thread(i)
  
  Protected tt,start,stop , p , s
  p=@param()
  
  start = (( param(3) * param(4) ) / param(5)) * i
  stop = (( param(3) * param(4) ) / param(5)) * ( i + 1 )
  If i = param(5) - 1
    If stop < (param(3) * param(4)) : stop = param(3) * param(4) : EndIf
  EndIf
  
  Protected Dim Reg_memory.q(3*8)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !mov [rax+000],r15
  !mov [rax+008],r14
  !mov [rax+016],r13
  
  !mov rax,[p.v_p]
  !mov rcx,[rax+00] ; source
  !mov rdx,[rax+08] ; cible
  !mov r15,[rax+16] ; mask
  !movq xmm0,[rax+48]  ; opt
  !pxor xmm3,xmm3
  !mov rax,[p.v_start]
  
  !cmp r15,0
  !jnz Filter_Brightness_thread_saut
  
    !Filter_Brightness_thread_1:
    !movd xmm1,[rcx+rax*4]   
        !punpcklbw xmm1,xmm3  
        !paddsw xmm1,xmm0    
        !packuswb xmm1,xmm1    
        !movd [rdx+rax*4],xmm1  
        !inc rax
        !cmp rax,[p.v_stop]
    !jb Filter_Brightness_thread_1 
  !jp Filter_Brightness_thread_end
  
  !Filter_Brightness_thread_saut:
  
    !Filter_Brightness_mask_thread_1:
      !mov r8d,[rcx+rax*4] 
      !movd xmm1,r8d
      !punpcklbw xmm1,xmm3  
      !paddsw xmm1,xmm0    
      !packuswb xmm1,xmm1   
       
      !movd r13d,xmm1 ; calcul du mask
      !mov r14d,[r15+rax*4]
      !and r13d,r14d ; modification dans le mask
      !xor r14d,$ffffffff
      !and r8d,r14d
      !or r8d,r13d ; ajout de la partie hors du mask
      
      !mov [rdx+rax*4],r8d  
      !inc rax
      !cmp rax,[p.v_stop]
    !jb Filter_Brightness_mask_thread_1 
      
    !Filter_Brightness_thread_end:
    
  !mov rax,[p.v_s]
  !mov r15,[rax+000]
  !mov r14,[rax+008]
  !mov r13,[rax+016]
  
EndProcedure

Procedure Filter_Balance(Filter_Balance_source,Filter_Balance_cible,Filter_Balance_r,Filter_Balance_g,Filter_Balance_b,Filter_Balance_mask = 0)
  
  If Filter_Balance_cible = 0 Or Filter_Balance_source = 0 : ProcedureReturn : EndIf
  
  Protected thread , Psource , Pcible , Pmask , lg , ht  , i
  
  thread=CountCPUs(#PB_System_CPUs)
  If thread<2:thread=1:EndIf
  
  Protected Dim tr.q(thread)
  
  StartDrawing(ImageOutput(Filter_Balance_source))
  Psource = DrawingBuffer()
  lg = ImageWidth(Filter_Balance_source)
  ht = ImageHeight(Filter_Balance_source) 
  StopDrawing()
  
  StartDrawing(ImageOutput(Filter_Balance_cible))
  Pcible = DrawingBuffer()
  StopDrawing()
  
  If Filter_Balance_mask <> 0
    StartDrawing(ImageOutput(Filter_Balance_mask))
    Pmask = DrawingBuffer()
    StopDrawing()
  EndIf
  
  Filter_Balance_r=Filter_Balance_r-255
  Filter_Balance_g=Filter_Balance_g-255
  Filter_Balance_b=Filter_Balance_b-255
  param(0)=Psource
  param(1)=Pcible
  param(2)=Pmask
  param(3)=lg
  param(4)=ht
  param(5)=thread
  param(6)= Filter_Balance_r<<32 + Filter_Balance_g<<16 + Filter_Balance_b
  
  For i=0 To thread-1 : tr(i)=0 : Next
  For i=0 To thread-1
    While tr(i)=0       
        tr(i)=CreateThread(@Filter_Brightness_thread(),i)
    Wend
  Next
  For i=0 To thread-1
    If IsThread(tr(i))>0 : WaitThread(tr(i)) : EndIf 
  Next
  
  FreeArray(tr())
  
  EndProcedure
Programme de test

Code : Tout sélectionner

;-- image plugins
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Global Dim param(256)

;-- include files
IncludeFile "filtres\Brightness.pbi"

; 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)
    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
;------------------------------------------------------------------

;-- programme test
If OpenWindow(0, 0, 0, 800, 600, "image processing v3", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
    MenuItem( 1, "Load Image")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
  MenuTitle("mask")
    MenuItem(6,"add mask")  
    
    TrackBarGadget(10, 10, 0, 512, 20, 0, 512 )
    TrackBarGadget(11, 10, 20, 512, 20, 0, 512 )
    TrackBarGadget(12, 10, 40, 512, 20, 0, 512 )
    TrackBarGadget(13, 10, 60, 512, 20, 0, 512 )
    SetGadgetState(10, 255)
    SetGadgetState(11, 255)
    SetGadgetState(12, 255)
    
  Repeat
    update = 0
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            var_r = GetGadgetState(10)
            update = 1
          Case 11
            var_g = GetGadgetState(11)
            update = 1
          Case 12
            var_b = GetGadgetState(12)
            update = 1
          Case 13
            var_r = GetGadgetState(13)
            var_g = GetGadgetState(13)
            var_b = GetGadgetState(13)
            update = 1

        EndSelect
                
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            source = 2
            If IsImage(source) : FreeImage(source) : EndIf
            If IsImage(cible) : FreeImage(cible) : cible = 0 : EndIf
            If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              source = 0
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              cible = 3
              If IsImage(cible) : FreeImage(cible) : EndIf
              CopyImage(source,cible)
              StartDrawing(WindowOutput(0))
              If IsImage(cible) : DrawImage(ImageID(cible),0,80) : EndIf
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
           EndIf
          
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf

          Case 4
            SetClipboardImage(cible)
            
          Case 5
            quit = 1
            
          Case 6
            If source <> 0
              StartDrawing(ImageOutput(source))
              Psource = DrawingBuffer()            
              lg = ImageWidth(source)            
              ht = ImageHeight(source) 
              StopDrawing()
              If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
              mask = 4
              CreateImage(mask,lg,ht,32)
              StartDrawing(ImageOutput(mask))
              Circle(lg/2,ht/2,ht/4,$ffffff)
              Box(lg/8,ht/8,lg/6,ht/6,$ffffff)
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
            EndIf
            
        EndSelect
      EndSelect
      
      If update = 1      
      t=ElapsedMilliseconds()
      Filter_Balance(source,cible,var_r,var_g,var_b,mask)

        t=ElapsedMilliseconds() - t
        
        StartDrawing(WindowOutput(0))
        If IsImage(cible)
          DrawImage(ImageID(cible),0,80)
          ;DrawText(750,5,Str(t)+"     ")
        EndIf
        StopDrawing()
      EndIf
      
      
  Until Event = #PB_Event_CloseWindow Or quit=1

  CloseWindow(0)

EndIf
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

filtre color ( selon l'option , passe une ou deux couleurs en "gris" )

Color.pbi

Code : Tout sélectionner

;*******************************************************************************
;Titre      : Filter_Color
;Date       : 06/03/2022
;Version PB : PureBasic 5.70 LTS
;             x64 seulement
;             Windows
;             linux - non testé
;             ios   - non testé
;
;Info       : ne fonctionne qu'avec des images 32bits ( source , cible et masque )
;             "la fonction "load_image" convertis les images 24bits en 32bits"    
;
;           : "Global Dim param(256)" est a declarer dans le programme principal
;*******************************************************************************

; NewPixel = if ColorPixel > seuil : ColorPixel = Graycolor
; option = (0 < option < 11 )
; valeur seuil min = 0
; valeur seuil 'mediane' = 0
; valeur seuil max = 127
;Filter_Color( source , cible , option , seuil )
;Filter_Color( source , cible , option , seuil , mask )

; new_color = pixel + modif
; modif = (-255 -> 255)
  
Procedure Filter_Color_thread(i)
  
  Protected start,stop,p,s 
  p=@param()

  start = (( param(3) * param(4) ) / param(5)) * i
  stop = (( param(3) * param(4) ) / param(5)) * ( i + 1 )
  If i = param(5) - 1
    If stop < (param(3) * param(4)) : stop = param(3) * param(4) : EndIf
  EndIf

  
  Protected Dim Reg_memory.q(5*8)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !mov [rax+000],r10
  !mov [rax+008],r11
  !mov [rax+016],r12
  !mov [rax+024],r13
  !mov [rax+032],r15
  
  Select param(6)
;--red < (or)
    Case 0 ; If (r<g) Or (r<b) Or (r<seuil)  then (((r+g+b)*21845)>>16)*$10101
        
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_00:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+02] ; r
      !cmp al,byte [r8+rcx*4+01] ; g
      !jb saut_Filter_Color_00_ok
      !cmp al,byte [r8+rcx*4+00] ; b
      !jb saut_Filter_Color_00_ok
      !cmp al,byte [r15+56] ; seuil
      !ja saut_Filter_Color_00_end
      !saut_Filter_Color_00_ok:
      
        !mov rax,21845 ; gray
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_00_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
    
      !saut_Filter_Color_00_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
    !jb boucle_Filter_Color_00
      
    Case 1 ; If (g<r) Or (g<b) Or (r<seuil)  then (((r+g+b)*21845)>>16)*$10101
;--green < (or)
  
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_01:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+01] ; g
      !cmp al,byte [r8+rcx*4+02] ; r
      !jb saut_Filter_Color_01_ok
      !cmp al,byte [r8+rcx*4+00] ; b
      !jb saut_Filter_Color_01_ok
      !cmp al,byte [r15+56] ; seuil
      !ja saut_Filter_Color_01_end
      !saut_Filter_Color_01_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_01_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_01_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
    !jb boucle_Filter_Color_01
    
    Case 2 ; If (b<g) Or (b<r) Or (b>seuil)
;--blue < (or)
    
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_02:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+00] ; b
      !cmp al,byte [r8+rcx*4+02] ; r
      !jb saut_Filter_Color_02_ok
      !cmp al,byte [r8+rcx*4+01] ; g
      !jb saut_Filter_Color_02_ok
      !cmp al,byte [r15+56] ; seuil
      !ja saut_Filter_Color_02_end
      !saut_Filter_Color_02_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_02_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_02_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
    !jb boucle_Filter_Color_02
;--     
;--red > (or)
  Case 3 ; If (r>g) Or (r>b) Or (r>seuil)

    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_03:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+02] ; r
      !cmp al,byte [r8+rcx*4+01] ; g
      !ja saut_Filter_Color_03_ok
      !cmp al,byte [r8+rcx*4+00] ; b
      !ja saut_Filter_Color_03_ok
      !cmp al,byte [r15+56] ; seuil
      !ja saut_Filter_Color_03_end
      !saut_Filter_Color_03_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_03_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_03_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
      !jb boucle_Filter_Color_03
      
;--green > (or)       
  Case 4  ;If (g>r) Or (g>b) Or (g>seuil)
         
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_04:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+01] ; g
      !cmp al,byte [r8+rcx*4+02] ; r
      !ja saut_Filter_Color_04_ok
      !cmp al,byte [r8+rcx*4+00] ; b
      !ja saut_Filter_Color_04_ok
      !cmp al,byte [r15+56] ; seuil
      !ja saut_Filter_Color_04_end
      !saut_Filter_Color_04_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_04_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_04_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
      !jb boucle_Filter_Color_04
      
;--blue > (or)        
    Case 5 ;If (b>r) Or (b>g) Or (g>seuil)
           
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_05:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+00] ; b
      !cmp al,byte [r8+rcx*4+02] ; r
      !ja saut_Filter_Color_05_ok
      !cmp al,byte [r8+rcx*4+01] ; g
      !ja saut_Filter_Color_05_ok
      !cmp al,byte [r15+56] ; seuil
      !ja saut_Filter_Color_05_end
      !saut_Filter_Color_05_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_05_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_05_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
      !jb boucle_Filter_Color_05
      
;-- 
;--((r<g) And (r<b))
    Case 6 ; If ((r<g) And (r<b)) Or (r<seuil)
        
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_06:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+02] ; r
      !cmp al,byte [r15+56] ; seuil
      !jb saut_Filter_Color_06_ok
      !cmp al,byte [r8+rcx*4+01] ; g
      !ja saut_Filter_Color_06_end
      !cmp al,byte [r8+rcx*4+00] ; b
      !ja saut_Filter_Color_06_end
      !saut_Filter_Color_06_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_06_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_06_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
      !jb boucle_Filter_Color_06
      
;--((g<r) And (g<b))        
    Case 7 ; If ((g<r) And (g<b)) Or (g<seuil)
        
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_07:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+01] ; g
      !cmp al,byte [r15+56] ; seuil
      !jb saut_Filter_Color_07_ok
      !cmp al,byte [r8+rcx*4+02] ; r
      !ja saut_Filter_Color_07_end
      !cmp al,byte [r8+rcx*4+00] ; b
      !ja saut_Filter_Color_07_end
      !saut_Filter_Color_07_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_07_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_07_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
      !jb boucle_Filter_Color_07
      
;--(b<gb) And (b<r)       
    Case 8 ; If (b<gb) And (b<r) Or (b<seuil)        
    
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_08:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+00] ; b
      !cmp al,byte [r15+56] ; seuil
      !jb saut_Filter_Color_08_ok
      !cmp al,byte [r8+rcx*4+02] ; r
      !ja saut_Filter_Color_08_end
      !cmp al,byte [r8+rcx*4+01] ; g
      !ja saut_Filter_Color_08_end
      !saut_Filter_Color_08_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_08_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_08_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
      !jb boucle_Filter_Color_08
;--     
;--((r>g) And (r>b))   
    Case 9 ; If ((r>g) And (r>b)) Or (r>seuil)      
      
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_09:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+02] ; r
      !cmp al,byte [r15+56] ; seuil
      !jb saut_Filter_Color_09_ok
      !cmp al,byte [r8+rcx*4+01] ; g
      !jb saut_Filter_Color_09_end
      !cmp al,byte [r8+rcx*4+00] ; b
      !jb saut_Filter_Color_09_end
      !saut_Filter_Color_09_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_09_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_09_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
      !jb boucle_Filter_Color_09
;--((g>r) And (g>b))          
    Case 10 ; If ((g>r) And (g>b)) Or (g>seuil)         
    
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_10:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+01] ; g
      !cmp al,byte [r15+56] ; seuil
      !jb saut_Filter_Color_10_ok
      !cmp al,byte [r8+rcx*4+02] ; r
      !jb saut_Filter_Color_10_end
      !cmp al,byte [r8+rcx*4+00] ; b
      !jb saut_Filter_Color_10_end
      !saut_Filter_Color_10_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_10_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_10_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
      !jb boucle_Filter_Color_10
      
;--((b>g) And (b>r))        
    Case 11 ; If ((b>g) And (b>r)) Or (b>seuil)
        
    !mov r15,[p.v_p]
    !mov r8,[r15+00] ; source
    !mov r9,[r15+08] ; cible
    !mov r10,[r15+16] ; mask
    
    !mov rcx,[p.v_start]
    !boucle_Filter_Color_11:
      !mov ebx,[r8+rcx*4]
      !mov al,[r8+rcx*4+00] ; b
      !cmp al,byte [r15+56] ; seuil
      !jb saut_Filter_Color_11_ok
      !cmp al,byte [r8+rcx*4+02] ; r
      !jb saut_Filter_Color_11_end
      !cmp al,byte [r8+rcx*4+01] ; g
      !jb saut_Filter_Color_11_end
      !saut_Filter_Color_11_ok:
      
        !mov rax,21845
        !movzx r11,bl
        !shr ebx,8
        !movzx r12,bl
        !shr ebx,8
        !movzx r13,bl
        !add r11d,r12d
        !add r11d,r13d
        !mul r11d
        !shr eax,16
        !mov ah,al
        !shl eax,8
        !mov al,ah
        !mov ebx,eax
        
        !mov eax,0
        !cmp rax,r10
        !je saut_Filter_Color_11_end 
        !mov r13d,ebx ; calcul du mask
        !mov r12d,[r10+rcx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov ebx,[r8+rcx*4]
        !and ebx,r12d
        !or ebx,r13d ; ajout de la partie hors du mask
        
      !saut_Filter_Color_11_end:
      !mov [r9+rcx*4],ebx
      !inc rcx
      !cmp rcx,[p.v_stop]
      !jb boucle_Filter_Color_11
      
;--
      
EndSelect

  !mov rax,[p.v_s]
  !mov r10,[rax+000]
  !mov r11,[rax+008]
  !mov r12,[rax+016]
  !mov r13,[rax+024]
  !mov r15,[rax+032]
  
  FreeArray(Reg_memory())
  
EndProcedure

Procedure Filter_Color(Filter_Color_source,Filter_Color_cible,Filter_Color_option,Filter_Color_seuil,Filter_Color_mask = 0)
  
  If Filter_Color_cible = 0 Or Filter_Color_source = 0 : ProcedureReturn : EndIf
  If Filter_Color_option < 0 : Filter_Color_option = 0 : EndIf
  If Filter_Color_option > 11 : Filter_Color_option = 11 : EndIf
  If Filter_Color_seuil < 0 : Filter_Color_seuil = 0 : EndIf
  If Filter_Color_seuil >255 : Filter_Color_seuil = 255 : EndIf
  
  Protected thread , Psource , Pcible , Pmask , lg , ht , opt  , i
  thread=CountCPUs(#PB_System_CPUs)
  If thread<2:thread=1:EndIf

  Protected Dim tr.q(thread)
  
  StartDrawing(ImageOutput(Filter_Color_source))
  Psource = DrawingBuffer()
  lg = ImageWidth(Filter_Color_source)
  ht = ImageHeight(Filter_Color_source) 
  StopDrawing()
  
  StartDrawing(ImageOutput(Filter_Color_cible))
  Pcible = DrawingBuffer()
  StopDrawing()
  
  If Filter_Color_mask <> 0
    StartDrawing(ImageOutput(Filter_Color_mask))
    Pmask = DrawingBuffer()
    StopDrawing()
  EndIf
  
  param(0)=Psource
  param(1)=Pcible
  param(2)=Pmask
  param(3)=lg
  param(4)=ht
  param(5)=thread
  param(6)=Filter_Color_option
  param(7)=Filter_Color_seuil
  
  For i=0 To thread-1 : tr(i)=0 : Next
  For i=0 To thread-1
    While tr(i)=0       
        tr(i)=CreateThread(@Filter_Color_thread(),i)
    Wend
  Next
  
  For i=0 To thread-1
    If IsThread(tr(i))>0 : WaitThread(tr(i)) : EndIf 
  Next
  FreeArray(tr())
  
  EndProcedure

Programme de test

Code : Tout sélectionner

;-- image plugins
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Global Dim param(256)

;-- include files
IncludeFile "filtres\color.pbi"

; 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)
    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
;------------------------------------------------------------------

;-- programme test
If OpenWindow(0, 0, 0, 900, 900, "image processing v3", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
    MenuItem( 1, "Load Image")
   ;MenuTitle("Save")   
    ;MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    ;MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
  MenuTitle("mask")
    MenuItem(6,"new mask")  
    
    TrackBarGadget(10, 10, 0, 512, 20, 0, 255 )
    
    Dim img_source(12)
    Dim img_cible(12)
    Dim img_mask(12)

    
    
  Repeat
    update = 0
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            seuil = GetGadgetState(10)
            update = 1

        EndSelect
                
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            source = 2
            For i=0 To 11
              If img_source(i) : FreeImage(img_source(i)) : img_source(i) = 0 :EndIf
              If img_cible(i) : FreeImage(img_cible(i)) : img_cible(i) = 0 : EndIf
              If img_mask(i) : FreeImage(img_mask(i)) : img_mask(i) = 0 : EndIf
            Next
            
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              source = 0
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              ResizeImage(source,300,220)
              For i=0 To 11
                img_source(i) = 100 + i
                img_cible(i) = 200 + i
                CopyImage(source,img_source(i))
                CopyImage(source,img_cible(i))
              Next
              
              cible = 3
              StartDrawing(WindowOutput(0))
              compt =0
              For y=0 To 3
                For x=0 To 2
                  If img_cible(compt)
                    DrawImage(ImageID(img_cible(compt)),x*300,40+y*200)
                  EndIf
                  compt = compt + 1
                Next
              Next
              StopDrawing()
           EndIf

          Case 5
            quit = 1
            
          Case 6
            If source <> 0
              StartDrawing(ImageOutput(source))
              Psource = DrawingBuffer()            
              lg = ImageWidth(source)            
              ht = ImageHeight(source) 
              StopDrawing()
              If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
              mask = 4
              CreateImage(mask,lg,ht,32)
              StartDrawing(ImageOutput(mask))
              Circle(lg/2,ht/2,ht/2,$ffffff)
              StopDrawing()
              For i=0 To 11
                img_mask(i) = 300 + i
                CopyImage(mask,img_mask(i))
              Next
              
            EndIf
            
        EndSelect
      EndSelect
      
      If update = 1      
        
        For i=0 To 11
          Filter_Color(img_source(i),img_cible(i),i,seuil,img_mask(i))
        Next
        
        StartDrawing(WindowOutput(0))
        ;If IsImage(cible)
              compt =0
              For y=0 To 3
                For x=0 To 2
                  If img_cible(compt)
                    DrawImage(ImageID(img_cible(compt)),x*300,40+y*200)
                  EndIf
                  compt = compt + 1
                Next
              Next
       ; EndIf
        StopDrawing()
      EndIf
      
      
  Until Event = #PB_Event_CloseWindow Or quit=1

  CloseWindow(0)

EndIf
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

filtre color_effect ( mix les couleurs entre elles )

color_effect.pbi

Code : Tout sélectionner

;*******************************************************************************
;Titre      : Filter_color_effect
;Date       : 06/03/2022
;Version PB : PureBasic 5.70 LTS
;             x64 seulement
;             Windows
;             linux - non testé
;             ios   - non testé
;
;Info       : ne fonctionne qu'avec des images 32bits ( source , cible et masque )
;             "la fonction "load_image" convertis les images 24bits en 32bits"    
;
;           : "Global Dim param(256)" est a declarer dans le programme principal
;*******************************************************************************

; NewPixel = (r + b)>1
; option = ( 0 < option < 5)
;Filter_Balance( source , cible , option )
;Filter_Balance( source , cible , option , mask )
Procedure filter_color_effect_thread(i)
  
  Protected tt,start,stop,p,s
  p=@param()
  
  tt = ( param(3) * param(4) ) / param(5)
  start = tt * i
  stop = tt * ( i + 1 )
  If i = param(5) - 1
    If stop < (param(3) * param(4)) : stop = param(3) * param(4) : EndIf
  EndIf
  
  Protected Dim Reg_memory.q(2*8)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !mov [rax+000],r10
  !mov [rax+008],r12
  !mov [rax+016],r13
  
  Select param(6)
    Case 0   
      If param(2) = 0
        !mov rax,[p.v_p]
        !mov r8,[rax+00] ; source
        !mov r9,[rax+08] ; cible
        !pxor xmm3,xmm3
        !mov edx,[p.v_start]
        !color_effect_0:
          !movd xmm0,[r8+rdx*4]
          !punpcklbw xmm0,xmm3
          !movq xmm1,xmm0
          !pshuflw xmm1,xmm1, 201
          !paddw xmm0,xmm1
          !psrlw xmm0,1
          !packuswb xmm0,xmm3     
          !movd [r9+rdx*4],xmm0
          !inc rdx
          !cmp rdx,[p.v_stop]
        !jb color_effect_0 
      Else
        !mov rax,[p.v_p]
        !mov r8,[rax+00] ; source
        !mov r9,[rax+08] ; cible
        !mov r10,[rax+16] ; mask
        !pxor xmm3,xmm3
        !mov edx,[p.v_start]
        !color_effect_0bis:
          !movd xmm0,[r8+rdx*4]
          !punpcklbw xmm0,xmm3
          !movq xmm1,xmm0
          !pshuflw xmm1,xmm1, 201
          !paddw xmm0,xmm1
          !psrlw xmm0,1
          !packuswb xmm0,xmm3   
          
          !movd ecx,xmm0
          !mov r13d,ecx  ; calcul du mask
          !mov r12d,[r10+rdx*4]
          !and r13d,r12d ; modification dans le mask
          !xor r12d,$ffffffff
          !mov ecx,[r8+rdx*4]
          !and ecx,r12d
          !or ecx,r13d ; ajout de la partie hors du mask   
 
          !mov [r9+rdx*4],ecx
          !inc rdx
          !cmp rdx,[p.v_stop]
        !jb color_effect_0bis 
      EndIf
      
    Case 1  
      If param(2) = 0
        !mov rax,[p.v_p]
        !mov r8,[rax+00] ; source
        !mov r9,[rax+08] ; cible
        !pxor xmm3,xmm3
        !mov edx,[p.v_start]
        !color_effect_1:
          !movd xmm0,[r8+rdx*4]
          !punpcklbw xmm0,xmm3
          !movq xmm1,xmm0
          !pshuflw xmm1,xmm1, 210
          !paddw xmm0,xmm1
          !psrlw xmm0,1
          !packuswb xmm0,xmm3     
          !movd [r9+rdx*4],xmm0
          !inc rdx
          !cmp rdx,[p.v_stop]
          !jb color_effect_1
      Else 
        !mov rax,[p.v_p]
        !mov r8,[rax+00] ; source
        !mov r9,[rax+08] ; cible
        !mov r10,[rax+16] ; mask
        !pxor xmm3,xmm3
        !mov edx,[p.v_start]
        !color_effect_1bis:
          !movd xmm0,[r8+rdx*4]
          !punpcklbw xmm0,xmm3
          !movq xmm1,xmm0
          !pshuflw xmm1,xmm1, 210
          !paddw xmm0,xmm1
          !psrlw xmm0,1
          !packuswb xmm0,xmm3   
          
          !movd ecx,xmm0
          !mov r13d,ecx  ; calcul du mask
          !mov r12d,[r10+rdx*4]
          !and r13d,r12d ; modification dans le mask
          !xor r12d,$ffffffff
          !mov ecx,[r8+rdx*4]
          !and ecx,r12d
          !or ecx,r13d ; ajout de la partie hors du mask
       
          !mov [r9+rdx*4],ecx
          !inc rdx
          !cmp rdx,[p.v_stop]
        !jb color_effect_1bis  
      EndIf
        
          
    Case 2  
      If param(2) = 0   
        !mov rax,[p.v_p]
        !mov r8,[rax+00] ; source
        !mov r9,[rax+08] ; cible
        !pxor xmm3,xmm3
        !mov edx,[p.v_start]
        !color_effect_2:
          !movd xmm0,[r8+rdx*4]
          !punpcklbw xmm0,xmm3
          !movq xmm1,xmm0
          !pshuflw xmm1,xmm1, 198
          !paddw xmm0,xmm1
          !psrlw xmm0,1
          !packuswb xmm0,xmm3     
          !movd [r9+rdx*4],xmm0
          !inc rdx
          !cmp rdx,[p.v_stop]
          !jb color_effect_2
      Else 
        !mov rax,[p.v_p]
        !mov r8,[rax+00] ; source
        !mov r9,[rax+08] ; cible
        !mov r10,[rax+16] ; mask
        !pxor xmm3,xmm3
        !mov edx,[p.v_start]
        !color_effect_2bis:
          !movd xmm0,[r8+rdx*4]
          !punpcklbw xmm0,xmm3
          !movq xmm1,xmm0
          !pshuflw xmm1,xmm1, 198
          !paddw xmm0,xmm1
          !psrlw xmm0,1
          !packuswb xmm0,xmm3   
          
          !movd ecx,xmm0
          !mov r13d,ecx  ; calcul du mask
          !mov r12d,[r10+rdx*4]
          !and r13d,r12d ; modification dans le mask
          !xor r12d,$ffffffff
          !mov ecx,[r8+rdx*4]
          !and ecx,r12d
          !or ecx,r13d ; ajout de la partie hors du mask
          
          !mov [r9+rdx*4],ecx
          !inc rdx
          !cmp rdx,[p.v_stop]
        !jb color_effect_2bis  
      EndIf
       
    Case 3 
      If param(2) = 0     
        !mov rax,[p.v_p]
        !mov r8,[rax+00] ; source
        !mov r9,[rax+08] ; cible
        !pxor xmm3,xmm3
        !mov edx,[p.v_start]
        !color_effect_3:
          !movd xmm0,[r8+rdx*4]
          !punpcklbw xmm0,xmm3
          !movq xmm1,xmm0
          !pshuflw xmm1,xmm1, 216
          !paddw xmm0,xmm1
          !psrlw xmm0,1
          !packuswb xmm0,xmm3     
          !movd [r9+rdx*4],xmm0
          !inc rdx
          !cmp rdx,[p.v_stop]
          !jb color_effect_3
      Else
        !mov rax,[p.v_p]
        !mov r8,[rax+00] ; source
        !mov r9,[rax+08] ; cible
        !mov r10,[rax+16] ; mask
        !pxor xmm3,xmm3
        !mov edx,[p.v_start]
        !color_effect_3bis:
          !movd xmm0,[r8+rdx*4]
          !punpcklbw xmm0,xmm3
          !movq xmm1,xmm0
          !pshuflw xmm1,xmm1, 216
          !paddw xmm0,xmm1
          !psrlw xmm0,1
          !packuswb xmm0,xmm3   
          
          !movd ecx,xmm0
          !mov r13d,ecx  ; calcul du mask
          !mov r12d,[r10+rdx*4]
          !and r13d,r12d ; modification dans le mask
          !xor r12d,$ffffffff
          !mov ecx,[r8+rdx*4]
          !and ecx,r12d
          !or ecx,r13d ; ajout de la partie hors du mask
          
          !mov [r9+rdx*4],ecx
          !inc rdx
          !cmp rdx,[p.v_stop]
        !jb color_effect_3bis  
      EndIf
       
    Case 4
      If param(2) = 0     
        !mov rax,[p.v_p]
        !mov r8,[rax+00] ; source
        !mov r9,[rax+08] ; cible
        !pxor xmm3,xmm3
        !mov edx,[p.v_start]
        !color_effect_4:
          !movd xmm0,[r8+rdx*4]
          !punpcklbw xmm0,xmm3
          !movq xmm1,xmm0
          !pshuflw xmm1,xmm1, 225
          !paddw xmm0,xmm1
          !psrlw xmm0,1
          !packuswb xmm0,xmm3     
          !movd [r9+rdx*4],xmm0
          !inc rdx
          !cmp rdx,[p.v_stop]
          !jb color_effect_4
      Else 
        !mov rax,[p.v_p]
        !mov r8,[rax+00] ; source
        !mov r9,[rax+08] ; cible
        !mov r10,[rax+16] ; mask
        !pxor xmm3,xmm3
        !mov edx,[p.v_start]
        !color_effect_4bis:
          !movd xmm0,[r8+rdx*4]
          !punpcklbw xmm0,xmm3
          !movq xmm1,xmm0
          !pshuflw xmm1,xmm1, 225
          !paddw xmm0,xmm1
          !psrlw xmm0,1
          !packuswb xmm0,xmm3   
          
          !movd ecx,xmm0
          !mov r13d,ecx  ; calcul du mask
          !mov r12d,[r10+rdx*4]
          !and r13d,r12d ; modification dans le mask
          !xor r12d,$ffffffff
          !mov ecx,[r8+rdx*4]
          !and ecx,r12d
          !or ecx,r13d ; ajout de la partie hors du mask
          
          !mov [r9+rdx*4],ecx
          !inc rdx
          !cmp rdx,[p.v_stop]
        !jb color_effect_4bis  
      EndIf 
      
    EndSelect
    
  !mov rax,[p.v_s]
  !mov r10,[rax+000]
  !mov r12,[rax+008]
  !mov r13,[rax+016]
  FreeArray(Reg_memory())
  
EndProcedure

Procedure filter_color_effect(filter_color_effect_source,filter_color_effect_cible,filter_color_effect_option,filter_color_effect_mask=0)
  
  If filter_color_effect_cible = 0 Or filter_color_effect_source = 0 : ProcedureReturn : EndIf
  If filter_color_effect_option < 0 : filter_color_effect_option = 0 : EndIf
  If filter_color_effect_option > 4 : filter_color_effect_option = 4 : EndIf
  Protected thread , Psource , Pcible , Pmask , lg , ht , opt  , i
  
  thread=CountCPUs(#PB_System_CPUs)
  If thread<2:thread=1:EndIf

  Protected Dim tr.q(thread)
  
  StartDrawing(ImageOutput(filter_color_effect_source))
  Psource = DrawingBuffer()
  lg = ImageWidth(filter_color_effect_source)
  ht = ImageHeight(filter_color_effect_source) 
  StopDrawing()
  
  StartDrawing(ImageOutput(filter_color_effect_cible))
  Pcible = DrawingBuffer()
  StopDrawing()
  
  If filter_color_effect_mask <> 0
    StartDrawing(ImageOutput(filter_color_effect_mask))
    Pmask = DrawingBuffer()
    StopDrawing()
  EndIf
  
  param(0)=Psource
  param(1)=Pcible
  param(2)=Pmask
  param(3)=lg
  param(4)=ht
  param(5)=thread
  param(6)=filter_color_effect_option
  
  For i=0 To thread-1 : tr(i)=0 : Next
   
  For i=0 To thread-1
    While tr(i)=0       
        tr(i)=CreateThread(@Filter_color_effect_thread(),i)
    Wend
  Next
  
  For i=0 To thread-1
    If IsThread(tr(i))>0 : WaitThread(tr(i)) : EndIf 
  Next
  
  FreeArray(tr())
  
  EndProcedure
Programme de test

Code : Tout sélectionner

;-- image plugins
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Global Dim param(256)

;-- include files
IncludeFile "filtres\color_effect.pbi"

; 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)
    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
;------------------------------------------------------------------

;-- programme test
If OpenWindow(0, 0, 0, 800, 800, "color_effect", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
    MenuItem( 1, "Load Image")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
  MenuTitle("mask")
    MenuItem(6,"new mask")  
    
    TrackBarGadget(10, 10, 0, 512, 20, 0, 4 )
   
  Repeat
    update = 0
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            var = GetGadgetState(10)
            update = 1

        EndSelect
                
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            source = 2
            If IsImage(source) : FreeImage(source) : EndIf
            If IsImage(cible) : FreeImage(cible) : cible = 0 : EndIf
            If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              source = 0
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              cible = 3
              If IsImage(cible) : FreeImage(cible) : EndIf
              CopyImage(source,cible)
              StartDrawing(WindowOutput(0))
              If IsImage(cible) : DrawImage(ImageID(cible),0,80) : EndIf
              StopDrawing()
              var = GetGadgetState(10)
              update = 1
           EndIf
          
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf

          Case 4
            SetClipboardImage(cible)
            
          Case 5
            quit = 1
            
          Case 6
            If source <> 0
              StartDrawing(ImageOutput(source))
              Psource = DrawingBuffer()            
              lg = ImageWidth(source)            
              ht = ImageHeight(source) 
              StopDrawing()
              If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
              mask = 4
              CreateImage(mask,lg,ht,32)
              StartDrawing(ImageOutput(mask))
              Circle(lg/2,ht/2,ht/4,$ffffff)
              Box(lg/8,ht/8,lg/6,ht/6,$ffffff)
              StopDrawing()
              var = GetGadgetState(10)
              update = 1
            EndIf
            
        EndSelect
      EndSelect
      
      If update = 1      
      t=ElapsedMilliseconds()
      Filter_Color_effect(source,cible,var,mask)

        t=ElapsedMilliseconds() - t
        
        StartDrawing(WindowOutput(0))
        If IsImage(cible)
          DrawImage(ImageID(cible),0,80)
          DrawText(750,5,Str(t)+"     ")
        EndIf
        StopDrawing()
      EndIf
      
      
  Until Event = #PB_Event_CloseWindow Or quit=1

  CloseWindow(0)

EndIf
Avatar de l’utilisateur
Guillot
Messages : 522
Inscription : jeu. 25/juin/2015 16:18

Re: Filtre graphique

Message par Guillot »

non mais c'est incroyable, un truc utile, ultra optimisé
et aucun commentaire !
t'as testé la v6 ? , ça serai bien de comparer le compilation C optimisée à l'assembleur
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

dsl , je suis un peu avard avec les commentaires.( je ne suis pas tres doué ).
non , je n'ai pas testé la v6 , la syntaxe du nouvelle "assembleur" est differente et porte à confusion ( pour moi ).
ce qui serait sympat , ca serrai qu'ils integrent les "sharders" de facon à que se sois simple a utiliser.

ps: ce n'est pas optimisé
Avatar de l’utilisateur
Guillot
Messages : 522
Inscription : jeu. 25/juin/2015 16:18

Re: Filtre graphique

Message par Guillot »

- je parlais des commentaires des membres du forum
- je parlais de comparer le code pb compilé avec le backend c (avec optimisation) et le code asm (pour les instruction 'de base' la v6 est environ 3x plus rapide)
- je sais de source sure, que la nouvelle version permettra la création de shader directement dans le code
(c'est moi qui gere les nouveautés 3d ;o)
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

je n'avais pas compris pour les commentaires . dsl.
je ne sais pas pourquoi je n'ai pas encore testé le nouvelle version de PB , peut que j'attends une version plus "definitive/aboutie" ( ??? )
cette nouvelle version de PB parait tres prometteuse .
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

filtre Emboss

emboss.pbi

Code : Tout sélectionner

;*******************************************************************************
;Titre      : Filter_enboss
;Date       : 12/03/2022
;Version PB : PureBasic 5.70 LTS
;             x64 seulement
;             Windows
;             linux - non testé
;             ios   - non testé
;
;Info       : ne fonctionne qu'avec des images 32bits ( source , cible et masque )
;             "la fonction "load_image" convertis les images 24bits en 32bits"    
;
;           : "Global Dim param(256)" est a declarer dans le programme principal
;*******************************************************************************

; NewPixel = Pixel1 - pixel2
; power : 1 < power  < 50  : default = 10 : renfore ou diminue les details
; light : 0 < lihgt  < 255 : defaut = 128 : 
; si light = 0   => similaire a un filtre detection de contour
; si light = 255 => silimaire a un filtre sketch ( dessin crayon papier)
; option: 0 < option < 35
;Filter_Emboss( source , cible , power , light , option )
;Filter_Emboss( source , cible , power , light , option , mask )

Macro Filter_Emboss_grayscale_macro()
      !PMULLd xmm0,xmm4 ; rgb = (r* $55 + g* $55 + b* $55) ; grayscale
      !pshufd xmm1,xmm0,1 ; xmm1 = g * $55
      !pshufd xmm2,xmm0,2 ; xmm2 = r * $55
      !paddd xmm0,xmm1
      !paddd xmm0,xmm2
      !psrad xmm0,8
      !movd eax,xmm0  
      !mov ecx,255 ; if eax > 255 : eax = 255 : endif
      !cmp eax,ecx
      !cmovg eax,ecx
      !mov ecx,0 ; if eax < 0 : eax = 0 : endif
      !cmp eax,ecx
      !cmovl eax,ecx
      !mov ah,al ; eax = eax * $10101
      !shl eax,8
      !mov al,ah
EndMacro

Macro Filter_Emboss_pos_macro()
    !mov rdx,r8
    !shl rdx,2
    !add rcx,rdx
    !mov ecx,[rcx]
    !mov rax,[r9+24] ; param(3)
    !mul rcx
    !shl rax,2
    !add rax,[r9+00] ; param(0)
EndMacro

Macro Filter_Emboss_pokel_macro()
    !mov rax,[r9+24]
    !mov rcx,r8
    !mul rcx
    !shl rax,2
    !add rax,[r9+08]
  EndMacro
  
  
Procedure Filter_EmbossV1(i) ; 2 pixels
  
  Protected start,stop , p , s , d.f  , p1,p2,p3

  p=@param()
  
  start =( param(4)  / param(5) ) * i
  stop = ( param(4)  / param(5) ) * ( i + 1 )
  If i = param(5) - 1
    If stop < param(4) : stop = param(4) : EndIf
  EndIf
 
  d.f = param(6)
  d = d / 10
  
  Protected Dim Reg_memory.q(3*16)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !movdqu [rax+000],xmm4
  !movdqu [rax+016],xmm5
  !movdqu [rax+032],xmm6
  
  !pxor xmm5,xmm5
  !mov eax,$55
  !movd xmm4,eax
  !pshufd xmm4,xmm4,0
  !movups xmm3,[p.v_d]
  !pshufd xmm3,xmm3,0 ; xmm3 = d : d : d : d
  
  !mov rax,[p.v_p]
  !movd xmm12,[rax+56] ; light
  !pshufd xmm12,xmm12,0 ; xmm2 = param(7)(32bits) : param(7)(32bits) : param(7)(32bits) : param(7)(32bits)
  
  ;For y=start To stop
  !mov r8,[p.v_start]
  !Filter_EmbossV1_boucle_y:
    
    !mov r9,[p.v_p]
    ;p1 = param(0) + (PeekL(param(9) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+72] ; param(9)
    Filter_Emboss_pos_macro()
    !mov [p.v_p1],rax

    ;p2 = param(0) + (PeekL(param(11) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+88] ; param(11)
    Filter_Emboss_pos_macro()
    !mov [p.v_p2],rax
    
    ;p3 = param(1) + (y * (param(3)) << 2)
    Filter_Emboss_pokel_macro()
    !mov [p.v_p3],rax
    
    !xor rdx,rdx
    !Filter_EmbossV1_boucle_x: ; For x=0 To param(3)-1 
      
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add ecx,[r9+64] ; (param(10) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p1]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add ecx,[r9+80] ; (param(12) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p2]
      !movd xmm1,[rcx]
      !punpcklbw xmm1,xmm5 ; coversion 8bits -> 16bits
      !punpcklwd xmm0,xmm5 ; coversion 16bits -> 32bits   
      !punpcklwd xmm1,xmm5 ; coversion 16bits -> 32bits  
         
      !psubd xmm0,xmm1 ;  r = (r1 - r2) : g = (g1 - g2) : b = (b1 - b2)
      !cvtdq2ps xmm0,xmm0 ; r.f = r.i : g.f = g.i : b.f = b.i
      !mulps xmm0,xmm3 ; r * d : g * d : b * d
      !cvtps2dq xmm0,xmm0 ; r.i = r.f ...
      !paddd xmm0,xmm12 ; param(7) + ( r * d ) ...
      
      Filter_Emboss_grayscale_macro()
     
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add rcx,[p.v_p3]
      !mov [rcx],eax
      
      !inc rdx
      !cmp rdx,[r9+24]
    !jb Filter_EmbossV1_boucle_x ; next
    !inc r8
    !cmp r8,[p.v_stop]
  !jb Filter_EmbossV1_boucle_y ; next
  
  !mov rax,[p.v_s]
  !movdqu xmm4,[rax+000]
  !movdqu xmm5,[rax+016]
  !movdqu xmm6,[rax+032]

  FreeArray(Reg_memory())
  
EndProcedure



Procedure Filter_EmbossV2(i) ; 3 pixerls
  
  Protected start,stop , p , s , d.f  , p1,p2,p3,p4 

  p=@param()
  
  start =( param(4)  / param(5) ) * i
  stop = ( param(4)  / param(5) ) * ( i + 1 )
  If i = param(5) - 1
    If stop < param(4) : stop = param(4) : EndIf
  EndIf
 
  d.f = param(6)
  d = d / 10
  
  Protected Dim Reg_memory.q(3*16)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !movdqu [rax+000],xmm4
  !movdqu [rax+016],xmm5
  !movdqu [rax+032],xmm6
  
  !pxor xmm5,xmm5
  !mov eax,$55
  !movd xmm4,eax
  !pshufd xmm4,xmm4,0
  !movups xmm3,[p.v_d]
  !pshufd xmm3,xmm3,0 ; xmm3 = d : d : d : d
  
  !mov rax,[p.v_p]
  !movd xmm12,[rax+56] ; light
  !pshufd xmm12,xmm12,0 ; xmm2 = param(7)(32bits) : param(7)(32bits) : param(7)(32bits) : param(7)(32bits)
    
  ;For y=start To stop
  !mov r8,[p.v_start]
  !Filter_EmbossV2_boucle_y:
  
    !mov r9,[p.v_p]
    ;p1 = param(0) + (PeekL(param(9) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+72] ; param(9)
    Filter_Emboss_pos_macro()
    !mov [p.v_p1],rax

    ;p2 = param(0) + (PeekL(param(11) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+88] ; param(11)
    Filter_Emboss_pos_macro()
    !mov [p.v_p2],rax
    
    ;p3 = param(0) + (PeekL(param(13) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+104] ; param(13)
    Filter_Emboss_pos_macro()
    !mov [p.v_p3],rax
    
    ;p4 = param(1) + (y * (param(3)) << 2)
    Filter_Emboss_pokel_macro()
    !mov [p.v_p4],rax
   
    !xor rdx,rdx
    !Filter_EmbossV2_boucle_x: ; For x=0 To param(3)-1 
      
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add ecx,[r9+64] ; (param(10) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p1]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add ecx,[r9+80] ; (param(11) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p2]
      !movd xmm1,[rcx]
      !punpcklbw xmm1,xmm5 ; coversion 8bits -> 16bits
      
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add ecx,[r9+96] ; (param(12) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p3]
      !movd xmm2,[rcx]
      !punpcklbw xmm2,xmm5 ; coversion 8bits -> 16bits
     
      !punpcklwd xmm1,xmm5 ; coversion 16bits -> 32bits  
      ;r=(param(7)+ ((r1*2)-(r2+r3)) * p)
      !paddd xmm1,xmm1 ; r2=r2*2
      !paddw xmm0,xmm2 ; r1 = r1 + r3
      !punpcklwd xmm0,xmm5 ; coversion 16bits -> 32bits 
      !psubd xmm0,xmm1 ;  r = (r1 + r3) - ( r2 * 2 )
      
      !cvtdq2ps xmm0,xmm0 ; r.f = r.i : g.f = g.i : b.f = b.i
      !mulps xmm0,xmm3 ; r * d : g * d : b * d
      !cvtps2dq xmm0,xmm0 ; r.i = r.f ...
      
      !paddd xmm0,xmm12 ; param(7) + ( r * d ) ...
      
      Filter_Emboss_grayscale_macro()
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add rcx,[p.v_p4]
      !mov [rcx],eax
      
      !inc rdx
      !cmp rdx,[r9+24]
    !jb Filter_EmbossV2_boucle_x ; next
    !inc r8
    !cmp r8,[p.v_stop]
  !jb Filter_EmbossV2_boucle_y ; next
  
  !mov rax,[p.v_s]
  !movdqu xmm4,[rax+000]
  !movdqu xmm5,[rax+016]
  !movdqu xmm6,[rax+032]

  FreeArray(Reg_memory())
  
EndProcedure


    
Procedure Filter_EmbossV3(i) ; 5 pixerls
  
  Protected start,stop , p , s , d.f  , p0,p1,p2,p3,p4,p5

  p=@param()
  
  start =( param(4)  / param(5) ) * i
  stop = ( param(4)  / param(5) ) * ( i + 1 )
  If i = param(5) - 1
    If stop < param(4) : stop = param(4) : EndIf
  EndIf
 
  d.f = param(6)
  d = d / 10
  
  Protected Dim Reg_memory.q(3*16)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !movdqu [rax+000],xmm4
  !movdqu [rax+016],xmm5
  !movdqu [rax+032],xmm6
  
  !pxor xmm5,xmm5
  !mov eax,$55
  !movd xmm4,eax
  !pshufd xmm4,xmm4,0
  !movups xmm6,[p.v_d]
  !pshufd xmm6,xmm6,0 ; xmm3 = d : d : d : d
  
  !mov rax,[p.v_p]
  !movd xmm12,[rax+56] ; light
  !pshufd xmm12,xmm12,0 ; xmm2 = param(7)(32bits) : param(7)(32bits) : param(7)(32bits) : param(7)(32bits)
    
  ;For y=start To stop
  !mov r8,[p.v_start]
  !Filter_EmbossV3_boucle_y:
  
    !mov r9,[p.v_p]
  
    ;p1 = param(0) + ( y * 4 * (param(3)) << 2)
    !mov rdx,r8
    !mov rax,[r9+24] ; param(3)
    !mul rdx
    !shl rax,2
    !add rax,[r9+00] ; param(0)
    !mov [p.v_p0],rax
    
    ;p1 = param(0) + (PeekL(param(9) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+72] ; param(9)
    Filter_Emboss_pos_macro()
    !mov [p.v_p1],rax

    ;p2 = param(0) + (PeekL(param(11) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+88] ; param(11)
    Filter_Emboss_pos_macro()
    !mov [p.v_p2],rax
    
    ;p3 = param(0) + (PeekL(param(13) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+104] ; param(13)
    Filter_Emboss_pos_macro()
    !mov [p.v_p3],rax
    
    ;p4 = param(0) + (PeekL(param(15) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+120] ; param(15)
    Filter_Emboss_pos_macro()
    !mov [p.v_p4],rax
    
    ;p5 = param(1) + (y * (param(3)) << 2)
    Filter_Emboss_pokel_macro()
    !mov [p.v_p5],rax
    
    !xor rdx,rdx
    !Filter_EmbossV3_boucle_x: ; For x=0 To param(3)-1 
    
      !pxor xmm0,xmm0
      !pxor xmm1,xmm1
      !mov r9,[p.v_p]
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add ecx,[r9+64] ; (param(10) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p1]
      !movd xmm1,[rcx]
      !punpcklbw xmm1,xmm5 ; coversion 8bits -> 16bits
      
      !mov r9,[p.v_p]
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add ecx,[r9+80] ; (param(11) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p2]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm0
      
      !mov r9,[p.v_p]
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add ecx,[r9+96] ; (param(12) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p3]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm0
      
      !mov r9,[p.v_p]
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add ecx,[r9+112] ; (param(13) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p4]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm0
      !punpcklwd xmm1,xmm5 ; coversion 16bits -> 32bits
      
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add rcx,[p.v_p0]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !punpcklwd xmm0,xmm5 ; coversion 16bits -> 32bits
      
      !paddd xmm0,xmm0
      !paddd xmm0,xmm0
      
      ;r=(param(7)+ (r0 * 4) - (r1+r2+r3+r4) 
      !psubd xmm0,xmm1 ;
      
      !cvtdq2ps xmm0,xmm0 ; r.f = r.i : g.f = g.i : b.f = b.i
      !mulps xmm0,xmm6 ; r * d : g * d : b * d
      !cvtps2dq xmm0,xmm0 ; r.i = r.f ...
      
      !paddd xmm0,xmm12 ; param(7) + ( r * d ) ...
      
      Filter_Emboss_grayscale_macro()
      
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add rcx,[p.v_p5]
      !mov [rcx],eax
      
      !mov rax,[p.v_p]
      !inc rdx
      !cmp rdx,[rax+24]
    !jb Filter_EmbossV3_boucle_x ; next
    !inc r8
    !cmp r8,[p.v_stop]
  !jb Filter_EmbossV3_boucle_y ; next
  
  
  !mov rax,[p.v_s]
  !movdqu xmm4,[rax+000]
  !movdqu xmm5,[rax+016]
  !movdqu xmm6,[rax+032]

  FreeArray(Reg_memory())
EndProcedure


    

Procedure Filter_EmbossV4(i) ; 6 pixerls
  
  Protected start,stop , p , s , d.f  , p1,p2,p3,p4,p5,p6,p7

  p=@param()
  
  start =( param(4)  / param(5) ) * i
  stop = ( param(4)  / param(5) ) * ( i + 1 )
  If i = param(5) - 1
    If stop < param(4) : stop = param(4) : EndIf
  EndIf
 
  d.f = param(6)
  d = d / 10
  
  Protected Dim Reg_memory.q(3*16)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !movdqu [rax+000],xmm4
  !movdqu [rax+016],xmm5
  !movdqu [rax+032],xmm6
  
  !pxor xmm5,xmm5
  !mov eax,$55
  !movd xmm4,eax
  !pshufd xmm4,xmm4,0
  !movups xmm6,[p.v_d]
  !pshufd xmm6,xmm6,0 ; xmm3 = d : d : d : d
  
  !mov rax,[p.v_p]
  !movd xmm12,[rax+56] ; light
  !pshufd xmm12,xmm12,0 ; xmm2 = param(7)(32bits) : param(7)(32bits) : param(7)(32bits) : param(7)(32bits)
    
  ;For y=start To stop
  !mov r8,[p.v_start]
  !Filter_EmbossV4_boucle_y:
  
    !mov r9,[p.v_p]
    
    ;p1 = param(0) + (PeekL(param(9) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+72] ; param(9)
    Filter_Emboss_pos_macro()
    !mov [p.v_p1],rax

    ;p2 = param(0) + (PeekL(param(11) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+88] ; param(11)
    Filter_Emboss_pos_macro()
    !mov [p.v_p2],rax
    
    ;p3 = param(0) + (PeekL(param(13) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+104] ; param(13)
    Filter_Emboss_pos_macro()
    !mov [p.v_p3],rax
    
    ;p4 = param(0) + (PeekL(param(15) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+120] ; param(15)
    Filter_Emboss_pos_macro()
    !mov [p.v_p4],rax
    
    ;p5 = param(0) + (PeekL(param(15) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+136] ; param(15)
    Filter_Emboss_pos_macro()
    !mov [p.v_p5],rax
    
    ;p6 = param(0) + (PeekL(param(15) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+152] ; param(15)
    Filter_Emboss_pos_macro()
    !mov [p.v_p6],rax
    
    ;p5 = param(1) + (y * (param(3)) << 2)
    Filter_Emboss_pokel_macro()
    !mov [p.v_p7],rax
    
    !xor rdx,rdx
    !Filter_EmbossV4_boucle_x: ; For x=0 To param(3)-1 
    
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !mov rax,rcx
      !add ecx,[r9+64] ; (param(10) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p1]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm0,xmm0 ; X2
      
      !mov rcx,rax
      !add ecx,[r9+80] ; (param(11) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p2]
      !movd xmm1,[rcx]
      !punpcklbw xmm1,xmm5 ; coversion 8bits -> 16bits
      
      !mov rcx,rax
      !add ecx,[r9+96] ; (param(12) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p3]
      !movd xmm2,[rcx]
      !punpcklbw xmm2,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm0,xmm1
      !paddw xmm0,xmm2
      
      !mov rcx,rax
      !add ecx,[r9+112] ; (param(13) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p4]
      !movd xmm1,[rcx]
      !punpcklbw xmm1,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm1
      
      !mov rcx,rax
      !add ecx,[r9+128] ; (param(11) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p5]
      !movd xmm2,[rcx]
      !punpcklbw xmm2,xmm5 ; coversion 8bits -> 16bits
      
      !mov rcx,rax
      !add ecx,[r9+144] ; (param(12) + x*4)
      !mov ecx,[rcx]
      !add rcx,[p.v_p6]
      !movd xmm3,[rcx]
      !punpcklbw xmm3,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm2
      !paddw xmm1,xmm3
      
      !punpcklwd xmm0,xmm5 ; coversion 16bits -> 32bits
      !punpcklwd xmm1,xmm5 ; coversion 16bits -> 32bits
      
      ;r=(param(7)+ (r0*2+r1+r2) - (r3*2+r4+r5) 
      !psubd xmm0,xmm1 ;
      
      !cvtdq2ps xmm0,xmm0 ; r.f = r.i : g.f = g.i : b.f = b.i
      !mulps xmm0,xmm6 ; r * d : g * d : b * d
      !cvtps2dq xmm0,xmm0 ; r.i = r.f ...
      
      !paddd xmm0,xmm12 ; param(7) + ( r * d ) ...
      
      Filter_Emboss_grayscale_macro()
      
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add rcx,[p.v_p7]
      !mov [rcx],eax
      
      !mov rax,[p.v_p]
      !inc rdx
      !cmp rdx,[rax+24]
    !jb Filter_EmbossV4_boucle_x ; next
    !inc r8
    !cmp r8,[p.v_stop]
  !jb Filter_EmbossV4_boucle_y ; next
  
  !mov rax,[p.v_s]
  !movdqu xmm4,[rax+000]
  !movdqu xmm5,[rax+016]
  !movdqu xmm6,[rax+032]

  FreeArray(Reg_memory())
  
EndProcedure



Procedure Filter_EmbossV5(i) ; 9 pixerls
  
  Protected start,stop , p , s , d.f  , p0,p1,p2,p3,p4,p5,p6,p7,p8,p9

  p=@param()
  
  start =( param(4)  / param(5) ) * i
  stop = ( param(4)  / param(5) ) * ( i + 1 )
  If i = param(5) - 1
    If stop < param(4) : stop = param(4) : EndIf
  EndIf

  d.f = param(6)
  d = d / 10
  
  Protected Dim Reg_memory.q(3*16)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !movdqu [rax+000],xmm4
  !movdqu [rax+016],xmm5
  !movdqu [rax+032],xmm6
  
  !pxor xmm5,xmm5
  !mov eax,$55
  !movd xmm4,eax
  !pshufd xmm4,xmm4,0
  !movups xmm6,[p.v_d]
  !pshufd xmm6,xmm6,0 ; xmm3 = d : d : d : d
  
  !mov rax,[p.v_p]
  !movd xmm12,[rax+56] ; light
  !pshufd xmm12,xmm12,0 ; xmm2 = param(7)(32bits) : param(7)(32bits) : param(7)(32bits) : param(7)(32bits)
    
  ;For y=start To stop
  !mov r8,[p.v_start]
  !Filter_EmbossV5_boucle_y:
  
    !mov r9,[p.v_p]
    
    ;p1 = param(0) + (PeekL(param(9) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+72] ; param(9)
    Filter_Emboss_pos_macro()
    !mov [p.v_p1],rax
    !mov [p.v_p2],rax
    !mov [p.v_p3],rax

    ;p2 = param(0) + (PeekL(param(11) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+88] ; param(11)
    Filter_Emboss_pos_macro()
    !mov [p.v_p4],rax
    !mov [p.v_p5],rax
    !mov [p.v_p9],rax
    
    ;p3 = param(0) + (PeekL(param(13) + y * 4) * (param(3)) << 2)
    !mov rcx,[r9+104] ; param(13)
    Filter_Emboss_pos_macro()
    !mov [p.v_p6],rax
    !mov [p.v_p7],rax
    !mov [p.v_p8],rax
    
    ;p5 = param(1) + (y * (param(3)) << 2)
    Filter_Emboss_pokel_macro()
    !mov [p.v_p0],rax

    !xor rdx,rdx
    !Filter_EmbossV5_boucle_x: ; For x=0 To param(3)-1 
      
      !mov rcx,rdx
      !shl rcx,2
      !add ecx,[r9+64] ; (param(10) + x*4)
      !mov ecx,[rcx]
      !mov eax,ecx
      !add rcx,[p.v_p1]
      !movd xmm1,[rcx]
      !punpcklbw xmm1,xmm5 ; coversion 8bits -> 16bits
      
      !mov ecx,eax
      !add rcx,[p.v_p4]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm0
      
      !mov ecx,eax
      !add rcx,[p.v_p6]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm0
      
      !mov rcx,rdx
      !shl rcx,2
      !add ecx,[r9+96] ; (param(12) + x*4)
      !mov ecx,[rcx]
      !mov eax,ecx
      !add rcx,[p.v_p3]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm0
      
      !mov ecx,eax
      !add rcx,[p.v_p5]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm0
      
      !mov ecx,eax
      !add rcx,[p.v_p8]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm0 
      
      !mov rcx,rdx
      !shl rcx,2
      !add ecx,[r9+80] ; (param(11) + x*4)
      !mov ecx,[rcx]
      !mov eax,ecx
      !add rcx,[p.v_p7]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm0
        
      !mov ecx,eax
      !add rcx,[p.v_p2]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !paddw xmm1,xmm0
      
      !mov ecx,eax
      !add rcx,[p.v_p9]
      !movd xmm0,[rcx]
      !punpcklbw xmm0,xmm5 ; coversion 8bits -> 16bits
      !punpcklwd xmm0,xmm5 ; coversion 16bits -> 32bits
      !pslld xmm0,3 ; X8
      
      !punpcklwd xmm1,xmm5 ; coversion 16bits -> 32bits
      
      ;r=(r9*8) - (r1+r2+...r7+r8) 
      !psubd xmm0,xmm1 ;
      
      !cvtdq2ps xmm0,xmm0 ; r.f = r.i : g.f = g.i : b.f = b.i
      !mulps xmm0,xmm6 ; r * d : g * d : b * d
      !cvtps2dq xmm0,xmm0 ; r.i = r.f ...
      
      !paddd xmm0,xmm12 ; param(7) + ( r * d ) ...
      
      Filter_Emboss_grayscale_macro()
      
      !mov rcx,rdx;[p.v_x]
      !shl rcx,2
      !add rcx,[p.v_p0]
      !mov [rcx],eax
      
      !inc rdx
      !cmp rdx,[r9+24]
    !jb Filter_EmbossV5_boucle_x ; next  
  
    !inc r8
    !cmp r8,[p.v_stop]
  !jb Filter_EmbossV5_boucle_y ; next
  
  !mov rax,[p.v_s]
  !movdqu xmm4,[rax+000]
  !movdqu xmm5,[rax+016]
  !movdqu xmm6,[rax+032]

  FreeArray(Reg_memory())
EndProcedure



    
Procedure Filter_Emboss(Filter_Emboss_source,Filter_Emboss_cible,Filter_Emboss_power,Filter_Emboss_light,Filter_Emboss_opt,Filter_Emboss_mask = 0)
  
  If Filter_Emboss_source = 0 Or Filter_Emboss_cible = 0 : ProcedureReturn : EndIf
    
  Protected thread , Psource , Pcible , Pmask , lg , ht , i
  thread=CountCPUs(#PB_System_CPUs)
  If thread<2:thread=1:EndIf
  Protected Dim tr.q(thread)
  
  StartDrawing(ImageOutput(Filter_Emboss_source))
   Psource = DrawingBuffer()
   lg = ImageWidth(Filter_Emboss_source)
   ht = ImageHeight(Filter_Emboss_source) 
  StopDrawing()
  
  StartDrawing(ImageOutput(Filter_Emboss_cible))
   Pcible = DrawingBuffer()
  StopDrawing()
  
  If Filter_Emboss_mask <> 0
    StartDrawing(ImageOutput(Filter_Emboss_mask))
     Pmask = DrawingBuffer()
    StopDrawing()
  EndIf
  
  Protected Dim tx1.l(lg + 3)
  Protected Dim ty1.l(ht + 3)
  Protected Dim tx2.l(lg + 3)
  Protected Dim ty2.l(ht + 3)
  Protected Dim tx3.l(lg + 3)
  Protected Dim ty3.l(ht + 3)
  Protected Dim tx4.l(lg + 3)
  Protected Dim ty4.l(ht + 3)
  Protected Dim tx5.l(lg + 3)
  Protected Dim ty5.l(ht + 3)
  Protected Dim tx6.l(lg + 3)
  Protected Dim ty6.l(ht + 3)
  
  ; coordonnees de chaque pixel pour le precalcul de position
  Select Filter_Emboss_opt
    Case 0,16
      nx1 = -1 : ny1 = -1 : nx2 = 0 : ny2 = 0 : nx3 = 1 : ny3 = 1
    Case 1,17
      nx1 = -1 : ny1 = -0 : nx2 = 0 : ny2 = 0 : nx3 = 1 : ny3 = 0
    Case 2,18
      nx1 = -1 : ny1 = 1 : nx2 = 0 : ny2 = 0 : nx3 = 1 : ny3 = -1
    Case 3,19
      nx1 = 0 : ny1 = 1 : nx2 = 0 : ny2 = 0 : nx3 = 0 : ny3 = -1
    Case 4,20
      nx1 = 1 : ny1 = 1 : nx2 = 0 : ny2 = 0 : nx3 = -1 : ny3 = -1
    Case 5,21
      nx1 = 1 : ny1 = 0 : nx2 = 0 : ny2 = 0 : nx3 = -1 : ny3 = 0
    Case 6,22
      nx1 = 1 : ny1 = -1 : nx2 = 0 : ny2 = 0 : nx3 = -1 : ny3 = 1
    Case 7,23
      nx1 = 0 : ny1 = -1 : nx2 = 0 : ny2 = 0 : nx3 = 0 : ny3 = 1
    Case 8
      nx1 = -1 : ny1 = -1 : nx2 = 1 : ny2 = 1
    Case 9
      nx1 = -1 : ny1 = -0 : nx2 = 1 : ny2 = 0
    Case 10
      nx1 = -1 : ny1 = 1 : nx2 = 1 : ny2 = -1
    Case 11
      nx1 = 0 : ny1 = 1 : nx2 = 0 : ny2 = -1
    Case 12
      nx1 = 1 : ny1 = 1 : nx2 = -1 : ny2 = -1
    Case 13
      nx1 = 1 : ny1 = 0 : nx2 = -1 : ny2 = 0
    Case 14
      nx1 = 1 : ny1 = -1 : nx2 = -1 : ny2 = 1
    Case 15
      nx1 = 0 : ny1 = -1 : nx2 = 0 : ny2 = 1
    Case 24
      nx1 = 0 : ny1 = -1 : nx2 = -1 : ny2 = -1 : nx3 = -1 : ny3 = 0
    Case 25
      nx1 = -1 : ny1 = 0 : nx2 = -1 : ny2 = 1 : nx3 = 0 : ny3 = 1
    Case 26
      nx1 = 0 : ny1 = 1 : nx2 = 1 : ny2 = 1 : nx3 = 1 : ny3 = 0
    Case 27
      nx1 = 1 : ny1 = 0 : nx2 = 1 : ny2 = -1 : nx3 = 0 : ny3 = -1
    Case 28
      nx1 = -1 : ny1 = 0 : nx2 = 0 : ny2 = 1 : nx3 = 1 : ny3 = 0 : nx4 = 0 : ny4 = -1
    Case 29
      nx1 = -1 : ny1 = 1 : nx2 = 1 : ny2 = 1 : nx3 = 1 : ny3 = -1 : nx4 = -1 : ny4 = -1
    Case 30
      nx1 = -1 : ny1 = -1 : nx2 = 0 : ny2 = -1 : nx3 = -1 : ny3 = 0 : nx4 = 1 : ny4 = 1 : nx5 = 0 : ny5 = 1 : nx6 = 1 : ny6 = 0
    Case 31
      nx1 = -1 : ny1 = 1 : nx2 = 0 : ny2 = 1 : nx3 = -1 : ny3 = 0 : nx4 = 1 : ny4 = -1 : nx5 = 0 : ny5 = -1 : nx6 = 1 : ny6 = 0
    Case 32
       nx1 = 1 : ny1 = 1 : nx2 = 0 : ny2 = 1 : nx3 = 1 : ny3 = 0 : nx4 = -1 : ny4 = -1 : nx5 = 0 : ny5 = -1 : nx6 = -1 : ny6 = 0
     Case 33
       nx1 = 1 : ny1 = -1 : nx2 = 0 : ny2 = -1 : nx3 = 1 : ny3 = 0 : nx4 = -1 : ny4 = 1 : nx5 = 0 : ny5 = 1 : nx6 = -1 : ny6 = 0
     Case 34
       nx1 = -1 : ny1 = -1 : nx2 = 0 : ny2 = 0 : nx3 = 1 : ny3 = 1
  EndSelect
  
  ;precalcul des pixel en "x" et en "y"
  ;permet supprimer les tests de depassement de chaque pixel hors "ecran"
  For i=0 To lg - 1 
    px1 = i + nx1 : If px1< 0 : px1 = 0 : EndIf : If px1 > ( lg - 1 ) : px1 = lg - 1 : EndIf : tx1(i) = px1 * 4
    px2 = i + nx2 : If px2< 0 : px2 = 0 : EndIf : If px2 > ( lg - 1 ) : px2 = lg - 1 : EndIf : tx2(i) = px2 * 4
    px3 = i + nx3 : If px3< 0 : px3 = 0 : EndIf : If px3 > ( lg - 1 ) : px3 = lg - 1 : EndIf : tx3(i) = px3 * 4
    px4 = i + nx4 : If px4< 0 : px4 = 0 : EndIf : If px4 > ( lg - 1 ) : px4 = lg - 1 : EndIf : tx4(i) = px4 * 4
    px5 = i + nx5 : If px5< 0 : px5 = 0 : EndIf : If px5 > ( lg - 1 ) : px5 = lg - 1 : EndIf : tx5(i) = px5 * 4
    px6 = i + nx6 : If px6< 0 : px6 = 0 : EndIf : If px6 > ( lg - 1 ) : px6 = lg - 1 : EndIf : tx6(i) = px6 * 4
  Next
    
  For i=0 To ht + 1
    py1 = i + ny1 : If py1 < 0 : py1 = 0 : EndIf : If py1 > ( ht - 1 ) : py1 = ht - 1 : EndIf : ty1(i) = py1
    py2 = i + ny2 : If py2 < 0 : py2 = 0 : EndIf : If py2 > ( ht - 1 ) : py2 = ht - 1 : EndIf : ty2(i) = py2
    py3 = i + ny3 : If py3 < 0 : py3 = 0 : EndIf : If py3 > ( ht - 1 ) : py3 = ht - 1 : EndIf : ty3(i) = py3
    py4 = i + ny4 : If py4 < 0 : py4 = 0 : EndIf : If py4 > ( ht - 1 ) : py4 = ht - 1 : EndIf : ty4(i) = py4
    py5 = i + ny5 : If py5 < 0 : py5 = 0 : EndIf : If py5 > ( ht - 1 ) : py5 = ht - 1 : EndIf : ty5(i) = py4
    py6 = i + ny6 : If py6 < 0 : py6 = 0 : EndIf : If py6 > ( ht - 1 ) : py6 = ht - 1 : EndIf : ty6(i) = py4
  Next 
  
  param(0)=Psource; 00
  param(1)=Pcible ; 08
  param(2)=Pmask  ; 16 
  param(3)=lg     ; 24
  param(4)=ht     ; 32
  param(5)= thread ; 40
  param(6)= Filter_Emboss_power ; 48
  param(7)= Filter_Emboss_light ; 56
  param(8)= @tx1()  ; 64
  param(9)= @ty1()  ; 72
  param(10)= @tx2() ; 80
  param(11)= @ty2() ; 88
  param(12)= @tx3() ; 96
  param(13)= @ty3() ; 104
  param(14)= @tx4() ; 112
  param(15)= @ty4() ; 120
  param(16)= @tx5() ; 128
  param(17)= @ty5() ; 136
  param(18)= @tx6() ; 144
  param(19)= @ty6() ; 152
  
  For i=0 To thread-1 : tr(i)=0 : Next
  
  Select Filter_Emboss_opt
    Case 0 To 15
      For i=0 To thread-1
        While tr(i)=0       
            tr(i)=CreateThread(@Filter_EmbossV1(),i)
        Wend
      Next
    Case 16 To 27
      For i=0 To thread-1
        While tr(i)=0       
            tr(i)=CreateThread(@Filter_EmbossV2(),i)
        Wend
      Next
    Case 28,29
      For i=0 To thread-1
        While tr(i)=0       
            tr(i)=CreateThread(@Filter_EmbossV3(),i)
        Wend
      Next
    Case 30 To 33
      For i=0 To thread-1
        While tr(i)=0       
            tr(i)=CreateThread(@Filter_EmbossV4(),i)
        Wend
      Next
    Case 34
      For i=0 To thread-1
        While tr(i)=0       
            tr(i)=CreateThread(@Filter_EmbossV5(),i)
        Wend
      Next  
  EndSelect
  
  For i=0 To thread-1
    If IsThread(tr(i))>0 : WaitThread(tr(i)) : EndIf 
  Next
  
  
  FreeArray(tr())
  
  Protected Dim Reg_memory.q(3*8)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !mov [rax+000],r10
  !mov [rax+008],r11
  !mov [rax+016],r12
  
  If Filter_Emboss_mask<>0
    
    taille = lg * ht
    !mov rcx,[p.v_Pmask]
    !mov r8,[p.v_Psource]
    !mov r9,[p.v_Pcible]
    !xor rdx,rdx
    !saut01:
      !mov r10d,[rcx+rdx*4];,[p.v_Pmask]
      !mov r11d,[r8+rdx*4];r8,[p.v_Psource]
      !mov r12d,[r9+rdx*4];,[p.v_Pcible]
     
      !and r12d,r10d
      !xor r10d,$ffffffff
      !and r11d,r10d
      !or r11d,r12d
      !mov [r9+rdx*4],r11d
     
      !inc rdx
      !cmp rdx,[p.v_taille]
    !jb saut01
     
    !mov rax,[p.v_s]
    !mov r10,[rax+000]
    !mov r11,[rax+008]
    !mov r12,[rax+016]
  
    FreeArray(Reg_memory())
    
  EndIf
  
  FreeArray(tx1())
  FreeArray(ty1())
  FreeArray(tx2())
  FreeArray(ty2())
  FreeArray(tx3())
  FreeArray(ty3())
  FreeArray(tx4())
  FreeArray(ty4())
  FreeArray(tx5())
  FreeArray(ty5())
  FreeArray(tx6())
  FreeArray(ty6())
  
EndProcedure
Programme de test

Code : Tout sélectionner

;-- image plugins
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Global Dim param(256)

;-- include files
IncludeFile "filtres\emboss.pbi"

; 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)
    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
;------------------------------------------------------------------

;-- programme test
If OpenWindow(0, 0, 0, 800, 800, "emboss", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
    MenuItem( 1, "Load Image")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
  MenuTitle("mask")
    MenuItem(6,"new mask")  
    
  TrackBarGadget(10, 10, 0, 512, 20, 1, 50 )
    TrackBarGadget(11, 10, 20, 512, 20, 0, 255 )
    TrackBarGadget(12, 10, 40, 512, 20, 0, 34 )
    SetGadgetState(10, 10)
    SetGadgetState(11, 128)
    SetGadgetState(12, 0)
   
  Repeat
    update = 0
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            power = GetGadgetState(10)
            update = 1
          Case 11
            light= GetGadgetState(11)
            update = 1
          Case 12
            option = GetGadgetState(12)
            update = 1
          Case 13
            opt2 = GetGadgetState(13)
            update = 1

        EndSelect
                
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            source = 2
            If IsImage(source) : FreeImage(source) : EndIf
            If IsImage(cible) : FreeImage(cible) : cible = 0 : EndIf
            If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              source = 0
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              cible = 3
              If IsImage(cible) : FreeImage(cible) : EndIf
              CopyImage(source,cible)
              StartDrawing(WindowOutput(0))
              If IsImage(cible) : DrawImage(ImageID(cible),0,80) : EndIf
              StopDrawing()
              power = GetGadgetState(10)
              light = GetGadgetState(11)
              option = GetGadgetState(12)
              update = 1
           EndIf
          
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf

          Case 4
            SetClipboardImage(cible)
            
          Case 5
            quit = 1
            
          Case 6
            If source <> 0
              StartDrawing(ImageOutput(source))
              Psource = DrawingBuffer()            
              lg = ImageWidth(source)            
              ht = ImageHeight(source) 
              StopDrawing()
              If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
              mask = 4
              CreateImage(mask,lg,ht,32)
              StartDrawing(ImageOutput(mask))
              Circle(lg/2,ht/2,ht/4,$ffffff)
              Box(lg/8,ht/8,lg/6,ht/6,$ffffff)
              StopDrawing()
              var_r = GetGadgetState(10)
              var_g = GetGadgetState(11)
              var_b = GetGadgetState(12)
              update = 1
            EndIf
            
        EndSelect
      EndSelect
      
      If update = 1      
      t=ElapsedMilliseconds()
      Filter_Emboss(source,cible,power,light,option,mask)

        t=ElapsedMilliseconds() - t
        
        StartDrawing(WindowOutput(0))
        If IsImage(cible)
          DrawImage(ImageID(cible),0,80)
          ;DrawText(750,5,Str(t)+"     ")
        EndIf
        StopDrawing()
      EndIf
      
      
  Until Event = #PB_Event_CloseWindow Or quit=1

  CloseWindow(0)

EndIf

manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

filtre contrast

Code : Tout sélectionner

;*******************************************************************************
;Titre : Filter contrat
;Date : 26/03/2022
;Version PB : PureBasic 5.70 LTS
; x64 seulement
; Windows
; linux - non testé
; ios - non testé
;
;Info : ne fonctionne qu'avec des images 32bits ( source , cible et masque )
; "la fonction "load_image" convertis les images 24bits en 32bits"
;
; : "Global Dim param(256)" est a declarer dans le programme principal
;*******************************************************************************

; NewPixel = (pixel+(contrast-128)/255*(pixel-127))
; r,g,b : 0 < r,g,b< 1024 : default = 256

;Filter_Contrast( source , cible , r, g , b )
;Filter_Contrast( source , cible , r , g , b , mask )

;np=(p+(opt-128)/255*(p-127))
Procedure Filter_Contrast_mask_thread(i)

  Protected start,stop,p,s
  p=@param()
  start = (( param(3) * param(4) ) / param(5)) * i
  stop = (( param(3) * param(4) ) / param(5)) * ( i + 1 )
  If i = param(5) - 1
    If stop < (param(3) * param(4)) : stop = param(3) * param(4) : EndIf
  EndIf
  
  p=param()
  
  Protected Dim Reg_memory.q(4*4 + 3*16)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !mov [rax+00],r10
  !mov [rax+08],r11
  !mov [rax+16],r12
  !mov [rax+24],r13
  !movdqu [rax+032],xmm4
  !movdqu [rax+048],xmm5
  !movdqu [rax+064],xmm6
  
  !mov rdx,[p.v_p]
  !mov ecx,[rdx+64]; param(6) = option r
  !mov [rax+00],ecx
  !mov ecx,[rdx+56]; param(7) = option g
  !mov [rax+04],ecx
  !mov ecx,[rdx+48]; param(8) = option b
  !mov [rax+08],ecx
  !movdqu xmm4,[rax+00]
  !cvtdq2ps xmm4,xmm4
  
  !pxor xmm3,xmm3
  !mov eax,127
  !movd xmm5,eax
  !pshufd xmm5,xmm5,0
  !cvtdq2ps xmm5,xmm5
  
  !mov eax,255
  !movd xmm6,eax
  !pshufd xmm6,xmm6,0
  !cvtdq2ps xmm6,xmm6
  
  !mov rax,[p.v_p]
  !mov r8,[rax+00] ; source
  !mov r9,[rax+08] ; cible
  !mov r10,[rax+16] ; mask
  !mov rdx,[p.v_start]
  !Filter_Contrast_boucle_mask:
    !movd xmm0,[r8+rdx*4]
    !punpcklbw xmm0,xmm3 ; coversion 8bits -> 16bits
    !punpcklwd xmm0,xmm3 ; coversion 16bits -> 32bits 
    !cvtdq2ps xmm0,xmm0
    !movups xmm1,xmm0 ; save (pixel) 
    !movups xmm2,xmm4 ; save xmm13 ( opt )
    !subps xmm0,xmm5 ; ( pixel - 127 )
    !divps xmm2,xmm6 ; option / 255
    !mulps xmm2,xmm0  ; (option /255) * ( pixel - 127 )
    !addps xmm1,xmm2 
    !cvtps2dq xmm1,xmm1
    !packusdw xmm1,xmm3
    !packuswb xmm1,xmm3
   
        !movd r13d,xmm1 ; calcul du mask
        !mov r12d,[r10+rdx*4]
        !and r13d,r12d ; modification dans le mask
        !xor r12d,$ffffffff
        !mov r11d,[r8+rdx*4]
        !and r11d,r12d
        !or r11d,r13d ; ajout de la partie hors du mask
      
    !mov [r9+rdx*4],r11d
    !inc rdx
    !cmp rdx,[p.v_stop]
  !jb Filter_Contrast_boucle_mask     
  
  !mov rax,[p.v_s]
  !mov r10,[rax+00]
  !mov r11,[rax+08]
  !mov r12,[rax+16]
  !mov r13,[rax+24]
  !movdqu xmm4,[rax+032]
  !movdqu xmm5,[rax+048]
  !movdqu xmm6,[rax+064]
  FreeArray(Reg_memory())
  
  
EndProcedure



Procedure Filter_Contrast_thread(i)

  Protected start,stop,p,s
  p=@param()
  start = (( param(3) * param(4) ) / param(5)) * i
  stop = (( param(3) * param(4) ) / param(5)) * ( i + 1 )
  If i = param(5) - 1
    If stop < (param(3) * param(4)) : stop = param(3) * param(4) : EndIf
  EndIf
  
  p=param()
  
  Protected Dim Reg_memory.q(4*4 + 3*16)
  s=@reg_memory()
  !mov rax,[p.v_s]
  !movdqu [rax+016],xmm4
  !movdqu [rax+032],xmm5
  !movdqu [rax+048],xmm6
  
  !mov rdx,[p.v_p]
  !mov ecx,[rdx+64]; param(6) = option r
  !mov [rax+00],ecx
  !mov ecx,[rdx+56]; param(7) = option g
  !mov [rax+04],ecx
  !mov ecx,[rdx+48]; param(8) = option b
  !mov [rax+08],ecx
  !movdqu xmm4,[rax+00]
  !cvtdq2ps xmm4,xmm4
  
  !pxor xmm3,xmm3
  !mov eax,127
  !movd xmm5,eax
  !pshufd xmm5,xmm5,0
  !cvtdq2ps xmm5,xmm5
  
  !mov eax,255
  !movd xmm6,eax
  !pshufd xmm6,xmm6,0
  !cvtdq2ps xmm6,xmm6
  
  !mov rax,[p.v_p]
  !mov r8,[rax+00]
  !mov r9,[rax+08]
  !mov rdx,[p.v_start]
  !Filter_Contrast_boucle:
    !movd xmm0,[r8+rdx*4]
    !punpcklbw xmm0,xmm3 ; coversion 8bits -> 16bits
    !punpcklwd xmm0,xmm3 ; coversion 16bits -> 32bits 
    !cvtdq2ps xmm0,xmm0 ; xmm0.f = xmm0.i
    !movups xmm1,xmm0 ; save (pixel) 
    !movups xmm2,xmm4 ; save xmm13 ( opt )
    !subps xmm0,xmm5 ; ( pixel - 127 )
    !divps xmm2,xmm6 ; option / 255
    !mulps xmm2,xmm0  ; (option /255) * ( pixel - 127 )
    !addps xmm1,xmm2 
    !cvtps2dq xmm1,xmm1 ; xmm0.i = xmm0.f
    !packusdw xmm1,xmm3 ; conversion 32bits -> 16bits
    !packuswb xmm1,xmm3 ; conversion 16bits -> 8bits
    !movd [r9+rdx*4],xmm1
    !inc rdx
    !cmp rdx,[p.v_stop]
  !jb Filter_Contrast_boucle     
  
  !mov rax,[p.v_s]
  !movdqu xmm4,[rax+016]
  !movdqu xmm5,[rax+032]
  !movdqu xmm6,[rax+048]
  FreeArray(Reg_memory())
  
  
EndProcedure



Procedure Filter_Contrast(Filter_Contrast_source,Filter_Contrast_cible,Filter_Contrast_r,Filter_Contrast_g,Filter_Contrast_b,Filter_Contrast_mask = 0)
  
  If Filter_Contrast_cible = 0 Or Filter_Contrast_source = 0 : ProcedureReturn : EndIf
  
  Protected thread , Psource , Pcible , Pmask , lg , ht , i  ;
  
  thread=CountCPUs(#PB_System_CPUs)
  If thread<2:thread=1:EndIf
  Protected Dim tr.q(thread)
  
  StartDrawing(ImageOutput(Filter_Contrast_source))
  Psource = DrawingBuffer()
  lg = ImageWidth(Filter_Contrast_source)
  ht = ImageHeight(Filter_Contrast_source) 
  StopDrawing()
  
  StartDrawing(ImageOutput(Filter_Contrast_cible))
  Pcible = DrawingBuffer()
  StopDrawing()
  
  If Filter_Contrast_mask <> 0
    StartDrawing(ImageOutput(Filter_Contrast_mask))
    Pmask = DrawingBuffer()
    StopDrawing()
  EndIf
  
  param(0)=Psource ;00
  param(1)=Pcible  ;08
  param(2)=Pmask   ;16
  param(3)=lg      ;24
  param(4)=ht      ;32
  param(5)=thread  ;40
  param(6)= Filter_Contrast_r - 256
  param(7)= Filter_Contrast_g - 256
  param(8)= Filter_Contrast_b - 256

  
  For i=0 To thread-1 : tr(i)=0 : Next
  For i=0 To thread-1
    While tr(i)=0     
      If Filter_Contrast_mask = 0
        tr(i)=CreateThread(@Filter_Contrast_thread(),i)
      Else
        tr(i)=CreateThread(@Filter_Contrast_mask_thread(),i)
      EndIf 
    Wend
  Next
  For i=0 To thread-1
    If IsThread(tr(i))>0 : WaitThread(tr(i)) : EndIf 
  Next
  
  FreeArray(tr())
  
  EndProcedure
Programme de test

Code : Tout sélectionner

;-- image plugins
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Global Dim param(256)

;-- include files
IncludeFile "filtres\contrast.pbi"

; 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)
    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
;------------------------------------------------------------------

;-- programme test
If OpenWindow(0, 0, 0, 800, 800, "Contrast", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
    MenuItem( 1, "Load Image")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
  MenuTitle("mask")
    MenuItem(6,"new mask")  
    
  TrackBarGadget(10, 10, 0, 512, 20, 0, 1024 )
    TrackBarGadget(11, 10, 20, 512, 20, 0, 1024 )
    TrackBarGadget(12, 10, 40, 512, 20, 0, 1024 )
    TrackBarGadget(13, 10, 60, 512, 20, 0, 1024 )
    SetGadgetState(10, 256)
    SetGadgetState(11, 256)
    SetGadgetState(12, 256)
    SetGadgetState(13, 256)
    
  Repeat
    update = 0
    Event = WindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            r = GetGadgetState(10)
            update = 1
          Case 11
            g= GetGadgetState(11)
            update = 1
          Case 12
            b = GetGadgetState(12)
            update = 1
          Case 13
            r = GetGadgetState(13)
            g=r : b=r
            update = 1

        EndSelect
                
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            source = 2
            If IsImage(source) : FreeImage(source) : EndIf
            If IsImage(cible) : FreeImage(cible) : cible = 0 : EndIf
            If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              source = 0
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              cible = 3
              If IsImage(cible) : FreeImage(cible) : EndIf
              CopyImage(source,cible)
              StartDrawing(WindowOutput(0))
              If IsImage(cible) : DrawImage(ImageID(cible),0,80) : EndIf
              StopDrawing()
              r = GetGadgetState(10)
              g = GetGadgetState(11)
              b = GetGadgetState(12)
              update = 1
           EndIf
          
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf

          Case 4
            SetClipboardImage(cible)
            
          Case 5
            quit = 1
            
          Case 6
            If source <> 0
              StartDrawing(ImageOutput(source))
              Psource = DrawingBuffer()            
              lg = ImageWidth(source)            
              ht = ImageHeight(source) 
              StopDrawing()
              If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
              mask = 4
              CreateImage(mask,lg,ht,32)
              StartDrawing(ImageOutput(mask))
              Circle(lg/2,ht/2,ht/4,$ffffff)
              Box(lg/8,ht/8,lg/6,ht/6,$ffffff)
              StopDrawing()
              r = GetGadgetState(10)
              g = GetGadgetState(11)
              b = GetGadgetState(12)
              update = 1
            EndIf
            
        EndSelect
      EndSelect
      
      If update = 1      
      t=ElapsedMilliseconds()
      Filter_contrast(source,cible,r,g,b,mask)

        t=ElapsedMilliseconds() - t
        
        StartDrawing(WindowOutput(0))
        If IsImage(cible)
          DrawImage(ImageID(cible),0,80)
          ;DrawText(750,5,Str(t)+"     ")
        EndIf
        StopDrawing()
      EndIf
      
      
  Until Event = #PB_Event_CloseWindow Or quit=1

  CloseWindow(0)

EndIf
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: Filtre graphique

Message par manababel »

Filtre guillossien
c'est extement le meme filtre que le filtre "BoxBlur" mais en plus rapide

voici le post d'oririne
viewtopic.php?p=207695&hilit=guillossien#p207695

Code : Tout sélectionner

;*******************************************************************************
;Titre      : Filter_guillossien - (Filter_Boxblur)
;Date       : 14/07/2022
;Version PB : PureBasic 5.70 LTS & 6.00 LTS
;             x64 seulement
;             Windows
;             linux - non testé
;             ios   - non testé
;
;Info       : ne fonctionne qu'avec des images 32bits ( source , cible et masque )
;             "la fonction "load_image" convertis les images 24bits en 32bits"    
;
;           : "Global Dim param(256)" est a declarer dans le programme principal
;*******************************************************************************

; NewPixel = (pixel1 + pixel2 + pixelN) / N 
; scaleX
; scaleY
; pass ; nombre de passe , pour un flou correcte minimum 2
; loop ; "utilisé pour la jointure des textures" ( 0 ou 1 ) 


Procedure Filter_guillossien_sp1(i)
  
  Protected p , d.f , start , stop 
  p=@param()
  
  d = 1 / param(10) 
  start = ( param(4) / param(9) ) * i ; param(4) = ht
  stop = ( param(4) / param(9) ) * (i + 1) - 1 ; param(9) = thread
  If i = (param(9) - 1)
    If stop < param(4) : stop = param(4) - 1 : EndIf
  EndIf  
  
  Dim mem(16,8) : mp = @mem() 
  Dim r.l(param(3)) : r1 = @r() ; param(3) = lg
  Dim g.l(param(3)) : g1 = @g()
  Dim b.l(param(3)) : b1 = @b()

  var = AllocateMemory(128)
  
  !mov rax,[p.v_mp]
  !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+064],r10
  !mov [rax+072],r11
  !mov [rax+080],r12
  !mov [rax+088],r13
  !mov [rax+096],r14
  !mov [rax+104],r15
  
  !movups xmm0,[p.v_d]
  !pshufd xmm0,xmm0,0
  !pxor xmm2,xmm2
  
      !mov r10,[p.v_b1]
      !mov r11,[p.v_g1]
      !mov r12,[p.v_r1]
      !mov rcx,[p.v_p]
      !mov r9,[p.v_start] ; For j = start To param(6) - 1 + start ; param(6) = nry
      !guillossien_b4:
        !mov rax,r9;[p.v_j] ; ;var = PeekL( py + j*4 )
        !shl rax,2
        !add rax,[rcx+8*8] ; py
        !mov eax,[rax]
        !mov edx,[rcx+3*8] ;pos1 = param(1) + ( var * param(3) ) <<2 ; pos1 = param(1) + ( (ly(j)) * param(3) ) <<2 ; param(1) = pcible
        !mul edx
        !shl eax,2
        !add rax,[rcx+1*8] ; cible
        !mov r8,rax

        !xor r14,r14
        !xor rdx,rdx
        !guillossien_b1: ;For i = 0 To (lg-1)
          !mov eax,[r8+r14*4] ;var = PeekL(pos1)
          !mov dl,al ; b(i) = b(i) + var & 255 
          !add [r10+r14*4],dx
          !mov dl,ah ; g(i) = g(i) + (var >> 8 ) & 255
          !add [r11+r14*4],dx
          !shr eax,8 ;r(i) = r(i) + (var >> 16 ) & 255
          !mov dl,ah
          !add [r12+r14*4],dx 
          !inc r14
          !cmp r14,[rcx+3*8] ; [p.v_lg]
        !jb guillossien_b1 ; Next
        !inc r9 
        !mov rax,[p.v_start]
        !add rax,[rcx+6*8] ; nrx
        !cmp r9,rax
      !jb guillossien_b4
      
      !mov rsi,[p.v_start] ;For j = start To stop;(ht-1)
      !guillossien_b6:
      
        !mov rax,[rcx+6*8] ; ;var = PeekL (param(8) + j*4 + param(6) * 4) ;var = PeekL (py + j*4 + param(6) * 4)
        !add rax,rsi;[p.v_j]
        !shl rax,2
        !add rax,[rcx+8*8]
        !mov eax,[rax]
        !mov rdx,[rcx+3*8] ; ;pos1 = param(1) + ( var * param(3) ) <<2 ; pos1 = param(1) + ( ly(param(6)+j) * param(3) ) <<2
        !mul rdx
        !shl rax,2
        !add rax,[rcx+1*8]
        !mov r8,rax
        
        !mov rax,rsi;[p.v_j] ; ;var = PeekL (py + j*4)
        !shl rax,2
        !add rax,[rcx+8*8] ; py = param(8)
        !mov eax,[rax]
        !mov rdx,[rcx+3*8] ;pos2 = param(1) + ( var * param(3) ) <<2 ; pos2 = param(1) + ( ly(j) * param(3) ) <<2
        !mul rdx
        !shl rax,2
        !add rax,[rcx+1*8]
        !mov r9,rax
        ;------------------------------------------------------------
        !xor r14,r14
        !xor rdx,rdx
        !guillossien_b2: ;For i = 0 To (lg-1) 
          !mov eax,[r8+r14*4] ;var = PeekL(pos1)
          !mov dl,al ; b(i) = b(i) + var & 255 
          !add [r10+r14*4],dx
          !mov dl,ah ; g(i) = g(i) + (var >> 8 ) & 255
          !add [r11+r14*4],dx
          !shr rax,8 ;r(i) = r(i) + (var >> 16 ) & 255
          !mov dl,ah
          !add [r12+r14*4],dx
          !mov eax,[r9+r14*4] ;var = PeekL(pos1)
          !mov dl,al ; b(i) = b(i) - var & 255 
          !sub [r10+r14*4],dx
          !mov dl,ah ; g(i) = g(i) - (var >> 8 ) & 255
          !sub [r11+r14*4],dx
          !shr eax,8 ;r(i) = r(i) - (var >> 16 ) & 255
          !mov dl,ah
          !sub [r12+r14*4],dx
          !inc r14
          !cmp r14,[rcx+3*8];[p.v_lg]
        !jb guillossien_b2 ; Next
        ;------------------------------------------------------------
        ;------------------------------------------------------------
        !xor r13,r13 ; rx1 = 0
        !xor r14,r14 ; gx1 = 0
        !xor r15,r15 ; bx1 = 0
        !xor rax,rax
        !xor rdx,rdx
        !guillossien_b3: ; For i = 0 To param(5)-1
          !mov r8,rdx
          !shl r8,2 
          !add r8,[rcx+7*8] ; 7*8 ; param(7) = px  ; (lx) ; rx1 = rx1 + r(lx(i))
          !mov eax,[r8]
          !add r13d,[r12+rax*4] ; rx1 = rx1 + r(var)
          !add r14d,[r11+rax*4] ; gx1 = gx1 + g(var)
          !add r15d,[r10+rax*4] ; bx1 = bx1 + b(var)
          !inc rdx
          !cmp rdx,[rcx+8*5] ; param(5) = [rcx+40] ; nrx
        !jb guillossien_b3 ; next
        ;------------------------------------------------------------
        ;----------------------------------------------------------------------------
        !mov rax,[rcx+3*8] ;pos = ( param(2) + (( j * param(3)  ) <<2) )
        !mov rdx,rsi ;[p.v_j]
        !mul rdx
        !shl rax,2
        !add rax,[rcx+2*8]
        !mov rdi,rax
        
        !xor r8,r8
        !xor r9,r9
        !xor rbx,rbx
        !guillossien_b5:;For i = 0 To (param(3)-1)

          !mov rax,rbx;[p.v_i] ; var = PeekL( px + i * 4)
          !shl rax,2
          !add rax,[rcx+7*8] ; px = param(7)
          !mov r8d,[rax]
          
          !mov rax,rbx;[p.v_i] ;var2 =PeekL( px + (i+param(5)) * 4)
          !add rax,[rcx+5*8]
          !shl rax,2
          !add rax,[rcx+7*8]
          !mov r9d,[rax]
          
          !add r13d,[r12+r9*4] ;rx1 = rx1 + r(var2) - r(var)
          !sub r13d,[r12+r8*4]
          !add r14d,[r11+r9*4] ;gx1 = gx1 + g(var2) - g(var)
          !sub r14d,[r11+r8*4]
          !add r15d,[r10+r9*4] ;bx1 = bx1 + b(var2) - b(var)
          !sub r15d,[r10+r8*4]
          
          !mov rax,[p.v_var]
          !mov [rax+00],r15d
          !mov [rax+04],r14d
          !mov [rax+08],r13d
          !movdqu xmm1,[rax]
          
          !cvtdq2ps xmm1,xmm1
          !mulps xmm1,xmm0
          !cvtps2dq xmm1,xmm1
          !packusdw xmm1,xmm2
          !packuswb xmm1,xmm2
          !movd [rdi+rbx*4],xmm1
          !inc rbx
          !cmp rbx,[rcx+3*8]
        !jb guillossien_b5 ; next
        ;----------------------------------------------------------------------------
        !inc rsi
        !cmp rsi,[p.v_stop]
      !jbe guillossien_b6 ; next    
      
  !mov rax,[p.v_mp]
  !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+064]
  !mov r11,[rax+072]
  !mov r12,[rax+080]
  !mov r13,[rax+088]
  !mov r14,[rax+096]
  !mov r15,[rax+104]
  
  FreeArray(mem())
  FreeArray(r())
  FreeArray(g())
  FreeArray(b())
EndProcedure

 

Procedure Filter_guillossien(Filter_guillossien_source,Filter_guillossien_cible,Filter_guillossien_rx.q,Filter_guillossien_ry.q,Filter_guillossien_pass=1,Filter_guillossien_loop=0,Filter_guillossien_mask=0)
  If Filter_guillossien_rx = 0 And Filter_guillossien_ry = 0 : ProcedureReturn : EndIf
  If Filter_guillossien_source = 0 Or Filter_guillossien_cible = 0 : ProcedureReturn : EndIf
  If Filter_guillossien_pass <1 : Filter_guillossien_pass = 1 : EndIf
  
  Protected i,ii,e,nrx,nry,dx,dy,dij, lg,ht ,taille ,pcible , psource , tempo , thread , s
  
  thread=CountCPUs(#PB_System_CPUs)
  If thread<2:thread=1:EndIf
  Protected Dim tr.q(thread)
    
  StartDrawing(ImageOutput(Filter_guillossien_source))
  psource = DrawingBuffer()
  lg = ImageWidth(Filter_guillossien_source)
  ht = ImageHeight(Filter_guillossien_source)
  taille = lg * ht * 4
  tempo = AllocateMemory(taille)
  StopDrawing()

  StartDrawing(ImageOutput(Filter_guillossien_cible))
  pcible = DrawingBuffer()
  StopDrawing()
  CopyMemory(psource,pcible,taille)

  dx = lg-1
  dy = ht-1
  If Filter_guillossien_rx > dx : Filter_guillossien_rx = dx : EndIf
  If Filter_guillossien_ry > dy : Filter_guillossien_ry = dy : EndIf

  nrx = Filter_guillossien_rx + 1
  nry = Filter_guillossien_ry + 1
  dij = nrx * nry
  
  Protected Dim lx.l(dx + 2 * nrx)
  Protected Dim ly.l(dy + 2 * nry)
  If Filter_guillossien_loop
    e=dx-nrx/2 : For i = 0 To dx + 2 * nrx : lx(i) = (i+e) % (dx+1) : Next
    e=dy-nry/2 : For i = 0 To dy + 2 * nry : ly(i) = (i+e) % (dy+1) : Next
  Else      
    For i = 0 To dx + 2 * nrx : ii=i-1-nrx/2 : If ii<0:ii=0:EndIf : If ii>dx:ii=dx:EndIf : lx(i) = ii : Next
    For i = 0 To dy + 2 * nry : ii = i - 1 - nry / 2 : If ii<0 : ii=0 : ElseIf ii>dy : ii=dy : EndIf : ly(i) = ii : Next
  EndIf 
  
  param(0)=psource
  param(1)=pcible
  param(2)=tempo
  param(3)=lg
  param(4)=ht
  param(5)=nrx
  param(6)=nry
  param(7)=lx()
  param(8)=ly()
  param(9)=thread
  param(10)=dij

  For k = 1 To Filter_guillossien_pass
    For i=0 To thread-1 : tr(i)=0 : Next
    For i=0 To thread-1 : While tr(i)=0 : tr(i)=CreateThread(@Filter_guillossien_sp1(),i) : Wend : Next
    For i=0 To thread-1 : If IsThread(tr(i))>0 : WaitThread(tr(i)) : EndIf  : Next
    CopyMemory(tempo,pcible, taille)
  Next
  
  CopyMemory(tempo,pcible,taille)
  
  If Filter_guillossien_mask <>0
    Protected Dim Reg_memory.q(5*8)

    StartDrawing(ImageOutput(Filter_guillossien_mask))
    Protected pmask = DrawingBuffer()
    lg = ImageWidth(Filter_guillossien_source)
    ht = ImageHeight(Filter_guillossien_source)
    Protected taillex = lg * ht
    StopDrawing()
    
    s = @reg_memory() ; calcul du mask
    !mov rax,[p.v_s]
    !mov [rax+000],r10
    !mov [rax+008],r11
    !mov [rax+016],r12
    !mov [rax+024],rcx
    
    !mov rcx,[p.v_pmask]
    !mov r8,[p.v_psource]
    !mov r9,[p.v_pcible]
    !xor rdx,rdx
    !Filter_guillossien_mask_saut01:
      !mov r10d,[rcx+rdx*4];,[p.v_Pmask]
      !mov r11d,[r8+rdx*4];r8,[p.v_Psource]
      !mov r12d,[r9+rdx*4];,[p.v_Pcible]
     
      !and r12d,r10d
      !xor r10d,$ffffffff
      !and r11d,r10d
      !or r11d,r12d
      !mov [r9+rdx*4],r11d
     
      !inc rdx
      !cmp rdx,[p.v_taillex]
    !jb Filter_guillossien_mask_saut01
     
    !mov rax,[p.v_s]
    !mov r10,[rax+000]
    !mov r11,[rax+008]
    !mov r12,[rax+016]
    !mov rcx,[rax+024]
  
    FreeArray(Reg_memory())
    
  EndIf
  
  FreeMemory(tempo)
  FreeArray(tr())
  FreeArray(lx())
  FreeArray(ly())
EndProcedure
Programme de test

Code : Tout sélectionner

;-- image plugins
UseGIFImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEG2000ImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()
UsePNGImageEncoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()

Global Dim param(256)

;-- include files
IncludeFile "filtres\guillossien.pbi"

; 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)
    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
;------------------------------------------------------------------

;-- programme test
If OpenWindow(0, 0, 0, 800, 800, "fire", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CreateMenu(0, WindowID(0))
    MenuTitle("Load")
    MenuItem( 1, "Load Image")
   MenuTitle("Save")   
    MenuItem( 2, "Save BMP")
    ;MenuItem( 3, "Save JPG")
    MenuItem( 4, "Save Clipboard")
  MenuTitle("Quit")
    MenuItem( 5, "Quit")
  MenuTitle("mask")
    MenuItem(6,"new mask")  
    
  TrackBarGadget(10, 10, 0, 512, 20, 0, 255 )
    TrackBarGadget(11, 10, 20, 512, 20, 0, 255 )
    TrackBarGadget(12, 10, 40, 512, 20, 0, 15 )
    TrackBarGadget(13, 10, 60, 512, 20, 0, 1 )
    SetGadgetState(10, 0)
    SetGadgetState(11, 0)
    SetGadgetState(12, 0)
    SetGadgetState(13, 0)
    
  Repeat
    update = 0
    Event = WindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            rx = GetGadgetState(10)
            update = 1
          Case 11
            ry = GetGadgetState(11)
            update = 1
          Case 12
            pass = GetGadgetState(12)
            update = 1
          Case 13
            loop = GetGadgetState(13)
            update = 1

        EndSelect
                
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            source = 2
            If IsImage(source) : FreeImage(source) : EndIf
            If IsImage(cible) : FreeImage(cible) : cible = 0 : EndIf
            If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
            file$ = OpenFileRequester("Image","","",0)
            If Not Load_Image(source,file$)
              source = 0
              MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
            Else
              cible = 3
              If IsImage(cible) : FreeImage(cible) : EndIf
              CopyImage(source,cible)
              StartDrawing(WindowOutput(0))
              If IsImage(cible) : DrawImage(ImageID(cible),0,80) : EndIf
              StopDrawing()
              update = 1
           EndIf
          
          Case 2
            nom$ = SaveFileRequester("Save BMP", "", "", 0)
            If nom$ <> "" : SaveImage(cible, nom$+".bmp" ,#PB_ImagePlugin_BMP ) : EndIf

          Case 4
            SetClipboardImage(cible)
            
          Case 5
            quit = 1
            
          Case 6
            If source <> 0
              StartDrawing(ImageOutput(source))
              Psource = DrawingBuffer()            
              lg = ImageWidth(source)            
              ht = ImageHeight(source) 
              StopDrawing()
              If IsImage(mask) : FreeImage(mask) : mask = 0 : EndIf
              mask = 4
              CreateImage(mask,lg,ht,32)
              StartDrawing(ImageOutput(mask))
              Circle(lg/2,ht/2,ht/4,$ffffff)
              Box(lg/8,ht/8,lg/6,ht/6,$ffffff)
              StopDrawing()
              rx = GetGadgetState(10)
              ry = GetGadgetState(11)
              pass = GetGadgetState(12)
              loop = GetGadgetState(13)
              update = 1
            EndIf
            
        EndSelect
      EndSelect
      
      If update = 1      
        t=ElapsedMilliseconds()
      Filter_guillossien(source,cible,rx,ry,pass,loop,mask)

        t=ElapsedMilliseconds() - t
        
        StartDrawing(WindowOutput(0))
        If IsImage(cible)
          DrawImage(ImageID(cible),0,80)
          DrawText(750,5,Str(t)+"     ")
        EndIf
        StopDrawing()
      EndIf
      
      
  Until Event = #PB_Event_CloseWindow Or quit=1

  CloseWindow(0)

EndIf

Dernière modification par manababel le jeu. 14/juil./2022 19:07, modifié 1 fois.
Répondre