File: color_spaces.go

package info (click to toggle)
golang-github-makeworld-the-better-one-dither 2.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,460 kB
  • sloc: makefile: 4
file content (51 lines) | stat: -rw-r--r-- 1,488 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package dither

import (
	"image/color"
	"math"
)

// linearize1 linearizes an R, G, or B channel value from an sRGB color.
// Must be in the range [0, 1].
func linearize1(v float64) float64 {
	if v <= 0.04045 {
		return v / 12.92
	}
	return math.Pow((v+0.055)/1.055, 2.4)
}

func linearize65535(i uint16) uint16 {
	v := float64(i) / 65535.0
	return uint16(math.RoundToEven(linearize1(v) * 65535.0))
}

func linearize255to65535(i uint8) uint16 {
	v := float64(i) / 255.0
	return uint16(math.RoundToEven(linearize1(v) * 65535.0))
}

// toLinearRGB converts a non-linear sRGB color to a linear RGB color space.
// RGB values are taken directly and alpha value is ignored, so this will not
// handle non-opaque colors properly.
func toLinearRGB(c color.Color) (uint16, uint16, uint16) {
	// Optimize for different color types
	switch v := c.(type) {
	case color.Gray:
		g := linearize255to65535(v.Y)
		return g, g, g
	case color.Gray16:
		g := linearize65535(v.Y)
		return g, g, g
	case color.NRGBA:
		return linearize255to65535(v.R), linearize255to65535(v.G), linearize255to65535(v.B)
	case color.NRGBA64:
		return linearize65535(v.R), linearize65535(v.G), linearize65535(v.B)
	case color.RGBA:
		return linearize255to65535(v.R), linearize255to65535(v.G), linearize255to65535(v.B)
	case color.RGBA64:
		return linearize65535(v.R), linearize65535(v.G), linearize65535(v.B)
	}

	r, g, b, _ := c.RGBA()
	return linearize65535(uint16(r)), linearize65535(uint16(g)), linearize65535(uint16(b))
}