rsc | ed7c8e8 | 2003-09-30 17:47:42 +0000 | [diff] [blame] | 1 | #include <u.h> |
| 2 | #include <libc.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 | u32int 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 | } |