Page 1 sur 1

filtre niveau de gris

Publié : lun. 25/mai/2020 0:27
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

Re: filtre niveau de gris

Publié : lun. 25/mai/2020 8:35
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.