This commit is contained in:
Ryan Oldenburg 2021-02-25 15:13:14 -06:00
parent f139c5dc79
commit b623150b3f

View file

@ -218,7 +218,7 @@ proc toPremultipliedAlpha*(image: Image) =
# When supported, SIMD convert as much as possible # When supported, SIMD convert as much as possible
let let
alphaMask = mm_set1_epi32(cast[int32](0xff000000)) alphaMask = mm_set1_epi32(cast[int32](0xff000000))
alphaMaskComp = mm_set1_epi32(0x00ffffff) notAlphaMask = mm_set1_epi32(0x00ffffff)
oddMask = mm_set1_epi16(cast[int16](0xff00)) oddMask = mm_set1_epi16(cast[int16](0xff00))
div255 = mm_set1_epi16(cast[int16](0x8081)) div255 = mm_set1_epi16(cast[int16](0x8081))
@ -226,6 +226,11 @@ proc toPremultipliedAlpha*(image: Image) =
var var
color = mm_loadu_si128(image.data[j].addr) color = mm_loadu_si128(image.data[j].addr)
alpha = mm_and_si128(color, alphaMask) alpha = mm_and_si128(color, alphaMask)
let eqOpaque = mm_cmpeq_epi16(alpha, alphaMask)
if mm_movemask_epi8(eqOpaque) != 0xffff:
# If not all of the alpha values are 255, premultiply
var
colorEven = mm_slli_epi16(color, 8) colorEven = mm_slli_epi16(color, 8)
colorOdd = mm_and_si128(color, oddMask) colorOdd = mm_and_si128(color, oddMask)
@ -239,7 +244,7 @@ proc toPremultipliedAlpha*(image: Image) =
color = mm_or_si128(colorEven, mm_slli_epi16(colorOdd, 8)) color = mm_or_si128(colorEven, mm_slli_epi16(colorOdd, 8))
color = mm_or_si128( color = mm_or_si128(
mm_and_si128(alpha, alphaMask), mm_and_si128(color, alphaMaskComp) mm_and_si128(alpha, alphaMask), mm_and_si128(color, notAlphaMask)
) )
mm_storeu_si128(image.data[j].addr, color) mm_storeu_si128(image.data[j].addr, color)
@ -247,6 +252,7 @@ proc toPremultipliedAlpha*(image: Image) =
# Convert whatever is left # Convert whatever is left
for j in i ..< image.data.len: for j in i ..< image.data.len:
var c = image.data[j] var c = image.data[j]
if c.a != 255:
c.r = ((c.r.uint32 * c.a.uint32) div 255).uint8 c.r = ((c.r.uint32 * c.a.uint32) div 255).uint8
c.g = ((c.g.uint32 * c.a.uint32) div 255).uint8 c.g = ((c.g.uint32 * c.a.uint32) div 255).uint8
c.b = ((c.b.uint32 * c.a.uint32) div 255).uint8 c.b = ((c.b.uint32 * c.a.uint32) div 255).uint8