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