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