le filtre "brightness"
- new pixel = pixel + Val ( Val peut être négatif ou positif )
le filtre "bend"
- new pixel = sin (pixel * val) * 127 + val
( la valeur 'val' doit être comprise entre 0 et 360 )
- toutes les nouvelles valeurs sont précalculées et stockées dans un tableau.
D'autres filtre fonctionnent de la même façon, comme le filtre "gamma"
Code : Tout sélectionner
EnableExplicit
Global Dim Reg_memory.q(4*344)
; charge une image et la convertie en 32bit
;-------------------------------------------------------------------
Procedure load_image(nom,file$)
Protected source_p , cible_p , s.q
Protected lg.q , ht.q , taille.q , depth.q
LoadImage(nom,file$)
If Not IsImage(nom) : ProcedureReturn 0 : EndIf
StartDrawing(ImageOutput(nom))
source_p = DrawingBuffer()
ht = ImageHeight(nom)
lg = ImageWidth(nom)
Depth=OutputDepth()
StopDrawing()
If Depth=24
taille=lg*ht
cible_p=AllocateMemory(taille*4)
Dim save.q(4)
s=@save()
EnableASM
!mov rax,[p.v_s]
!mov [rax],rcx
!mov [rax+8],rdx
!mov [rax+16],r8
!mov rcx,[p.v_source_p]
!mov rdx,[p.v_cible_p]
!mov r8,[p.v_taille]
!sub r8,1 ; <---------------- ????
!copy_boucle24:
!mov eax,[rcx]
!mov [rdx],eax
!add rcx,3
!add rdx,4
!dec r8
!jnz copy_boucle24
!mov rax,[p.v_s]
!mov rcx,[rax]
!mov rdx, [rax+8]
!mov r8,[rax+16]
DisableASM
FreeArray(save())
FreeImage(nom) ; supprime l'image 24bits
CreateImage(nom,lg,ht,32)
StartDrawing(ImageOutput(nom))
source_p = DrawingBuffer()
StopDrawing()
CopyMemory( cible_p , source_p , taille*4 )
FreeMemory(cible_p)
EndIf
ProcedureReturn 1
EndProcedure
; partie du programme à modifier pour adapter se programme au votre
; convertie les "IDs" des images en pointer d'adresse
; test si les images sont en 32bits et de la meme taille
;-------------------------------------------------------------------
Macro sp(source,cible)
Protected Depth.q , lg.q , ht.q , lg1.q , ht1.q , taille.q
Protected cible_p.q , source_p.q
StartDrawing(ImageOutput(cible))
cible_p = DrawingBuffer()
ht1 = ImageHeight(cible)
lg1 = ImageWidth(cible)
Depth=OutputDepth()
StopDrawing()
If depth<>32 : ProcedureReturn : EndIf
StartDrawing(ImageOutput(source))
source_p = DrawingBuffer()
ht = ImageHeight(source)
lg = ImageWidth(source)
Depth=OutputDepth()
StopDrawing()
If depth<>32 : ProcedureReturn : EndIf
If lg<>lg1 Or ht<>ht1 : ProcedureReturn : EndIf
taille = lg * ht
EndMacro
Macro clampRGB(r,g,b)
If r<0:r=0:EndIf
If g<0:g=0:EndIf
If b<0:b=0:EndIf
If r>255:r=255:EndIf
If g>255:g=255:EndIf
If b>255:b=255:EndIf
EndMacro
Macro returnRGB(pixel,r,g,b)
r=(pixel & $ff0000)>>16
g=(pixel & $ff00)>>8
b=(pixel & $ff)
EndMacro
;-------------------------------------------------------------------
; sauvegarde de registres
Macro Save_reg()
s=@reg_memory()
EnableASM
!mov rax,[p.v_s]
!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+056],r10
!mov [rax+064],r11
!mov [rax+072],r12
!mov [rax+080],r13
!mov [rax+088],r14
!mov [rax+096],r15
!movdqu [rax+104],xmm0 ;
!movdqu [rax+120],xmm1 ;
!movdqu [rax+136],xmm2 ;
!movdqu [rax+152],xmm3 ;
!movdqu [rax+168],xmm4
!movdqu [rax+184],xmm5
!movdqu [rax+200],xmm6
!movdqu [rax+216],xmm7
!movdqu [rax+232],xmm8
!movdqu [rax+248],xmm9
!movdqu [rax+264],xmm10
!movdqu [rax+280],xmm11
!movdqu [rax+296],xmm12
!movdqu [rax+312],xmm13
!movdqu [rax+328],xmm14
!movdqu [rax+344],xmm15
DisableASM
EndMacro
Macro Rest_Reg()
; restore les registres
s=@reg_memory()
EnableASM
!mov rax,[p.v_s]
!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+056]
!mov r11,[rax+064]
!mov r12,[rax+072]
!mov r13,[rax+080]
!mov r14,[rax+088]
!mov r15,[rax+096]
!movdqu xmm0,[rax+104] ;
!movdqu xmm1,[rax+120] ;
!movdqu xmm2,[rax+136] ;
!movdqu xmm3,[rax+152] ;
!movdqu xmm4,[rax+168]
!movdqu xmm5,[rax+184]
!movdqu xmm6,[rax+200]
!movdqu xmm7,[rax+216]
!movdqu xmm8,[rax+232]
!movdqu xmm9,[rax+248]
!movdqu xmm10,[rax+264]
!movdqu xmm11,[rax+280]
!movdqu xmm12,[rax+296]
!movdqu xmm13,[rax+312]
!movdqu xmm14,[rax+328]
!movdqu xmm15,[rax+344]
DisableASM
EndMacro
;-------------------------------------------------------------------
Procedure Filter_bend_pb(source.q,cible.q,r.q,g.q,b.q)
Protected i.q , pixel.l , v.f
Protected r1.f , g1.f , b1.f
sp(source,cible)
;If r<0:r=0:EndIf
;If g<0:g=0:EndIf
;If b<0:b=0:EndIf
;If r>360:r=360:EndIf
;If g>360:g=360:EndIf
;If b>360:b=360:EndIf
r=r-180
g=g-180
b=b-180
r1.f=r/255.0*3.14/180.0
g1.f=g/255.0*3.14/180.0
b1.f=b/255.0*3.14/180.0
Dim tabr(255)
Dim tabg(255)
Dim tabb(255)
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
clampRGB(tabr(i),tabg(i),tabb(i))
Next
For i=0 To taille
pixel=PeekL(source_p+i*4)
returnRGB(pixel,r,g,b)
PokeL(cible_p+i*4, tabr(r)<<16 + tabg(g)<<8 + tabb(b))
Next
FreeArray(tabr())
FreeArray(tabg())
FreeArray(tabb())
EndProcedure
;-------------------------------------------------------------------
; min = 0 : max = 360
Procedure Filter_bend(source.q,cible.q,r.q,g.q,b.q)
Protected s.q , palr.q , palg.q , palb.q , v.f , i.q
Protected r1.f , g1.f , b1.f
sp(source,cible)
r=r-180
g=g-180
b=b-180
r1.f=r/255.0*3.14/180.0
g1.f=g/255.0*3.14/180.0
b1.f=b/255.0*3.14/180.0
Dim tabr(255)
Dim tabg(255)
Dim tabb(255)
palr=@tabr()
palg=@tabg()
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
clampRGB(tabr(i),tabg(i),tabb(i))
Next
Dim save.q(14)
s=@save()
EnableASM
Save_reg()
!mov rsi,[p.v_source_p]
!mov rdi,[p.v_cible_p]
!mov r8,[p.v_palr]
!mov r9,[p.v_palg]
!mov r10,[p.v_palb]
!mov rdx,[p.v_taille]
!bend_2:
!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
!sub rdx,1
!jnz bend_2
Rest_reg()
DisableASM
FreeArray(save())
FreeArray(tabr())
FreeArray(tabg())
FreeArray(tabb())
EndProcedure
;-------------------------------------------------------------------
Procedure Filter_Brightness(source,cible,r,g,b)
Protected color.q , s.q
sp(source,cible)
color = r<<32 + g<<16 + b
EnableASM
Save_reg()
!pxor xmm3,xmm3
!mov rsi,[p.v_source_p]
!mov rdi,[p.v_cible_p]
!mov rdx,[p.v_taille]
!shr rdx,1
!mov rax,[p.v_color]
!movq xmm0,rax
!VPBROADCASTQ xmm0,xmm0 ; | 64bits A | 64 bits B | ; A = B
!xor rcx,rcx
!Filter_Brightness_1:
!movq xmm1,[rsi+rcx]
!punpcklbw xmm1,xmm3 ; converti r,g,b 8bits en r,g,b 16bits
!paddsw xmm1,xmm0 ; addition signée (-32767 a 32768 ) ; si var=(a-+b) if var<-32767 : var= -32767 : if var>32768 : var = 32768
!packuswb xmm1,xmm1 ; converti r,g,b 16bits en rgb 8bits de 0 a 255 : if var<0 : var =0 : if var >255 : var =255
!movq [rdi+rcx],xmm1
!add rcx,8
!dec rdx
!jnz Filter_Brightness_1
Rest_reg()
DisableASM
EndProcedure
;------------------------------------------------------------------
UseJPEGImageDecoder()
UsePNGImageDecoder()
Global imgx=1200
Global imgy=800
If OpenWindow(0, 0, 0, imgx, imgy, "balance", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define source.q , cible.q , t.q , file$ , i , var
ScrollBarGadget(1, imgx/4, 1, imgx/2, 24, 0, 720, 25)
ScrollBarGadget(2, imgx/4, 25, imgx/2, 24, 0, 512, 25)
SetGadgetState(2, 256)
file$ = OpenFileRequester("Image","","",0)
source=10
cible=20
If Load_Image(source,file$) = 0 ; <- commande differente de "LOADIMAGE"
MessageRequester("erreur", "image non chargeé" ,#PB_MessageRequester_Ok )
End
EndIf
ResizeImage(source,imgx,imgy,#PB_Image_Smooth)
CreateImage(cible,imgx,imgy,32) ; l'image doit entre en mode 32bits
var=200
SetGadgetState(1,var)
Filter_bend(source,cible,var,var,var)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
Select EventGadget()
Case 1
var=GetGadgetState(1)
t=ElapsedMilliseconds()
Filter_bend(source,cible,var,var,var) ; version asm
;Filter_bend_pb(source,cible,var,var,var) ; version pureabsic
t=ElapsedMilliseconds()-t
Case 2
var=GetGadgetState(2)-256
t=ElapsedMilliseconds()
Filter_Brightness(source,cible,var,var,var)
t=ElapsedMilliseconds()-t
EndSelect
EndSelect
StartDrawing(WindowOutput(0))
DrawImage(ImageID(cible),0,50)
DrawText(5,50,"temps : "+Str(t))
DrawText(5,5,Str(GetGadgetState(1))+" ")
DrawText(5,25,Str(GetGadgetState(2)-256)+" ")
StopDrawing()
ForEver
EndIf