1*8ccd4a63SDavid du Colombier #include <u.h>
2*8ccd4a63SDavid du Colombier #include <libc.h>
3*8ccd4a63SDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier
5*8ccd4a63SDavid du Colombier /*
6*8ccd4a63SDavid du Colombier * This original version, although fast and a true inverse of
7*8ccd4a63SDavid du Colombier * cmap2rgb, in the sense that rgb2cmap(cmap2rgb(c))
8*8ccd4a63SDavid du Colombier * returned the original color, does a terrible job for RGB
9*8ccd4a63SDavid du Colombier * triples that do not appear in the color map, so it has been
10*8ccd4a63SDavid du Colombier * replaced by the much slower version below, that loops
11*8ccd4a63SDavid du Colombier * over the color map looking for the nearest point in RGB
12*8ccd4a63SDavid du Colombier * space. There is no visual psychology reason for that
13*8ccd4a63SDavid du Colombier * criterion, but it's easy to implement and the results are
14*8ccd4a63SDavid du Colombier * far more pleasing.
15*8ccd4a63SDavid du Colombier *
167dd7cddfSDavid du Colombier int
177dd7cddfSDavid du Colombier rgb2cmap(int cr, int cg, int cb)
187dd7cddfSDavid du Colombier {
197dd7cddfSDavid du Colombier int r, g, b, v, cv;
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier if(cr < 0)
227dd7cddfSDavid du Colombier cr = 0;
237dd7cddfSDavid du Colombier else if(cr > 255)
247dd7cddfSDavid du Colombier cr = 255;
257dd7cddfSDavid du Colombier if(cg < 0)
267dd7cddfSDavid du Colombier cg = 0;
277dd7cddfSDavid du Colombier else if(cg > 255)
287dd7cddfSDavid du Colombier cg = 255;
297dd7cddfSDavid du Colombier if(cb < 0)
307dd7cddfSDavid du Colombier cb = 0;
317dd7cddfSDavid du Colombier else if(cb > 255)
327dd7cddfSDavid du Colombier cb = 255;
337dd7cddfSDavid du Colombier r = cr>>6;
347dd7cddfSDavid du Colombier g = cg>>6;
357dd7cddfSDavid du Colombier b = cb>>6;
367dd7cddfSDavid du Colombier cv = cr;
377dd7cddfSDavid du Colombier if(cg > cv)
387dd7cddfSDavid du Colombier cv = cg;
397dd7cddfSDavid du Colombier if(cb > cv)
407dd7cddfSDavid du Colombier cv = cb;
417dd7cddfSDavid du Colombier v = (cv>>4)&3;
427dd7cddfSDavid du Colombier return ((((r<<2)+v)<<4)+(((g<<2)+b+v-r)&15));
437dd7cddfSDavid du Colombier }
44*8ccd4a63SDavid du Colombier */
45*8ccd4a63SDavid du Colombier
46*8ccd4a63SDavid du Colombier int
rgb2cmap(int cr,int cg,int cb)47*8ccd4a63SDavid du Colombier rgb2cmap(int cr, int cg, int cb)
48*8ccd4a63SDavid du Colombier {
49*8ccd4a63SDavid du Colombier int i, r, g, b, sq;
50*8ccd4a63SDavid du Colombier ulong rgb;
51*8ccd4a63SDavid du Colombier int best, bestsq;
52*8ccd4a63SDavid du Colombier
53*8ccd4a63SDavid du Colombier best = 0;
54*8ccd4a63SDavid du Colombier bestsq = 0x7FFFFFFF;
55*8ccd4a63SDavid du Colombier for(i=0; i<256; i++){
56*8ccd4a63SDavid du Colombier rgb = cmap2rgb(i);
57*8ccd4a63SDavid du Colombier r = (rgb>>16) & 0xFF;
58*8ccd4a63SDavid du Colombier g = (rgb>>8) & 0xFF;
59*8ccd4a63SDavid du Colombier b = (rgb>>0) & 0xFF;
60*8ccd4a63SDavid du Colombier sq = (r-cr)*(r-cr)+(g-cg)*(g-cg)+(b-cb)*(b-cb);
61*8ccd4a63SDavid du Colombier if(sq < bestsq){
62*8ccd4a63SDavid du Colombier bestsq = sq;
63*8ccd4a63SDavid du Colombier best = i;
64*8ccd4a63SDavid du Colombier }
65*8ccd4a63SDavid du Colombier }
66*8ccd4a63SDavid du Colombier return best;
67*8ccd4a63SDavid du Colombier }
687dd7cddfSDavid du Colombier
697dd7cddfSDavid du Colombier int
cmap2rgb(int c)707dd7cddfSDavid du Colombier cmap2rgb(int c)
717dd7cddfSDavid du Colombier {
727dd7cddfSDavid du Colombier int j, num, den, r, g, b, v, rgb;
737dd7cddfSDavid du Colombier
747dd7cddfSDavid du Colombier r = c>>6;
757dd7cddfSDavid du Colombier v = (c>>4)&3;
767dd7cddfSDavid du Colombier j = (c-v+r)&15;
777dd7cddfSDavid du Colombier g = j>>2;
787dd7cddfSDavid du Colombier b = j&3;
797dd7cddfSDavid du Colombier den=r;
807dd7cddfSDavid du Colombier if(g>den)
817dd7cddfSDavid du Colombier den=g;
827dd7cddfSDavid du Colombier if(b>den)
837dd7cddfSDavid du Colombier den=b;
847dd7cddfSDavid du Colombier if(den==0) {
857dd7cddfSDavid du Colombier v *= 17;
867dd7cddfSDavid du Colombier rgb = (v<<16)|(v<<8)|v;
877dd7cddfSDavid du Colombier }
887dd7cddfSDavid du Colombier else{
897dd7cddfSDavid du Colombier num=17*(4*den+v);
907dd7cddfSDavid du Colombier rgb = ((r*num/den)<<16)|((g*num/den)<<8)|(b*num/den);
917dd7cddfSDavid du Colombier }
927dd7cddfSDavid du Colombier return rgb;
937dd7cddfSDavid du Colombier }
947dd7cddfSDavid du Colombier
957dd7cddfSDavid du Colombier int
cmap2rgba(int c)967dd7cddfSDavid du Colombier cmap2rgba(int c)
977dd7cddfSDavid du Colombier {
987dd7cddfSDavid du Colombier return (cmap2rgb(c)<<8)|0xFF;
997dd7cddfSDavid du Colombier }
100