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