9fans.net/go@v0.0.5/draw/rgb.go (about)

     1  package draw
     2  
     3  /*
     4   * This original version, although fast and a true inverse of
     5   * cmap2rgb, in the sense that rgb2cmap(cmap2rgb(c))
     6   * returned the original color, does a terrible job for RGB
     7   * triples that do not appear in the color map, so it has been
     8   * replaced by the much slower version below, that loops
     9   * over the color map looking for the nearest point in RGB
    10   * space.  There is no visual psychology reason for that
    11   * criterion, but it's easy to implement and the results are
    12   * far more pleasing.
    13   *
    14  int
    15  rgb2cmap(int cr, int cg, int cb)
    16  {
    17  	int r, g, b, v, cv;
    18  
    19  	if(cr < 0)
    20  		cr = 0;
    21  	else if(cr > 255)
    22  		cr = 255;
    23  	if(cg < 0)
    24  		cg = 0;
    25  	else if(cg > 255)
    26  		cg = 255;
    27  	if(cb < 0)
    28  		cb = 0;
    29  	else if(cb > 255)
    30  		cb = 255;
    31  	r = cr>>6;
    32  	g = cg>>6;
    33  	b = cb>>6;
    34  	cv = cr;
    35  	if(cg > cv)
    36  		cv = cg;
    37  	if(cb > cv)
    38  		cv = cb;
    39  	v = (cv>>4)&3;
    40  	return ((((r<<2)+v)<<4)+(((g<<2)+b+v-r)&15));
    41  }
    42  */
    43  
    44  func rgb2cmap(cr, cg, cb int) int {
    45  	best := 0
    46  	bestsq := 0x7FFFFFFF
    47  	for i := 0; i < 256; i++ {
    48  		r, g, b := cmap2rgb(i)
    49  		sq := (r-cr)*(r-cr) + (g-cg)*(g-cg) + (b-cb)*(b-cb)
    50  		if sq < bestsq {
    51  			bestsq = sq
    52  			best = i
    53  		}
    54  	}
    55  	return best
    56  }
    57  
    58  func cmap2rgb(c int) (r, g, b int) {
    59  	r = c >> 6
    60  	v := (c >> 4) & 3
    61  	j := (c - v + r) & 15
    62  	g = j >> 2
    63  	b = j & 3
    64  	den := r
    65  	if g > den {
    66  		den = g
    67  	}
    68  	if b > den {
    69  		den = b
    70  	}
    71  	if den == 0 {
    72  		v *= 17
    73  		return v, v, v
    74  	}
    75  	num := 17 * (4*den + v)
    76  	r = r * num / den
    77  	g = g * num / den
    78  	b = b * num / den
    79  	return
    80  }
    81  
    82  func cmap2rgba(c int) Color {
    83  	r, g, b := cmap2rgb(c)
    84  	return Color(r<<24 | g<<16 | b<<8 | 0xFF)
    85  }