Here's a small module to premultiply and unpremultiply a 32 bit pixel buffer.
Code: Select all
DeclareModule Premultiply
; 32 bits RGBA or BGRA pixel buffer
Declare PremultiplyPixels(*PixelBuffer32, NumPixels)
Declare UnpremultiplyPixels(*PixelBuffer32, NumPixels)
EndDeclareModule
Module Premultiply
EnableASM
DisableDebugger
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Macro rax : eax : EndMacro
Macro rbx : ebx : EndMacro
Macro rcx : ecx : EndMacro
Macro rdx : edx : EndMacro
Macro rsi : esi : EndMacro
CompilerEndIf
Procedure PremultiplyPixels(*PixelBuffer32, NumPixels)
lea rax, [premultiply.l_premultiplyTable]
mov rdx, *PixelBuffer32
mov rcx, NumPixels
push rbx
push rsi
mov rsi, rax
!premultiply.l_premul0:
movzx eax, word [rdx + 2]
cmp ah, 255
!je premultiply.l_premul1
movzx ebx, byte [rsi + rax]
mov [rdx + 2], bl
mov al, [rdx + 1]
movzx ebx, byte [rsi + rax]
mov [rdx + 1], bl
mov al, [rdx]
movzx ebx, byte [rsi + rax]
mov [rdx], bl
!premultiply.l_premul1:
add rdx, 4
sub rcx, 1
!jnz premultiply.l_premul0
pop rsi
pop rbx
EndProcedure
Procedure UnpremultiplyPixels(*PixelBuffer32, NumPixels)
lea rax, [premultiply.l_premultiplyTable + 0x10000]
mov rdx, *PixelBuffer32
mov rcx, NumPixels
push rbx
push rsi
mov rsi, rax
!premultiply.l_unpremul0:
movzx eax, word [rdx + 2]
cmp ah, 255
!je premultiply.l_unpremul1
cmp ah, 0
!je premultiply.l_unpremul1
movzx ebx, byte [rsi + rax]
mov [rdx + 2], bl
mov al, [rdx + 1]
movzx ebx, byte [rsi + rax]
mov [rdx + 1], bl
mov al, [rdx]
movzx ebx, byte [rsi + rax]
mov [rdx], bl
!premultiply.l_unpremul1:
add rdx, 4
sub rcx, 1
!jnz premultiply.l_unpremul0
pop rsi
pop rbx
EndProcedure
Procedure FillTable()
lea rdx, [premultiply.l_premultiplyTable]
push rbx
mov ebx, 255
sub ecx, ecx
!premultiply.l_filltable0:
movzx eax, ch
mul cl
add eax, 127
div bl
mov [rdx + rcx], al
add cx, 1
!jnz premultiply.l_filltable0
add rdx, 0x10000
mov ecx, 0x100
sub bx, bx
!premultiply.l_filltable1:
mov eax, 255
cmp cl, ch
!jae premultiply.l_filltable2
mul cl
add ax, bx
div ch
!premultiply.l_filltable2:
mov [rdx + rcx], al
add cl, 1
!jnz premultiply.l_filltable1
movzx bx, ch
add bx, 1
shr bx, 1
add ch, 1
!jnz premultiply.l_filltable1
pop rbx
EndProcedure
FillTable()
DataSection
!premultiply.l_premultiplyTable: times 131072 db 0
EndDataSection
EndModule
Code: Select all
Premultiply::UnpremultiplyPixels(DrawingBuffer(), (DrawingBufferPitch()*OutputHeight())>>2)