~eliasnaur/colorspace

0de846b04b43b0f2690286f009a2b2b402b55c59 — Elias Naur 2 years ago 1a46ef3 main
implement image.RGBA64Image, draw.RGBA64Image support

As suggested by Nigel Tao in https://github.com/golang/go/issues/11420.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
1 files changed, 27 insertions(+), 16 deletions(-)

M srgb.go
M srgb.go => srgb.go +27 -16
@@ 16,36 16,47 @@ import (

// SRGBA wraps an Image encoded in the sRGB color space.
type SRGBA struct {
	image.Image
	image.RGBA64Image
}

// NewSRGBA returns an SRGBA that wraps img. It panics if ima
// doesn't implement image.RGBA64Image.
func NewSRGBA(img image.Image) *SRGBA {
	return &SRGBA{img}
	return &SRGBA{img.(image.RGBA64Image)}
}

// At converts an sRGB color from the underlying image to linear RGB.
func (p *SRGBA) At(x, y int) color.Color {
	c := p.Image.At(x, y)
	r, g, b, a := c.RGBA()
// RGBA64At converts an sRGB color from the underlying image to linear RGB.
func (p *SRGBA) RGBA64At(x, y int) color.RGBA64 {
	c := p.RGBA64Image.RGBA64At(x, y)
	ret := color.RGBA64{
		uint16(sRGBToLinear(float32(r)/0xffff)*0xffff + .5),
		uint16(sRGBToLinear(float32(g)/0xffff)*0xffff + .5),
		uint16(sRGBToLinear(float32(b)/0xffff)*0xffff + .5),
		uint16(a),
		uint16(sRGBToLinear(float32(c.R)/0xffff)*0xffff + .5),
		uint16(sRGBToLinear(float32(c.G)/0xffff)*0xffff + .5),
		uint16(sRGBToLinear(float32(c.B)/0xffff)*0xffff + .5),
		c.A,
	}
	return ret
}

// At converts an sRGB color from the underlying image to linear RGB.
func (p *SRGBA) At(x, y int) color.Color {
	return p.RGBA64At(x, y)
}

// Set converts a linear RGB color to sRGB and stores it in the underlying image.
func (p *SRGBA) Set(x, y int, c color.Color) {
	r, g, b, a := c.RGBA()
	srgb := color.RGBA{
		uint8(linearTosRGB(float32(r)/0xffff)*0xff + .5),
		uint8(linearTosRGB(float32(g)/0xffff)*0xff + .5),
		uint8(linearTosRGB(float32(b)/0xffff)*0xff + .5),
		uint8(a >> 8),
	p.SetRGBA64(x, y, color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)})
}

// SetRGBA64 converts a linear RGB color to sRGB and stores it in the underlying image.
func (p *SRGBA) SetRGBA64(x, y int, c color.RGBA64) {
	srgb := color.RGBA64{
		uint16(linearTosRGB(float32(c.R)/0xffff)*0xffff + .5),
		uint16(linearTosRGB(float32(c.G)/0xffff)*0xffff + .5),
		uint16(linearTosRGB(float32(c.B)/0xffff)*0xffff + .5),
		c.A,
	}
	p.Image.(draw.Image).Set(x, y, srgb)
	p.RGBA64Image.(draw.RGBA64Image).SetRGBA64(x, y, srgb)
}

func linearTosRGB(c float32) float32 {