From c3c062672a859426c8583e197795e67150a01a89 Mon Sep 17 00:00:00 2001 From: nfnt Date: Tue, 12 May 2015 15:19:11 +0200 Subject: [PATCH] Reverse alpha-premultiplication for image.RGBA, image.RGBA64 and generic images types. --- converter.go | 59 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/converter.go b/converter.go index f4d9d0f..84bd284 100644 --- a/converter.go +++ b/converter.go @@ -64,6 +64,17 @@ func resizeGeneric(in image.Image, out *image.NRGBA64, scale float64, coeffs []i xi = maxX } r, g, b, a := in.At(xi+in.Bounds().Min.X, x+in.Bounds().Min.Y).RGBA() + + // reverse alpha-premultiplication. + if a != 0 { + r *= 0xffff + r /= a + g *= 0xffff + g /= a + b *= 0xffff + b /= a + } + rgba[0] += int64(coeff) * int64(r) rgba[1] += int64(coeff) * int64(g) rgba[2] += int64(coeff) * int64(b) @@ -112,10 +123,26 @@ func resizeRGBA(in *image.RGBA, out *image.NRGBA, scale float64, coeffs []int16, default: xi = 0 } - rgba[0] += int32(coeff) * int32(row[xi+0]) - rgba[1] += int32(coeff) * int32(row[xi+1]) - rgba[2] += int32(coeff) * int32(row[xi+2]) - rgba[3] += int32(coeff) * int32(row[xi+3]) + + r := uint32(row[xi+0]) + g := uint32(row[xi+1]) + b := uint32(row[xi+2]) + a := uint32(row[xi+3]) + + // reverse alpha-premultiplication. + if a != 0 { + r *= 0xffff + r /= a + g *= 0xffff + g /= a + b *= 0xffff + b /= a + } + + rgba[0] += int32(coeff) * int32(r) + rgba[1] += int32(coeff) * int32(g) + rgba[2] += int32(coeff) * int32(b) + rgba[3] += int32(coeff) * int32(a) sum += int32(coeff) } } @@ -192,10 +219,26 @@ func resizeRGBA64(in *image.RGBA64, out *image.NRGBA64, scale float64, coeffs [] default: xi = 0 } - rgba[0] += int64(coeff) * int64(uint16(row[xi+0])<<8|uint16(row[xi+1])) - rgba[1] += int64(coeff) * int64(uint16(row[xi+2])<<8|uint16(row[xi+3])) - rgba[2] += int64(coeff) * int64(uint16(row[xi+4])<<8|uint16(row[xi+5])) - rgba[3] += int64(coeff) * int64(uint16(row[xi+6])<<8|uint16(row[xi+7])) + + r := uint32(uint16(row[xi+0])<<8 | uint16(row[xi+1])) + g := uint32(uint16(row[xi+2])<<8 | uint16(row[xi+3])) + b := uint32(uint16(row[xi+4])<<8 | uint16(row[xi+5])) + a := uint32(uint16(row[xi+6])<<8 | uint16(row[xi+7])) + + // reverse alpha-premultiplication. + if a != 0 { + r *= 0xffff + r /= a + g *= 0xffff + g /= a + b *= 0xffff + b /= a + } + + rgba[0] += int64(coeff) * int64(r) + rgba[1] += int64(coeff) * int64(g) + rgba[2] += int64(coeff) * int64(b) + rgba[3] += int64(coeff) * int64(a) sum += int64(coeff) } }