Filtre graphique
Filtre graphique
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
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.
Re: Filtre graphique
filtre balance des couleur
; Balance.pbi"
Programme de test
; 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
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.
Re: Filtre graphique
filtre bend ( similaire au filtre balance )
Bend.pbi
Programme de test
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
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
Re: Filtre graphique
filtre Black&White ( threshold filter )
BlackAndWhite.pbi
Programme de test
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
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
Re: Filtre graphique
filtre Boxblur
BoxBlur.pbi
Programme de test
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
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
Re: Filtre graphique
filtre Brightness ( similaire au filtre balance )
Brightness.pbi
Programme de test
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
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
Re: Filtre graphique
filtre color ( selon l'option , passe une ou deux couleurs en "gris" )
Color.pbi
Programme de test
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
Re: Filtre graphique
filtre color_effect ( mix les couleurs entre elles )
color_effect.pbi
Programme de test
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
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
Re: Filtre graphique
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
et aucun commentaire !
t'as testé la v6 ? , ça serai bien de comparer le compilation C optimisée à l'assembleur
Re: Filtre graphique
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é
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é
Re: Filtre graphique
- 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)
- 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)
Re: Filtre graphique
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 .
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 .
Re: Filtre graphique
filtre Emboss
emboss.pbi
Programme de test
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
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
Re: Filtre graphique
filtre contrast
Programme de test
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
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
Re: Filtre graphique
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
Programme de test
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
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.