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