Home | History | Annotate | Download | only in palette
      1 // Copyright 2013 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // +build ignore
      6 
      7 package main
      8 
      9 // This program generates palette.go. Invoke it as
     10 //	go run gen.go -output palette.go
     11 
     12 import (
     13 	"bytes"
     14 	"flag"
     15 	"fmt"
     16 	"go/format"
     17 	"io"
     18 	"io/ioutil"
     19 	"log"
     20 )
     21 
     22 var filename = flag.String("output", "palette.go", "output file name")
     23 
     24 func main() {
     25 	flag.Parse()
     26 
     27 	var buf bytes.Buffer
     28 
     29 	fmt.Fprintln(&buf, `// Copyright 2013 The Go Authors. All rights reserved.
     30 // Use of this source code is governed by a BSD-style
     31 // license that can be found in the LICENSE file.`)
     32 	fmt.Fprintln(&buf)
     33 	fmt.Fprintln(&buf, "// generated by go run gen.go -output palette.go; DO NOT EDIT")
     34 	fmt.Fprintln(&buf)
     35 	fmt.Fprintln(&buf, "package palette")
     36 	fmt.Fprintln(&buf)
     37 	fmt.Fprintln(&buf, `import "image/color"`)
     38 	fmt.Fprintln(&buf)
     39 	printPlan9(&buf)
     40 	printWebSafe(&buf)
     41 
     42 	data, err := format.Source(buf.Bytes())
     43 	if err != nil {
     44 		log.Fatal(err)
     45 	}
     46 	err = ioutil.WriteFile(*filename, data, 0644)
     47 	if err != nil {
     48 		log.Fatal(err)
     49 	}
     50 }
     51 
     52 func printPlan9(w io.Writer) {
     53 	c, lines := [3]int{}, [256]string{}
     54 	for r, i := 0, 0; r != 4; r++ {
     55 		for v := 0; v != 4; v, i = v+1, i+16 {
     56 			for g, j := 0, v-r; g != 4; g++ {
     57 				for b := 0; b != 4; b, j = b+1, j+1 {
     58 					den := r
     59 					if g > den {
     60 						den = g
     61 					}
     62 					if b > den {
     63 						den = b
     64 					}
     65 					if den == 0 {
     66 						c[0] = 0x11 * v
     67 						c[1] = 0x11 * v
     68 						c[2] = 0x11 * v
     69 					} else {
     70 						num := 17 * (4*den + v)
     71 						c[0] = r * num / den
     72 						c[1] = g * num / den
     73 						c[2] = b * num / den
     74 					}
     75 					lines[i+(j&0x0f)] =
     76 						fmt.Sprintf("\tcolor.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff},", c[0], c[1], c[2])
     77 				}
     78 			}
     79 		}
     80 	}
     81 	fmt.Fprintln(w, "// Plan9 is a 256-color palette that partitions the 24-bit RGB space")
     82 	fmt.Fprintln(w, "// into 444 subdivision, with 4 shades in each subcube. Compared to the")
     83 	fmt.Fprintln(w, "// WebSafe, the idea is to reduce the color resolution by dicing the")
     84 	fmt.Fprintln(w, "// color cube into fewer cells, and to use the extra space to increase the")
     85 	fmt.Fprintln(w, "// intensity resolution. This results in 16 gray shades (4 gray subcubes with")
     86 	fmt.Fprintln(w, "// 4 samples in each), 13 shades of each primary and secondary color (3")
     87 	fmt.Fprintln(w, "// subcubes with 4 samples plus black) and a reasonable selection of colors")
     88 	fmt.Fprintln(w, "// covering the rest of the color cube. The advantage is better representation")
     89 	fmt.Fprintln(w, "// of continuous tones.")
     90 	fmt.Fprintln(w, "//")
     91 	fmt.Fprintln(w, "// This palette was used in the Plan 9 Operating System, described at")
     92 	fmt.Fprintln(w, "// https://9p.io/magic/man2html/6/color")
     93 	fmt.Fprintln(w, "var Plan9 = []color.Color{")
     94 	for _, line := range lines {
     95 		fmt.Fprintln(w, line)
     96 	}
     97 	fmt.Fprintln(w, "}")
     98 	fmt.Fprintln(w)
     99 }
    100 
    101 func printWebSafe(w io.Writer) {
    102 	lines := [6 * 6 * 6]string{}
    103 	for r := 0; r < 6; r++ {
    104 		for g := 0; g < 6; g++ {
    105 			for b := 0; b < 6; b++ {
    106 				lines[36*r+6*g+b] =
    107 					fmt.Sprintf("\tcolor.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff},", 0x33*r, 0x33*g, 0x33*b)
    108 			}
    109 		}
    110 	}
    111 	fmt.Fprintln(w, "// WebSafe is a 216-color palette that was popularized by early versions")
    112 	fmt.Fprintln(w, "// of Netscape Navigator. It is also known as the Netscape Color Cube.")
    113 	fmt.Fprintln(w, "//")
    114 	fmt.Fprintln(w, "// See http://en.wikipedia.org/wiki/Web_colors#Web-safe_colors for details.")
    115 	fmt.Fprintln(w, "var WebSafe = []color.Color{")
    116 	for _, line := range lines {
    117 		fmt.Fprintln(w, line)
    118 	}
    119 	fmt.Fprintln(w, "}")
    120 	fmt.Fprintln(w)
    121 }
    122