all repos — honk @ e2c6e21093741f27092b4ff017fff619dd1f0173

my fork of honk

avatar.go (view raw)

  1//
  2// Copyright (c) 2019 Ted Unangst <tedu@tedunangst.com>
  3//
  4// Permission to use, copy, modify, and distribute this software for any
  5// purpose with or without fee is hereby granted, provided that the above
  6// copyright notice and this permission notice appear in all copies.
  7//
  8// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15
 16package main
 17
 18import (
 19	"bufio"
 20	"bytes"
 21	"crypto/sha512"
 22	"image"
 23	"image/png"
 24	"log"
 25	"strconv"
 26	"strings"
 27)
 28
 29var avatarcolors = [4][4]byte{
 30	{16, 0, 48, 255},
 31	{48, 0, 96, 255},
 32	{72, 0, 144, 255},
 33	{96, 0, 192, 255},
 34}
 35
 36func loadAvatarColors() {
 37	var colors string
 38	getconfig("avatarcolors", &colors)
 39	if colors == "" {
 40		return
 41	}
 42	r := bufio.NewReader(strings.NewReader(colors))
 43	for i := 0; i < 4; i++ {
 44		l, _ := r.ReadString(' ')
 45		for l == " " {
 46			l, _ = r.ReadString(' ')
 47		}
 48		l = strings.Trim(l, "# \n")
 49		if len(l) == 6 {
 50			l = l + "ff"
 51		}
 52		c, err := strconv.ParseUint(l, 16, 32)
 53		if err != nil {
 54			log.Printf("error reading avatar color %d: %s", i, err)
 55			continue
 56		}
 57		avatarcolors[i][0] = byte(c >> 24 & 0xff)
 58		avatarcolors[i][1] = byte(c >> 16 & 0xff)
 59		avatarcolors[i][2] = byte(c >> 8 & 0xff)
 60		avatarcolors[i][3] = byte(c >> 0 & 0xff)
 61	}
 62}
 63
 64func genAvatar(name string) []byte {
 65	h := sha512.New()
 66	h.Write([]byte(name))
 67	s := h.Sum(nil)
 68	img := image.NewNRGBA(image.Rect(0, 0, 64, 64))
 69	for i := 0; i < 64; i++ {
 70		for j := 0; j < 64; j++ {
 71			p := i*img.Stride + j*4
 72			xx := i/16*16 + j/16
 73			x := s[xx]
 74			if x < 64 {
 75				img.Pix[p+0] = avatarcolors[0][0]
 76				img.Pix[p+1] = avatarcolors[0][1]
 77				img.Pix[p+2] = avatarcolors[0][2]
 78				img.Pix[p+3] = avatarcolors[0][3]
 79			} else if x < 128 {
 80				img.Pix[p+0] = avatarcolors[1][0]
 81				img.Pix[p+1] = avatarcolors[1][1]
 82				img.Pix[p+2] = avatarcolors[1][2]
 83				img.Pix[p+3] = avatarcolors[1][3]
 84			} else if x < 192 {
 85				img.Pix[p+0] = avatarcolors[2][0]
 86				img.Pix[p+1] = avatarcolors[2][1]
 87				img.Pix[p+2] = avatarcolors[2][2]
 88				img.Pix[p+3] = avatarcolors[2][3]
 89			} else {
 90				img.Pix[p+0] = avatarcolors[3][0]
 91				img.Pix[p+1] = avatarcolors[3][1]
 92				img.Pix[p+2] = avatarcolors[3][2]
 93				img.Pix[p+3] = avatarcolors[3][3]
 94			}
 95		}
 96	}
 97	var buf bytes.Buffer
 98	png.Encode(&buf, img)
 99	return buf.Bytes()
100}