]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libdraw/rgb.c
?a: getc() needs to increment lineno if it gets \n from peekc
[plan9front.git] / sys / src / libdraw / rgb.c
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         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 }