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