rgb.c (1678B)
1 #include "u.h" 2 #include "lib.h" 3 #include "draw.h" 4 5 /* 6 * This original version, although fast and a true inverse of 7 * cmap2rgb, in the sense that rgb2cmap(cmap2rgb(c)) 8 * returned the original color, does a terrible job for RGB 9 * triples that do not appear in the color map, so it has been 10 * replaced by the much slower version below, that loops 11 * over the color map looking for the nearest point in RGB 12 * space. There is no visual psychology reason for that 13 * criterion, but it's easy to implement and the results are 14 * far more pleasing. 15 * 16 int 17 rgb2cmap(int cr, int cg, int cb) 18 { 19 int r, g, b, v, cv; 20 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 */ 45 46 int 47 rgb2cmap(int cr, int cg, int cb) 48 { 49 int i, r, g, b, sq; 50 ulong rgb; 51 int best, bestsq; 52 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 } 68 69 int 70 cmap2rgb(int c) 71 { 72 int j, num, den, r, g, b, v, rgb; 73 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 } 94 95 int 96 cmap2rgba(int c) 97 { 98 return (cmap2rgb(c)<<8)|0xFF; 99 }