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)
}
|