aboutsummaryrefslogtreecommitdiff
path: root/palette.go
blob: ee946cb011a834ea27d7f20abbd1e95e83734e69 (plain)
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package epd7in3e

import "image/color"

// Color is a panel colour, whose value is the panel's 4-bit nibble
// code. The codes are not dense: 0x4 does not exist, so Blue is 5 and
// Green is 6.
type Color uint8

// The six panel colours. The value of each constant is the nibble
// written to the frame buffer.
const (
	Black  Color = 0x0
	White  Color = 0x1
	Yellow Color = 0x2
	Red    Color = 0x3
	Blue   Color = 0x5
	Green  Color = 0x6
)

// Palette is the six RGB values used for quantising, in index order
// Black, White, Yellow, Red, Blue, Green. A Palette index is not a
// panel code: index 4 is Blue, whose code is 5.
var Palette color.Palette = color.Palette{
	color.RGBA{0, 0, 0, 255},       // 0: Black
	color.RGBA{255, 255, 255, 255}, // 1: White
	color.RGBA{255, 255, 0, 255},   // 2: Yellow
	color.RGBA{255, 0, 0, 255},     // 3: Red
	color.RGBA{0, 0, 255, 255},     // 4: Blue
	color.RGBA{0, 255, 0, 255},     // 5: Green
}

// indexToCode maps a Palette index to the panel nibble code.
var indexToCode = [6]Color{0x0, 0x1, 0x2, 0x3, 0x5, 0x6}

// paletteRGB holds the quantising RGB value of each Palette index, in
// index order.
var paletteRGB = [6][3]uint8{
	{0, 0, 0},
	{255, 255, 255},
	{255, 255, 0},
	{255, 0, 0},
	{0, 0, 255},
	{0, 255, 0},
}

// nearestCode returns the panel code nearest to (r, g, b).
func nearestCode(r, g, b uint8) Color {
	var best Color
	bestD := 1 << 30
	for i := range paletteRGB {
		p := paletteRGB[i]
		dr := int(r) - int(p[0])
		dg := int(g) - int(p[1])
		db := int(b) - int(p[2])
		if d := dr*dr + dg*dg + db*db; d < bestD {
			best, bestD = indexToCode[i], d
		}
	}
	return best
}

// codeOf returns the nearest panel code for an arbitrary color;
// fully transparent pixels become Black.
func codeOf(c color.Color) Color {
	r, g, b, a := c.RGBA()
	if a == 0 {
		return Black
	}
	var r8, g8, b8 uint8
	if a == 0xffff {
		r8, g8, b8 = uint8(r>>8), uint8(g>>8), uint8(b>>8)
	} else {
		r8 = uint8(r * 255 / a)
		g8 = uint8(g * 255 / a)
		b8 = uint8(b * 255 / a)
	}
	return nearestCode(r8, g8, b8)
}