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