1 /*
2 * BestPixel() - Returns the best pixel
3 *
4 * RCS:
5 * $Revision$
6 * $Date$
7 *
8 * Security:
9 * Unclassified
10 *
11 * Description:
12 * This function returns the closest possible color rquested.
13 * It simply determines the closest point in the RGB space of the
14 * requested R, G, B values.
15 *
16 * Adapted from Imagemagick 3.0.0
17 *
18 * Input Parameters:
19 * type identifier description
20 *
21 * Display *display;
22 * Colormap colormap;
23 * XColor *colors;
24 * unsigned int number_colors;
25 * XColor *color;
26 *
27 * Output Parameters:
28 * type identifier description
29 *
30 * XColor *color;
31 *
32 * Return Values:
33 * value description
34 *
35 * Side Effects:
36 * text
37 *
38 * Limitations and Comments:
39 * text
40 *
41 * Development History:
42 * when who why
43 * 6/3/94 mm ????
44 */
45
46 #include "xhead.h"
47 #include "mxkill.h"
48
BestPixel(display,colormap,colors,number_colors,color)49 void BestPixel(display,colormap,colors,number_colors,color)
50 Display
51 *display;
52
53 Colormap
54 colormap;
55
56 XColor
57 *colors;
58
59 unsigned int
60 number_colors;
61
62 XColor
63 *color;
64 {
65 int
66 ii,
67 m_colors;
68
69 register int
70 blue_distance,
71 green_distance,
72 i,
73 red_distance;
74
75 unsigned long
76 distance,
77 min_distance;
78
79 m_colors = colors == (XColor *) NULL;
80
81 if (m_colors)
82 {
83 colors = (XColor *) malloc(number_colors*sizeof(XColor));
84 if (colors == (XColor *) NULL)
85 {
86 fprintf (stderr, "Failed to read X server colormap.\n");
87 goto ExitProcessing;
88 }
89
90 for (i=0; i < number_colors; i++)
91 {
92 colors[i].pixel = (unsigned long) i;
93 }
94
95 if (number_colors > 256)
96 {
97 number_colors = 256;
98 }
99
100 XQueryColors(display,colormap,colors,number_colors);
101 }
102
103 color->pixel=0;
104 min_distance=(unsigned long) (~0); /* just a big number */
105 ii=0;
106
107 for (i=0; i < number_colors; i++)
108 {
109 red_distance=(int) (colors[i].red >> 8)-(int) (color->red >> 8);
110 green_distance=(int) (colors[i].green >> 8)-(int) (color->green >> 8);
111 blue_distance=(int) (colors[i].blue >> 8)-(int) (color->blue >> 8);
112
113 /*
114 ** distance is distance, the co-ordinates values do not make any
115 ** diffetence, i.e., negative co-ordinate value will give the same
116 ** distance, because the points are squired. We do not care about
117 ** taking square root of the distance, because, we just need to find
118 ** the point closest to the requested point. distance is not important
119 */
120
121 distance=red_distance*red_distance+green_distance*green_distance+
122 blue_distance*blue_distance;
123
124 if (distance < min_distance)
125 {
126 min_distance=distance;
127 color->pixel=colors[i].pixel;
128 ii=i;
129 }
130 }
131
132 /*
133 ** this is the closest pixel. So, share it, allocate as Read only
134 */
135
136 (void) XAllocColor(display,colormap,&colors[ii]);
137 if (m_colors)
138 {
139 (void) free((char *) colors);
140 }
141
142 ExitProcessing:
143 return;
144 }
145