ImageFiter.pbi
Code: Select all
Structure IFRGBA
r.f
g.f
b.f
a.f
EndStructure
Structure IFContext
x.l ; x
y.l ; y
w.l ; width
h.l ; height
ri.f ; red in [0.0f - 1.0f]
gi.f ; green in [0.0f - 1.0f]
bi.f ; blue in [0.0f - 1.0f]
ai.f ; alpha in [0.0f - 1.0f]
ro.f ; red out [0.0f - 1.0f]
go.f ; green out [0.0f - 1.0f]
bo.f ; blue out [0.0f - 1.0f]
ao.f ; alpha out [0.0f - 1.0f]
arg1.q ; argument 1
arg2.q ; argument 2
px.IFRGBA[0] ; pixel buffer
EndStructure
Prototype ProtoIFCallBack(*ctx.IFContext)
Procedure.i ImageFilter(Image.i, *ImageFilterCallback, arg1.q = 0, arg2.q = 0)
If IsImage(Image) = 0
ProcedureReturn 0
EndIf
Protected result.i, i.i, x.l, y.l, c.l
Protected width.l = ImageWidth(Image)
Protected height.l = ImageHeight(Image)
Protected *mem_unaligned = AllocateMemory(width * height * 16 + 80)
Protected *mem.IFContext = (*mem_unaligned + 15) & -16
Protected Callback.ProtoIFCallback = *ImageFilterCallback
If *mem_unaligned
result.i = CreateImage(#PB_Any, width, height, 32)
If result
*mem\w = width
*mem\h = height
*mem\arg1 = arg1
*mem\arg2 = arg2
StartDrawing(ImageOutput(Image))
DrawingMode(#PB_2DDrawing_AllChannels)
i = *mem + 64
y = 0
While y < height
x = 0
While x < width
c = Point(x, y)
!mov eax, 0x3b808081; 1.0f / 255.0f
!movd xmm2, eax
!pshufd xmm2, xmm2, 0
!pxor xmm1, xmm1
!movd xmm0, [p.v_c]
!punpcklbw xmm0, xmm1
!punpcklwd xmm0, xmm1
!cvtdq2ps xmm0, xmm0
!mulps xmm0, xmm2
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
!mov edx, [p.v_i]
!movdqa [edx], xmm0
!add edx, 16
!mov [p.v_i], edx
CompilerElse
!mov rdx, [p.v_i]
!movdqa [rdx], xmm0
!add rdx, 16
!mov [p.v_i], rdx
CompilerEndIf
x + 1
Wend
y + 1
Wend
StopDrawing()
StartDrawing(ImageOutput(result))
DrawingMode(#PB_2DDrawing_AllChannels)
i = *mem + 64
y = 0
While y < height
x = 0
While x < width
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
!mov edx, [p.v_i]
!movdqa xmm0, [edx]
!add edx, 16
!mov [p.v_i], edx
!mov edx, [p.p_mem]
!movdqa [edx + 16], xmm0
!movdqa [edx + 32], xmm0
!mov eax, [p.v_x]
!mov [edx], eax
!mov eax, [p.v_y]
!mov [edx + 4], eax
Callback(*mem)
!mov edx, [p.p_mem]
!movdqa xmm0, [edx + 32]
CompilerElse
!mov rdx, [p.v_i]
!movdqa xmm0, [rdx]
!add rdx, 16
!mov [p.v_i], rdx
!mov rdx, [p.p_mem]
!movdqa [rdx + 16], xmm0
!movdqa [rdx + 32], xmm0
!mov eax, [p.v_x]
!mov dword [rdx], eax
!mov eax, [p.v_y]
!mov dword [rdx + 4], eax
Callback(*mem)
!mov rdx, [p.p_mem]
!movdqa xmm0, [rdx + 32]
CompilerEndIf
!mov eax, 0x437f0000; 255.0f
!movd xmm2, eax
!pshufd xmm2, xmm2, 0
!mulps xmm0, xmm2
!cvtps2dq xmm0, xmm0
!packssdw xmm0, xmm0
!packuswb xmm0, xmm0
!movd [p.v_c], xmm0
Plot(x, y, c)
x + 1
Wend
y + 1
Wend
StopDrawing()
EndIf
FreeMemory(*mem_unaligned)
EndIf
ProcedureReturn result
EndProcedure