17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier
5*80ee5cbfSDavid du Colombier /*
6*80ee5cbfSDavid du Colombier * This original version, although fast and a true inverse of
7*80ee5cbfSDavid du Colombier * cmap2rgb, in the sense that rgb2cmap(cmap2rgb(c))
8*80ee5cbfSDavid du Colombier * returned the original color, does a terrible job for RGB
9*80ee5cbfSDavid du Colombier * triples that do not appear in the color map, so it has been
10*80ee5cbfSDavid du Colombier * replaced by the much slower version below, that loops
11*80ee5cbfSDavid du Colombier * over the color map looking for the nearest point in RGB
12*80ee5cbfSDavid du Colombier * space. There is no visual psychology reason for that
13*80ee5cbfSDavid du Colombier * criterion, but it's easy to implement and the results are
14*80ee5cbfSDavid du Colombier * far more pleasing.
15*80ee5cbfSDavid 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*80ee5cbfSDavid du Colombier */
45*80ee5cbfSDavid du Colombier
46*80ee5cbfSDavid du Colombier int
rgb2cmap(int cr,int cg,int cb)47*80ee5cbfSDavid du Colombier rgb2cmap(int cr, int cg, int cb)
48*80ee5cbfSDavid du Colombier {
49*80ee5cbfSDavid du Colombier int i, r, g, b, sq;
50*80ee5cbfSDavid du Colombier ulong rgb;
51*80ee5cbfSDavid du Colombier int best, bestsq;
52*80ee5cbfSDavid du Colombier
53*80ee5cbfSDavid du Colombier best = 0;
54*80ee5cbfSDavid du Colombier bestsq = 0x7FFFFFFF;
55*80ee5cbfSDavid du Colombier for(i=0; i<256; i++){
56*80ee5cbfSDavid du Colombier rgb = cmap2rgb(i);
57*80ee5cbfSDavid du Colombier r = (rgb>>16) & 0xFF;
58*80ee5cbfSDavid du Colombier g = (rgb>>8) & 0xFF;
59*80ee5cbfSDavid du Colombier b = (rgb>>0) & 0xFF;
60*80ee5cbfSDavid du Colombier sq = (r-cr)*(r-cr)+(g-cg)*(g-cg)+(b-cb)*(b-cb);
61*80ee5cbfSDavid du Colombier if(sq < bestsq){
62*80ee5cbfSDavid du Colombier bestsq = sq;
63*80ee5cbfSDavid du Colombier best = i;
64*80ee5cbfSDavid du Colombier }
65*80ee5cbfSDavid du Colombier }
66*80ee5cbfSDavid du Colombier return best;
67*80ee5cbfSDavid 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