filtre niveau de gris

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

filtre niveau de gris

Message par manababel »

Se filtre permet de convertir une image "couleur" en image "grise".
Pour tous ceux qui on déjà vue une télévision "noir et blanc"
(pour les plus vieux d'entre nous) , par defaut utiliserons le terme
"noir et blanc" .

Il y a plusieurs calculs pour faire une image grise.
Quelle que soit la méthode utilisée , les résultats sont très similaires.

Code : Tout sélectionner

;EnableExplicit


; charge une image et la convertie en 32bit
;-------------------------------------------------------------------
Procedure load_image(nom,file$)
  Protected source_p , cible_p , s.q
  Protected lg.q , ht.q , taille.q , depth.q
  
  LoadImage(nom,file$)
  If Not IsImage(nom) : ProcedureReturn 0 : EndIf
    
  StartDrawing(ImageOutput(nom))
  source_p = DrawingBuffer()
  ht = ImageHeight(nom)
  lg = ImageWidth(nom)
  Depth=OutputDepth()
  StopDrawing()
  
  If Depth=24
    taille=lg*ht
    cible_p=AllocateMemory(taille*4)
    Dim save.q(4)
    s=@save()
    EnableASM
      !mov rax,[p.v_s]
      !mov [rax],rcx
      !mov [rax+8],rdx
      !mov [rax+16],r8
      !mov rcx,[p.v_source_p]
      !mov rdx,[p.v_cible_p]
      !mov r8,[p.v_taille]
      !sub r8,1 ; <---------------- ????
      !copy_boucle24:
        !mov eax,[rcx]     
        !mov [rdx],eax
        !add rcx,3
        !add rdx,4
        !dec r8
       !jnz copy_boucle24
      !mov rax,[p.v_s] 
      !mov rcx,[rax]
      !mov rdx, [rax+8]
      !mov r8,[rax+16]
    DisableASM
    FreeArray(save())
    
    FreeImage(nom) ; supprime l'image 24bits
    CreateImage(nom,lg,ht,32) 
    StartDrawing(ImageOutput(nom))
    source_p = DrawingBuffer()
    StopDrawing()
    CopyMemory( cible_p , source_p , taille*4 )
    FreeMemory(cible_p)
  EndIf
  ProcedureReturn 1
EndProcedure




; partie du programme à modifier pour adapter se programme au votre
; convertie les "IDs" des images en pointer d'adresse
; test si les images sont en 32bits et de la meme taille
;-------------------------------------------------------------------

Macro sp(source,cible)
  Protected Depth.q , lg.q , ht.q , lg1.q , ht1.q , taille.q
  Protected cible_p.q , source_p.q
  
  StartDrawing(ImageOutput(cible))
  cible_p = DrawingBuffer()
  ht1 = ImageHeight(cible)
  lg1 = ImageWidth(cible)
  Depth=OutputDepth()
  StopDrawing()
  If depth<>32 : ProcedureReturn : EndIf
  
  StartDrawing(ImageOutput(source))
  source_p = DrawingBuffer()
  ht = ImageHeight(source)
  lg = ImageWidth(source)
  Depth=OutputDepth()
  StopDrawing()
  If depth<>32 : ProcedureReturn : EndIf
  
  If lg<>lg1 Or ht<>ht1 : ProcedureReturn : EndIf
  
  taille = lg * ht
EndMacro

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


Procedure Filter_GrayScale(source.q,cible.q,opt.q)

   sp(source,cible)
  
   
   Select opt
       ;-- GrayScale (r+g+b)/3 Average : ((r+g+b)*$55)>>16 = (r+g+b)/3
     Case 0
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !movdqu [rax+64],xmm0
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15
      
      !mov rsi,[p.v_source_p]
      !mov rdi,[p.v_cible_p]
      !mov rdx,[p.v_taille]
      !shr rdx,1
      !xor rcx,rcx     
      !pxor xmm15,xmm15
      !mov rax,$0000005500550055    ; 0000 0055 0055 0055
      !movq xmm14,rax
      !movlhps xmm14,xmm14    ; 0000 0055 0055 0055 0000 0055 0055 0055     
      !mov eax,$00010101
      !movd xmm13,eax
      !pshufd xmm13,xmm13,0   ; 0000 0001 0001 0001 0000 0001 0001 0001     
      !mov eax,$ff
      !movd xmm12,eax
      !movlhps xmm12,xmm12    ; 0000 0000 0000 00ff 0000 0000 0000 00ff
      !GrayScale_01:
        !movq xmm0,[rsi+rcx]  ; xxxx xxxx xxxx xxxx a1r1 g1b1 a0r0 g0b0
        !punpcklbw xmm0,xmm15 ; 00a1 00r1 00g1 00b2 00a0 00r0 00g0 00b0
        !pmullw xmm0,xmm14    ; X $55
        !movups xmm1,xmm0     ; a1 r1 g1 b1   a0 r0 g0 b0 (a1=32bits ...)
        !psrldq xmm1,2        ; 00 a1 r1 g1   b1 a0 r0 g0
        !movups xmm2,xmm1
        !psrldq xmm2,2        ; 00 00 a1 r1   g1 b1 a0 r0
        !paddw xmm0,xmm1
        !paddw xmm0,xmm2
        !psrldq xmm0,1        ; >>8
        !pand xmm0,xmm12      ; and $ff
        !pmuludq xmm0,xmm13   ; 0000 00r1 00g1 00b1 0000 00r0 00g0 00b0
        !pshufd xmm0,xmm0,$F8 ; xxxx xxxx xxxx xxxx 00r1 g1b1 00r0 g0b0
        !movq [rdi+rcx],xmm0
        !add rcx,8
        !dec rdx
      !jnz GrayScale_01 
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !movdqu xmm0,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save())
    ;-- GrayScale Lum(0.35 , 0.50  ,0.15) (*256)
    Case 1
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !movdqu [rax+64],xmm0
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15 
      !mov rsi,[p.v_source_p]
      !mov rdi,[p.v_cible_p]
      !mov rdx,[p.v_taille]
      !shr rdx,1
      !xor rcx,rcx     
      !pxor xmm15,xmm15
      !mov rax,$0000005900800026    ; 0000 0059 0080 0026
      !movq xmm14,rax
      !movlhps xmm14,xmm14    ; 0000 0055 0055 0055 0000 0055 0055 0055     
      !mov eax,$00010101
      !movd xmm13,eax
      !pshufd xmm13,xmm13,0   ; 0000 0001 0001 0001 0000 0001 0001 0001     
      !mov eax,$ff
      !movd xmm12,eax
      !movlhps xmm12,xmm12    ; 0000 0000 0000 00ff 0000 0000 0000 00ff
      !GrayScale_02:
        !movq xmm0,[rsi+rcx]  ; xxxx xxxx xxxx xxxx a1r1 g1b1 a0r0 g0b0
        !punpcklbw xmm0,xmm15 ; 00a1 00r1 00g1 00b2 00a0 00r0 00g0 00b0
        !pmullw xmm0,xmm14    ; X $55
        !movups xmm1,xmm0     ; a1 r1 g1 b1   a0 r0 g0 b0 (a1=32bits ...)
        !psrldq xmm1,2        ; 00 a1 r1 g1   b1 a0 r0 g0
        !movups xmm2,xmm1
        !psrldq xmm2,2        ; 00 00 a1 r1   g1 b1 a0 r0
        !paddw xmm0,xmm1
        !paddw xmm0,xmm2
        !psrldq xmm0,1        ; >>8
        !pand xmm0,xmm12      ; and $ff
        !pmuludq xmm0,xmm13   ; 0000 00r1 00g1 00b1 0000 00r0 00g0 00b0
        !pshufd xmm0,xmm0,$F8 ; xxxx xxxx xxxx xxxx 00r1 g1b1 00r0 g0b0
        !movq [rdi+rcx],xmm0
        !add rcx,8
        !dec rdx
      !jnz GrayScale_02  
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !movdqu xmm0,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save())
      
      
;-- GrayScale Luma601(0.299 , 0.587  ,0.114)   (*256)
    Case 2
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !movdqu [rax+64],xmm0
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15 
      !mov rsi,[p.v_source_p]
      !mov rdi,[p.v_cible_p]
      !mov rdx,[p.v_taille]
      !shr rdx,1
      !xor rcx,rcx     
      !pxor xmm15,xmm15
      !mov rax,$0000004D0096001D    ; 0000 004D 0096 001d
      !movq xmm14,rax
      !movlhps xmm14,xmm14    ; 0000 0055 0055 0055 0000 0055 0055 0055     
      !mov eax,$00010101
      !movd xmm13,eax
      !pshufd xmm13,xmm13,0   ; 0000 0001 0001 0001 0000 0001 0001 0001     
      !mov eax,$ff
      !movd xmm12,eax
      !movlhps xmm12,xmm12    ; 0000 0000 0000 00ff 0000 0000 0000 00ff
      !GrayScale_03:
        !movq xmm0,[rsi+rcx]  ; xxxx xxxx xxxx xxxx a1r1 g1b1 a0r0 g0b0
        !punpcklbw xmm0,xmm15 ; 00a1 00r1 00g1 00b2 00a0 00r0 00g0 00b0
        !pmullw xmm0,xmm14    ; X $55
        !movups xmm1,xmm0     ; a1 r1 g1 b1   a0 r0 g0 b0 (a1=32bits ...)
        !psrldq xmm1,2        ; 00 a1 r1 g1   b1 a0 r0 g0
        !movups xmm2,xmm1
        !psrldq xmm2,2        ; 00 00 a1 r1   g1 b1 a0 r0
        !paddw xmm0,xmm1
        !paddw xmm0,xmm2
        !psrldq xmm0,1        ; >>8
        !pand xmm0,xmm12      ; and $ff
        !pmuludq xmm0,xmm13   ; 0000 00r1 00g1 00b1 0000 00r0 00g0 00b0
        !pshufd xmm0,xmm0,$F8 ; xxxx xxxx xxxx xxxx 00r1 g1b1 00r0 g0b0
        !movq [rdi+rcx],xmm0
        !add rcx,8
        !dec rdx
      !jnz GrayScale_03  
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !movdqu xmm0,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save())
      
      
;-- GrayScale Luma709(0.2126 , 0.7152  ,0.0722) (*256)
    Case 3
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !movdqu [rax+64],xmm0
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15 
      !mov rsi,[p.v_source_p]
      !mov rdi,[p.v_cible_p]
      !mov rdx,[p.v_taille]
      !shr rdx,1
      !xor rcx,rcx     
      !pxor xmm15,xmm15
      !mov rax,$0000003700B70012    ; 0000 0037 00B7 0012
      !movq xmm14,rax
      !movlhps xmm14,xmm14    ; 0000 0055 0055 0055 0000 0055 0055 0055     
      !mov eax,$00010101
      !movd xmm13,eax
      !pshufd xmm13,xmm13,0   ; 0000 0001 0001 0001 0000 0001 0001 0001     
      !mov eax,$ff
      !movd xmm12,eax
      !movlhps xmm12,xmm12    ; 0000 0000 0000 00ff 0000 0000 0000 00ff
      !GrayScale_04:
        !movq xmm0,[rsi+rcx]  ; xxxx xxxx xxxx xxxx a1r1 g1b1 a0r0 g0b0
        !punpcklbw xmm0,xmm15 ; 00a1 00r1 00g1 00b2 00a0 00r0 00g0 00b0
        !pmullw xmm0,xmm14    ; X $55
        !movups xmm1,xmm0     ; a1 r1 g1 b1   a0 r0 g0 b0 (a1=32bits ...)
        !psrldq xmm1,2        ; 00 a1 r1 g1   b1 a0 r0 g0
        !movups xmm2,xmm1
        !psrldq xmm2,2        ; 00 00 a1 r1   g1 b1 a0 r0
        !paddw xmm0,xmm1
        !paddw xmm0,xmm2
        !psrldq xmm0,1        ; >>8
        !pand xmm0,xmm12      ; and $ff
        !pmuludq xmm0,xmm13   ; 0000 00r1 00g1 00b1 0000 00r0 00g0 00b0
        !pshufd xmm0,xmm0,$F8 ; xxxx xxxx xxxx xxxx 00r1 g1b1 00r0 g0b0
        !movq [rdi+rcx],xmm0
        !add rcx,8
        !dec rdx
      !jnz GrayScale_04  
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !movdqu xmm0,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save()) 
      
      
;-- GrayScale blue     
    Case 4 ; blue
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !movdqu [rax+64],xmm0
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15
      !mov rsi,[p.v_source_p]
      !mov rdi,[p.v_cible_p]
      !mov rdx,[p.v_taille]
      !shr rdx,2
      !xor rcx,rcx
      !mov eax,$000000ff ; 32bits
      !movd xmm0,eax 
      !shufps xmm0,xmm0,$00 ; 128 bits (4x32bits)
      !mov eax,$00010101
      !movd xmm1,eax
      !shufps xmm1,xmm1,$00
      !boucle_grayscale_blue_1: 
        !movaps xmm2,[rsi+rcx]
        !andps xmm2,xmm0
        !pmulld xmm2,xmm1
        !movntps [rdi+rcx],xmm2
        !add rcx,16
        !dec rdx
      !jnz boucle_grayscale_blue_1  
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !movdqu xmm0,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save())
      
        
 ;-- GrayScale green     
    Case 5 ; 
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !movdqu [rax+64],xmm0
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15
      !mov rsi,[p.v_source_p]
      !mov rdi,[p.v_cible_p]
      !mov rdx,[p.v_taille]
      !shr rdx,2
      !xor rcx,rcx
      !mov eax,$0000ff00 ; 32bits
      !movd xmm0,eax 
      !shufps xmm0,xmm0,$00 ; 128 bits (4x32bits)
      !mov eax,$00010101
      !movd xmm1,eax
      !shufps xmm1,xmm1,$00
      !boucle_grayscale_green_1: 
        !movaps xmm2,[rsi+rcx]
        !andps xmm2,xmm0
        !psrlq xmm2,8
        !pmulld xmm2,xmm1
        !movntps [rdi+rcx],xmm2
        !add rcx,16
        !dec rdx
      !jnz boucle_grayscale_green_1  
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !movdqu xmm0,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save())
           
        
 ;-- GrayScale red     
    Case 6 ; 
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !movdqu [rax+64],xmm0
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15
      !mov rsi,[p.v_source_p]
      !mov rdi,[p.v_cible_p]
      !mov rdx,[p.v_taille]
      !shr rdx,2
      !xor rcx,rcx
      !mov eax,$00ff0000 ; 32bits
      !movd xmm0,eax 
      !shufps xmm0,xmm0,$00 ; 128 bits (4x32bits)
      !mov eax,$00010101
      !movd xmm1,eax
      !shufps xmm1,xmm1,$00
      !boucle_grayscale_red_1: 
      !movaps xmm2,[rsi+rcx]
        !andps xmm2,xmm0
        !psrlq xmm2,16
        !pmulld xmm2,xmm1
        !movntps [rdi+rcx],xmm2
        !add rcx,16
        !dec rdx
      !jnz boucle_grayscale_red_1  
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !movdqu xmm0,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save())    
               
;-- GrayScale max
    Case 7         
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !mov [rax+64],rbx
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15
      !mov esi,[p.v_source_p]
      !mov edi,[p.v_cible_p]
      !mov edx,[p.v_taille]
      !GrayScale_max_1:
        !xor eax,eax
        !xor ebx,ebx
        !xor ecx,ecx
        !mov al,[esi+0]
        !mov bl,[esi+1]
        !mov cl,[esi+2]
        !cmp ebx,eax
        !cmovae eax,ebx
        !cmp ecx,eax
        !cmovae eax,ecx
        !imul eax,$10101
        !mov [edi],eax
        !add esi,4
        !add edi,4
        !sub edx,1
      !jnz GrayScale_max_1  
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !mov rbx,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save())

      
;-- GrayScale min      
    Case 8
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !mov [rax+64],rbx
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15
      !mov esi,[p.v_source_p]
      !mov edi,[p.v_cible_p]
      !mov edx,[p.v_taille]
      !GrayScale_min_1:
        !xor eax,eax
        !xor ebx,ebx
        !xor ecx,ecx
        !mov al,[esi+0]
        !mov bl,[esi+1]
        !mov cl,[esi+2]
        !cmp ebx,eax
        !cmove eax,ebx
        !cmp ecx,eax
        !cmove eax,ecx
        !imul eax,$10101
        !mov [edi],eax
        !add esi,4
        !add edi,4
        !sub edx,1
      !jnz GrayScale_min_1  
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !mov rbx,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save())
      
    
    ;-- GrayScale moy (max+min)/2(average)  : RGBtoMean    ;aka "Lightness method"
    Case 9
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !mov [rax+64],rbx
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15
      !mov esi,[p.v_source_p]
      !mov edi,[p.v_cible_p]
      !mov edx,[p.v_taille]
      !GrayScale_min_1x:
        !xor eax,eax
        !xor ebx,ebx
        !xor ecx,ecx
        !mov al,[esi+0]
        !mov bl,[esi+1]
        !mov cl,[esi+2]
        !cmp bx,ax
        !cmove ax,bx
        !cmp cx,ax
        !cmove ax,cx
        !cmp bx,cx
        !cmovae bx,cx
        
        !add ax,bx
        !shr ax,1
        !imul eax,$10101
        !mov [edi],eax
        !add esi,4
        !add edi,4
        !sub edx,1
      !jnz GrayScale_min_1x 
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !mov rbx,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save())
            

    ;-- grayscale = sqr(0.23*r*r+0.7*g*g+0.07*b*b)
  Case 10    
      Dim save.q(22)
      s=@save()
      EnableASM 
      !mov rax,[p.v_s]
      !mov [rax+00],rsi
      !mov [rax+16],rdi
      !mov [rax+32],rcx
      !mov [rax+48],rdx
      !movdqu [rax+64],xmm0
      !movdqu [rax+80],xmm1
      !movdqu [rax+96],xmm2
      !movdqu [rax+112],xmm12
      !movdqu [rax+128],xmm13
      !movdqu [rax+144],xmm14
      !movdqu [rax+160],xmm15 
      !mov rsi,[p.v_source_p]
      !mov rdi,[p.v_cible_p]
      !mov rdx,[p.v_taille]
      !xor rcx,rcx     
      !pxor xmm15,xmm15
      !mov eax,$3bb312   ; 59(3b) 179(b3) 18(12)
      !movd xmm14,eax
      !punpcklbw xmm14,xmm15 ; 8 -> 16
      !punpcklwd xmm14,xmm15 ; 16 -> 32  
      !mov eax,$10101
      !movd xmm12,eax
      !GrayScale_011:
        !movd xmm0,[rsi+rcx]  
        !punpcklbw xmm0,xmm15 ; 8 -> 16 
        !punpcklwd xmm0,xmm15 ; 16 -> 32 
        !pmulld xmm0,xmm0     ; R = R x R
        !pmulld xmm0,xmm14    ; R = R x 0.xx
        !phaddd xmm0,xmm0
        !phaddd xmm0,xmm0
        !psrld xmm0,8       ; v = v /256
        !cvtdq2ps xmm0,xmm0
        !sqrtps xmm0,xmm0
        !cvtps2dq xmm0,xmm0
        !pmulld xmm0,xmm12  
        !movd [rdi+rcx],xmm0
        !add rcx,4
        !dec rdx
      !jnz GrayScale_011  
      !mov rax,[p.v_s]
      !mov rsi,[rax+00]
      !mov rdi,[rax+16]
      !mov rcx,[rax+32]
      !mov rdx,[rax+48]
      !movdqu xmm0,[rax+64]
      !movdqu xmm1,[rax+80]
      !movdqu xmm2,[rax+96]
      !movdqu xmm12,[rax+112]
      !movdqu xmm13,[rax+128]
      !movdqu xmm14,[rax+144]
      !movdqu xmm15,[rax+160]  
      DisableASM
      FreeArray(save())
      
  ;-------------------------------------------------------------------
  ;-- a convertir en ASM
  Case 11
      mi=255
      ma=0
      For i=0 To taille-4 
        var=PeekL(source_p+(i*4))
        r=Red(var)
        g=Green(var)
        b=Blue(var)
        var=(((r+g+b)*21845)>>16) ; (r+g+b)/3
        PokeB(cible_p+(i*4),var)
        If mi>var:mi=var:EndIf
        If ma<var:ma=var:EndIf
      Next
      scale=(ma-mi)
      For i=0 To taille-4 
        r=PeekB(cible_p+(i*4))
        r=((r-mi)*scale)>>8
        PokeL(cible_p+(i*4),r*$10101)
      Next
      
  EndSelect
  
  
EndProcedure

;-------------------------------------------------------------------
;-- version AVX  registe 256bits
; (r+g+b)/3

    ;Case 12  
      ;sp(source,cible)
      ;EnableASM 
      
      ;!mov rsi,[p.v_source_p]
      ;!mov rdi,[p.v_cible_p]
      ;!mov rdx,[p.v_long]
      ;!shr rdx,2
      ;!xor rcx,rcx    
      
      ;!vpxor ymm15,ymm15,ymm15
      
      ;!mov rax,$55
      ;!movq xmm14,rax 
      ;!VPBROADCASTW ymm14,xmm14 ;0055 (16*16bits = 256bits)
      
      ;!mov rax,$00010101
      ;!movq xmm13,rax
      ;!VPBROADCASTD ymm13,xmm13 ; 00010101 00010101 00010101 00010101 (8*32bits)
      
      ;!mov rax,$ff
      ;!movq xmm12,rax
      ;!VPBROADCASTq ymm12,xmm12 ; (8*32bits) ; 0000 0000 0000 00ff 0000 0000 0000 00ff
      
      ;!GrayScale_01x:
        ;!VBROADCASTI128 ymm0,[rsi+rcx] ; charge 4*32bits et les copy pour en faire 2*(4*32bits) abcd abcd
        ;!vpermq ymm0,ymm0,$30 ; met la partie haute du registre dans l'ordre cdab abcd
        ;!vpunpcklbw ymm0,ymm0,ymm15 ; cdab abcd -> 0a0b 0c0d (8bits -> 16bits) (total = 256bits)
        ;!vpmullw ymm0,ymm0,ymm14    ; X $55
        ;!vmovdqu ymm1,ymm0     ; a3 r3 g3 b3   a2 r2 g2 b2  a1 r1 g1 b1   a0 r0 g0 b0 (a1=32bits ...)
        ;!vpsrldq ymm1,ymm1,2        ; 00 a1 r1 g1   b1 a0 r0 g0
        ;!vmovdqu ymm2,ymm1
        ;!vpsrldq ymm2,ymm2,2        ; 00 00 a1 r1   g1 b1 a0 r0
        ;!vpaddw ymm0,ymm0,ymm1
        ;!vpaddw ymm0,ymm0,ymm2
        ;!vpsrldq ymm0,ymm0,1        ; >>8
        ;!vpand ymm0,ymm0,ymm12      ; and $ff : 000000ff 000000ff 000000ff 000000ff 000000ff 000000ff 000000ff 000000ff
        ;!vpmulld ymm0,ymm0,ymm13   ; 0000 00r1 00g1 00b1 0000 00r0 00g0 00b0
        ;!vpshufd ymm0,ymm0,$F8 ; xxxx xxxx xxxx xxxx 00r1 g1b1 00r0 g0b0 (16bits -> 8 bits)
        ;!vpermq ymm0,ymm0,$f8 ; 256bits -> 128bits
        ;!movntps [rdi+rcx],xmm0
        ;!add rcx,16
        ;!dec rdx
      ;!jnz GrayScale_01x  
      ;!VZEROALL
      ;DisableASM

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

UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=1920
Global imgy=1080


If OpenWindow(0, 0, 0, imgx, imgy, "grayscale", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define source.q , cible.q , t.q , file$ , i
  
  Dim tab$(12)
  tab$(0)="(r+g+b)/3"
  tab$(1)="lum"
  tab$(2)="lum 601"
  tab$(3)="lum 709"
  tab$(4)="bleu"
  tab$(5)="vert"
  tab$(6)="rouge"
  tab$(7)="max"
  tab$(8)="min"
  tab$(9)="(max/min)/2"
  tab$(10)="sqr( r*r*0.23 + g*g*0.70 + b*b*0.23)"
  tab$(11)=" scale = (max((r+g+b)/3) - min((r+g+b)/3)) : ((gray-min)*scale)/256"
  
   file$ = OpenFileRequester("Image","","",0)
   source=100

   If Not Load_Image(source,file$) ; <- commande differente de "LOADIMAGE"
     MessageRequester("load_image","erreur de chargement",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
     End
   EndIf
   ResizeImage(source,imgx,imgy,#PB_Image_Smooth)
   
   Dim cible.q(12)
   For i=0 To 11
     cible(i)=i
     v=CreateImage(cible(i),imgx,imgy,32) ; l'image doit entre en mode 32bits     
  Next
  
  For i=0 To 11
    t=ElapsedMilliseconds()
    Filter_GrayScale(source,cible(i),i)
    t=ElapsedMilliseconds()-t
    tab$(i)=tab$(i)+" : "+Str(t)+"ms"
    ResizeImage(cible(i),imgx/4,imgy/3,#PB_Image_Smooth)
 Next
   
   StartDrawing(WindowOutput(0))
   i=0
   For y=0 To 2
     For x=0 To 3
       px=(imgx/4)*x
       py=(imgy/3)*y
       DrawImage(ImageID(cible(i)),px,py)
       DrawText(px+5,py+5,tab$(i))
       i=i+1
     Next
   Next

   StopDrawing()
   
   Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
 EndIf
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: filtre niveau de gris

Message par Ar-S »

Merci,
Excellent de voir ces petites nuances.

Note qu'avec PB tu n'as pas besoin d'utiliser EnableASM/DisableASM si tu utilises le "!" devant tes instructions ASM.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Répondre