]> granicus.if.org Git - imagemagick/blob - magick/color.c
(no commit message)
[imagemagick] / magick / color.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                       CCCC   OOO   L       OOO   RRRR                       %
6 %                      C      O   O  L      O   O  R   R                      %
7 %                      C      O   O  L      O   O  RRRR                       %
8 %                      C      O   O  L      O   O  R R                        %
9 %                       CCCC   OOO   LLLLL   OOO   R  R                       %
10 %                                                                             %
11 %                                                                             %
12 %                          MagickCore Color Methods                           %
13 %                                                                             %
14 %                              Software Design                                %
15 %                                John Cristy                                  %
16 %                                 July 1992                                   %
17 %                                                                             %
18 %                                                                             %
19 %  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
20 %  dedicated to making software imaging solutions freely available.           %
21 %                                                                             %
22 %  You may not use this file except in compliance with the License.  You may  %
23 %  obtain a copy of the License at                                            %
24 %                                                                             %
25 %    http://www.imagemagick.org/script/license.php                            %
26 %                                                                             %
27 %  Unless required by applicable law or agreed to in writing, software        %
28 %  distributed under the License is distributed on an "AS IS" BASIS,          %
29 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
30 %  See the License for the specific language governing permissions and        %
31 %  limitations under the License.                                             %
32 %                                                                             %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 %  We use linked-lists because splay-trees do not currently support duplicate
36 %  key / value pairs (.e.g X11 green compliance and SVG green compliance).
37 %
38 */
39 \f
40 /*
41   Include declarations.
42 */
43 #include "magick/studio.h"
44 #include "magick/blob.h"
45 #include "magick/cache-view.h"
46 #include "magick/cache.h"
47 #include "magick/color.h"
48 #include "magick/color-private.h"
49 #include "magick/client.h"
50 #include "magick/configure.h"
51 #include "magick/exception.h"
52 #include "magick/exception-private.h"
53 #include "magick/gem.h"
54 #include "magick/geometry.h"
55 #include "magick/image-private.h"
56 #include "magick/memory_.h"
57 #include "magick/monitor.h"
58 #include "magick/monitor-private.h"
59 #include "magick/option.h"
60 #include "magick/pixel-private.h"
61 #include "magick/quantize.h"
62 #include "magick/quantum.h"
63 #include "magick/semaphore.h"
64 #include "magick/string_.h"
65 #include "magick/token.h"
66 #include "magick/utility.h"
67 #include "magick/xml-tree.h"
68 \f
69 /*
70   Define declarations.
71 */
72 #define ColorFilename  "colors.xml"
73 \f
74 /*
75   Static declarations.
76 */
77 typedef struct _ColorMapInfo
78 {
79   const char
80     *name;
81
82   const float
83     red,
84     green,
85     blue,
86     alpha;
87
88   const long
89     compliance;
90 } ColorMapInfo;
91
92 static const ColorMapInfo
93   ColorMap[] =
94   {
95     { "none", 0, 0, 0, 0, SVGCompliance },
96     { "black", 0, 0, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
97     { "red", 255, 0, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
98     { "magenta", 255, 0, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
99     { "green", 0, 128, 0, 1, SVGCompliance },
100     { "cyan", 0, 255, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
101     { "blue", 0, 0, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
102     { "yellow", 255, 255, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
103     { "white", 255, 255, 255, 1, SVGCompliance | X11Compliance },
104     { "AliceBlue", 240, 248, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
105     { "AntiqueWhite", 250, 235, 215, 1, SVGCompliance | X11Compliance | XPMCompliance },
106     { "AntiqueWhite1", 255, 239, 219, 1, X11Compliance },
107     { "AntiqueWhite2", 238, 223, 204, 1, X11Compliance },
108     { "AntiqueWhite3", 205, 192, 176, 1, X11Compliance },
109     { "AntiqueWhite4", 139, 131, 120, 1, X11Compliance },
110     { "aqua", 0, 255, 255, 1, SVGCompliance },
111     { "aquamarine", 127, 255, 212, 1, SVGCompliance | X11Compliance | XPMCompliance },
112     { "aquamarine1", 127, 255, 212, 1, X11Compliance },
113     { "aquamarine2", 118, 238, 198, 1, X11Compliance },
114     { "aquamarine3", 102, 205, 170, 1, X11Compliance },
115     { "aquamarine4", 69, 139, 116, 1, X11Compliance },
116     { "azure", 240, 255, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
117     { "azure1", 240, 255, 255, 1, X11Compliance },
118     { "azure2", 224, 238, 238, 1, X11Compliance },
119     { "azure3", 193, 205, 205, 1, X11Compliance },
120     { "azure4", 131, 139, 139, 1, X11Compliance },
121     { "beige", 245, 245, 220, 1, SVGCompliance | X11Compliance | XPMCompliance },
122     { "bisque", 255, 228, 196, 1, SVGCompliance | X11Compliance | XPMCompliance },
123     { "bisque1", 255, 228, 196, 1, X11Compliance },
124     { "bisque2", 238, 213, 183, 1, X11Compliance },
125     { "bisque3", 205, 183, 158, 1, X11Compliance },
126     { "bisque4", 139, 125, 107, 1, X11Compliance },
127     { "BlanchedAlmond", 255, 235, 205, 1, SVGCompliance | X11Compliance | XPMCompliance },
128     { "blue1", 0, 0, 255, 1, X11Compliance },
129     { "blue2", 0, 0, 238, 1, X11Compliance },
130     { "blue3", 0, 0, 205, 1, X11Compliance },
131     { "blue4", 0, 0, 139, 1, X11Compliance },
132     { "BlueViolet", 138, 43, 226, 1, SVGCompliance | X11Compliance | XPMCompliance },
133     { "brown", 165, 42, 42, 1, SVGCompliance | X11Compliance | XPMCompliance },
134     { "brown1", 255, 64, 64, 1, X11Compliance },
135     { "brown2", 238, 59, 59, 1, X11Compliance },
136     { "brown3", 205, 51, 51, 1, X11Compliance },
137     { "brown4", 139, 35, 35, 1, X11Compliance },
138     { "burlywood", 222, 184, 135, 1, SVGCompliance | X11Compliance | XPMCompliance },
139     { "burlywood1", 255, 211, 155, 1, X11Compliance },
140     { "burlywood2", 238, 197, 145, 1, X11Compliance },
141     { "burlywood3", 205, 170, 125, 1, X11Compliance },
142     { "burlywood4", 139, 115, 85, 1, X11Compliance },
143     { "cadet blue", 95, 158, 160, 1, X11Compliance },
144     { "CadetBlue", 95, 158, 160, 1, SVGCompliance | X11Compliance | XPMCompliance },
145     { "CadetBlue1", 152, 245, 255, 1, X11Compliance },
146     { "CadetBlue2", 142, 229, 238, 1, X11Compliance },
147     { "CadetBlue3", 122, 197, 205, 1, X11Compliance },
148     { "CadetBlue4", 83, 134, 139, 1, X11Compliance },
149     { "chartreuse", 127, 255, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
150     { "chartreuse1", 127, 255, 0, 1, X11Compliance },
151     { "chartreuse2", 118, 238, 0, 1, X11Compliance },
152     { "chartreuse3", 102, 205, 0, 1, X11Compliance },
153     { "chartreuse4", 69, 139, 0, 1, X11Compliance },
154     { "chocolate", 210, 105, 30, 1, SVGCompliance | X11Compliance | XPMCompliance },
155     { "chocolate1", 255, 127, 36, 1, X11Compliance },
156     { "chocolate2", 238, 118, 33, 1, X11Compliance },
157     { "chocolate3", 205, 102, 29, 1, X11Compliance },
158     { "chocolate4", 139, 69, 19, 1, X11Compliance },
159     { "coral", 255, 127, 80, 1, SVGCompliance | X11Compliance | XPMCompliance },
160     { "coral1", 255, 114, 86, 1, X11Compliance },
161     { "coral2", 238, 106, 80, 1, X11Compliance },
162     { "coral3", 205, 91, 69, 1, X11Compliance },
163     { "coral4", 139, 62, 47, 1, X11Compliance },
164     { "CornflowerBlue", 100, 149, 237, 1, SVGCompliance | X11Compliance | XPMCompliance },
165     { "cornsilk", 255, 248, 220, 1, SVGCompliance | X11Compliance | XPMCompliance },
166     { "cornsilk1", 255, 248, 220, 1, X11Compliance },
167     { "cornsilk2", 238, 232, 205, 1, X11Compliance },
168     { "cornsilk3", 205, 200, 177, 1, X11Compliance },
169     { "cornsilk4", 139, 136, 120, 1, X11Compliance },
170     { "crimson", 220, 20, 60, 1, SVGCompliance },
171     { "cyan1", 0, 255, 255, 1, X11Compliance },
172     { "cyan2", 0, 238, 238, 1, X11Compliance },
173     { "cyan3", 0, 205, 205, 1, X11Compliance },
174     { "cyan4", 0, 139, 139, 1, X11Compliance },
175     { "dark violet", 148, 0, 211, 1, X11Compliance },
176     { "DarkBlue", 0, 0, 139, 1, SVGCompliance | X11Compliance },
177     { "DarkCyan", 0, 139, 139, 1, SVGCompliance | X11Compliance },
178     { "DarkGoldenrod", 184, 134, 11, 1, SVGCompliance | X11Compliance | XPMCompliance },
179     { "DarkGoldenrod1", 255, 185, 15, 1, X11Compliance },
180     { "DarkGoldenrod2", 238, 173, 14, 1, X11Compliance },
181     { "DarkGoldenrod3", 205, 149, 12, 1, X11Compliance },
182     { "DarkGoldenrod4", 139, 101, 8, 1, X11Compliance },
183     { "DarkGray", 169, 169, 169, 1, SVGCompliance | X11Compliance },
184     { "DarkGreen", 0, 100, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
185     { "DarkGrey", 169, 169, 169, 1, SVGCompliance | X11Compliance },
186     { "DarkKhaki", 189, 183, 107, 1, SVGCompliance | X11Compliance | XPMCompliance },
187     { "DarkMagenta", 139, 0, 139, 1, SVGCompliance | X11Compliance },
188     { "DarkOliveGreen", 85, 107, 47, 1, SVGCompliance | X11Compliance | XPMCompliance },
189     { "DarkOliveGreen1", 202, 255, 112, 1, X11Compliance },
190     { "DarkOliveGreen2", 188, 238, 104, 1, X11Compliance },
191     { "DarkOliveGreen3", 162, 205, 90, 1, X11Compliance },
192     { "DarkOliveGreen4", 110, 139, 61, 1, X11Compliance },
193     { "DarkOrange", 255, 140, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
194     { "DarkOrange1", 255, 127, 0, 1, X11Compliance },
195     { "DarkOrange2", 238, 118, 0, 1, X11Compliance },
196     { "DarkOrange3", 205, 102, 0, 1, X11Compliance },
197     { "DarkOrange4", 139, 69, 0, 1, X11Compliance },
198     { "DarkOrchid", 153, 50, 204, 1, SVGCompliance | X11Compliance | XPMCompliance },
199     { "DarkOrchid1", 191, 62, 255, 1, X11Compliance },
200     { "DarkOrchid2", 178, 58, 238, 1, X11Compliance },
201     { "DarkOrchid3", 154, 50, 205, 1, X11Compliance },
202     { "DarkOrchid4", 104, 34, 139, 1, X11Compliance },
203     { "DarkRed", 139, 0, 0, 1, SVGCompliance | X11Compliance },
204     { "DarkSalmon", 233, 150, 122, 1, SVGCompliance | X11Compliance | XPMCompliance },
205     { "DarkSeaGreen", 143, 188, 143, 1, SVGCompliance | X11Compliance | XPMCompliance },
206     { "DarkSeaGreen1", 193, 255, 193, 1, X11Compliance },
207     { "DarkSeaGreen2", 180, 238, 180, 1, X11Compliance },
208     { "DarkSeaGreen3", 155, 205, 155, 1, X11Compliance },
209     { "DarkSeaGreen4", 105, 139, 105, 1, X11Compliance },
210     { "DarkSlateBlue", 72, 61, 139, 1, SVGCompliance | X11Compliance | XPMCompliance },
211     { "DarkSlateGray", 47, 79, 79, 1, SVGCompliance | X11Compliance | XPMCompliance },
212     { "DarkSlateGray1", 151, 255, 255, 1, X11Compliance },
213     { "DarkSlateGray2", 141, 238, 238, 1, X11Compliance },
214     { "DarkSlateGray3", 121, 205, 205, 1, X11Compliance },
215     { "DarkSlateGray4", 82, 139, 139, 1, X11Compliance },
216     { "DarkSlateGrey", 47, 79, 79, 1, SVGCompliance | X11Compliance },
217     { "DarkTurquoise", 0, 206, 209, 1, SVGCompliance | X11Compliance | XPMCompliance },
218     { "DarkViolet", 148, 0, 211, 1, SVGCompliance | X11Compliance | XPMCompliance },
219     { "DeepPink", 255, 20, 147, 1, SVGCompliance | X11Compliance | XPMCompliance },
220     { "DeepPink1", 255, 20, 147, 1, X11Compliance },
221     { "DeepPink2", 238, 18, 137, 1, X11Compliance },
222     { "DeepPink3", 205, 16, 118, 1, X11Compliance },
223     { "DeepPink4", 139, 10, 80, 1, X11Compliance },
224     { "DeepSkyBlue", 0, 191, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
225     { "DeepSkyBlue1", 0, 191, 255, 1, X11Compliance },
226     { "DeepSkyBlue2", 0, 178, 238, 1, X11Compliance },
227     { "DeepSkyBlue3", 0, 154, 205, 1, X11Compliance },
228     { "DeepSkyBlue4", 0, 104, 139, 1, X11Compliance },
229     { "DimGray", 105, 105, 105, 1, SVGCompliance | X11Compliance | XPMCompliance },
230     { "DimGrey", 105, 105, 105, 1, SVGCompliance | X11Compliance },
231     { "DodgerBlue", 30, 144, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
232     { "DodgerBlue1", 30, 144, 255, 1, X11Compliance },
233     { "DodgerBlue2", 28, 134, 238, 1, X11Compliance },
234     { "DodgerBlue3", 24, 116, 205, 1, X11Compliance },
235     { "DodgerBlue4", 16, 78, 139, 1, X11Compliance },
236     { "firebrick", 178, 34, 34, 1, SVGCompliance | X11Compliance | XPMCompliance },
237     { "firebrick1", 255, 48, 48, 1, X11Compliance },
238     { "firebrick2", 238, 44, 44, 1, X11Compliance },
239     { "firebrick3", 205, 38, 38, 1, X11Compliance },
240     { "firebrick4", 139, 26, 26, 1, X11Compliance },
241     { "FloralWhite", 255, 250, 240, 1, SVGCompliance | X11Compliance | XPMCompliance },
242     { "ForestGreen", 34, 139, 34, 1, SVGCompliance | X11Compliance | XPMCompliance },
243     { "fractal", 128, 128, 128, 1, SVGCompliance },
244     { "freeze", 0, 0, 0, 0, SVGCompliance },
245     { "fuchsia", 255, 0, 255, 1, SVGCompliance },
246     { "gainsboro", 220, 220, 220, 1, SVGCompliance | X11Compliance | XPMCompliance },
247     { "GhostWhite", 248, 248, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
248     { "gold", 255, 215, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
249     { "gold1", 255, 215, 0, 1, X11Compliance },
250     { "gold2", 238, 201, 0, 1, X11Compliance },
251     { "gold3", 205, 173, 0, 1, X11Compliance },
252     { "gold4", 139, 117, 0, 1, X11Compliance },
253     { "goldenrod", 218, 165, 32, 1, SVGCompliance | X11Compliance | XPMCompliance },
254     { "goldenrod1", 255, 193, 37, 1, X11Compliance },
255     { "goldenrod2", 238, 180, 34, 1, X11Compliance },
256     { "goldenrod3", 205, 155, 29, 1, X11Compliance },
257     { "goldenrod4", 139, 105, 20, 1, X11Compliance },
258     { "gray", 126, 126, 126, 1, SVGCompliance },
259     { "gray", 190, 190, 190, 1, X11Compliance | XPMCompliance },
260     { "gray0", 0, 0, 0, 1, X11Compliance | XPMCompliance },
261     { "gray1", 3, 3, 3, 1, X11Compliance | XPMCompliance },
262     { "gray10", 26, 26, 26, 1, X11Compliance | XPMCompliance },
263     { "gray100", 255, 255, 255, 1, X11Compliance | XPMCompliance },
264     { "gray100", 255, 255, 255, 1, X11Compliance | XPMCompliance },
265     { "gray11", 28, 28, 28, 1, X11Compliance | XPMCompliance },
266     { "gray12", 31, 31, 31, 1, X11Compliance | XPMCompliance },
267     { "gray13", 33, 33, 33, 1, X11Compliance | XPMCompliance },
268     { "gray14", 36, 36, 36, 1, X11Compliance | XPMCompliance },
269     { "gray15", 38, 38, 38, 1, X11Compliance | XPMCompliance },
270     { "gray16", 41, 41, 41, 1, X11Compliance | XPMCompliance },
271     { "gray17", 43, 43, 43, 1, X11Compliance | XPMCompliance },
272     { "gray18", 46, 46, 46, 1, X11Compliance | XPMCompliance },
273     { "gray19", 48, 48, 48, 1, X11Compliance | XPMCompliance },
274     { "gray2", 5, 5, 5, 1, X11Compliance | XPMCompliance },
275     { "gray20", 51, 51, 51, 1, X11Compliance | XPMCompliance },
276     { "gray21", 54, 54, 54, 1, X11Compliance | XPMCompliance },
277     { "gray22", 56, 56, 56, 1, X11Compliance | XPMCompliance },
278     { "gray23", 59, 59, 59, 1, X11Compliance | XPMCompliance },
279     { "gray24", 61, 61, 61, 1, X11Compliance | XPMCompliance },
280     { "gray25", 64, 64, 64, 1, X11Compliance | XPMCompliance },
281     { "gray26", 66, 66, 66, 1, X11Compliance | XPMCompliance },
282     { "gray27", 69, 69, 69, 1, X11Compliance | XPMCompliance },
283     { "gray28", 71, 71, 71, 1, X11Compliance | XPMCompliance },
284     { "gray29", 74, 74, 74, 1, X11Compliance | XPMCompliance },
285     { "gray3", 8, 8, 8, 1, X11Compliance | XPMCompliance },
286     { "gray30", 77, 77, 77, 1, X11Compliance | XPMCompliance },
287     { "gray31", 79, 79, 79, 1, X11Compliance | XPMCompliance },
288     { "gray32", 82, 82, 82, 1, X11Compliance | XPMCompliance },
289     { "gray33", 84, 84, 84, 1, X11Compliance | XPMCompliance },
290     { "gray34", 87, 87, 87, 1, X11Compliance | XPMCompliance },
291     { "gray35", 89, 89, 89, 1, X11Compliance | XPMCompliance },
292     { "gray36", 92, 92, 92, 1, X11Compliance | XPMCompliance },
293     { "gray37", 94, 94, 94, 1, X11Compliance | XPMCompliance },
294     { "gray38", 97, 97, 97, 1, X11Compliance | XPMCompliance },
295     { "gray39", 99, 99, 99, 1, X11Compliance | XPMCompliance },
296     { "gray4", 10, 10, 10, 1, X11Compliance | XPMCompliance },
297     { "gray40", 102, 102, 102, 1, X11Compliance | XPMCompliance },
298     { "gray41", 105, 105, 105, 1, X11Compliance | XPMCompliance },
299     { "gray42", 107, 107, 107, 1, X11Compliance | XPMCompliance },
300     { "gray43", 110, 110, 110, 1, X11Compliance | XPMCompliance },
301     { "gray44", 112, 112, 112, 1, X11Compliance | XPMCompliance },
302     { "gray45", 115, 115, 115, 1, X11Compliance | XPMCompliance },
303     { "gray46", 117, 117, 117, 1, X11Compliance | XPMCompliance },
304     { "gray47", 120, 120, 120, 1, X11Compliance | XPMCompliance },
305     { "gray48", 122, 122, 122, 1, X11Compliance | XPMCompliance },
306     { "gray49", 125, 125, 125, 1, X11Compliance | XPMCompliance },
307     { "gray5", 13, 13, 13, 1, X11Compliance | XPMCompliance },
308     { "gray50", 127.5, 127.5, 127.5, 1, X11Compliance | XPMCompliance },
309     { "gray51", 130, 130, 130, 1, X11Compliance | XPMCompliance },
310     { "gray52", 133, 133, 133, 1, X11Compliance | XPMCompliance },
311     { "gray53", 135, 135, 135, 1, X11Compliance | XPMCompliance },
312     { "gray54", 138, 138, 138, 1, X11Compliance | XPMCompliance },
313     { "gray55", 140, 140, 140, 1, X11Compliance | XPMCompliance },
314     { "gray56", 143, 143, 143, 1, X11Compliance | XPMCompliance },
315     { "gray57", 145, 145, 145, 1, X11Compliance | XPMCompliance },
316     { "gray58", 148, 148, 148, 1, X11Compliance | XPMCompliance },
317     { "gray59", 150, 150, 150, 1, X11Compliance | XPMCompliance },
318     { "gray6", 15, 15, 15, 1, X11Compliance | XPMCompliance },
319     { "gray60", 153, 153, 153, 1, X11Compliance | XPMCompliance },
320     { "gray61", 156, 156, 156, 1, X11Compliance | XPMCompliance },
321     { "gray62", 158, 158, 158, 1, X11Compliance | XPMCompliance },
322     { "gray63", 161, 161, 161, 1, X11Compliance | XPMCompliance },
323     { "gray64", 163, 163, 163, 1, X11Compliance | XPMCompliance },
324     { "gray65", 166, 166, 166, 1, X11Compliance | XPMCompliance },
325     { "gray66", 168, 168, 168, 1, X11Compliance | XPMCompliance },
326     { "gray67", 171, 171, 171, 1, X11Compliance | XPMCompliance },
327     { "gray68", 173, 173, 173, 1, X11Compliance | XPMCompliance },
328     { "gray69", 176, 176, 176, 1, X11Compliance | XPMCompliance },
329     { "gray7", 18, 18, 18, 1, X11Compliance | XPMCompliance },
330     { "gray70", 179, 179, 179, 1, X11Compliance | XPMCompliance },
331     { "gray71", 181, 181, 181, 1, X11Compliance | XPMCompliance },
332     { "gray72", 184, 184, 184, 1, X11Compliance | XPMCompliance },
333     { "gray73", 186, 186, 186, 1, X11Compliance | XPMCompliance },
334     { "gray74", 189, 189, 189, 1, X11Compliance | XPMCompliance },
335     { "gray75", 191, 191, 191, 1, X11Compliance | XPMCompliance },
336     { "gray76", 194, 194, 194, 1, X11Compliance | XPMCompliance },
337     { "gray77", 196, 196, 196, 1, X11Compliance | XPMCompliance },
338     { "gray78", 199, 199, 199, 1, X11Compliance | XPMCompliance },
339     { "gray79", 201, 201, 201, 1, X11Compliance | XPMCompliance },
340     { "gray8", 20, 20, 20, 1, X11Compliance | XPMCompliance },
341     { "gray80", 204, 204, 204, 1, X11Compliance | XPMCompliance },
342     { "gray81", 207, 207, 207, 1, X11Compliance | XPMCompliance },
343     { "gray82", 209, 209, 209, 1, X11Compliance | XPMCompliance },
344     { "gray83", 212, 212, 212, 1, X11Compliance | XPMCompliance },
345     { "gray84", 214, 214, 214, 1, X11Compliance | XPMCompliance },
346     { "gray85", 217, 217, 217, 1, X11Compliance | XPMCompliance },
347     { "gray86", 219, 219, 219, 1, X11Compliance | XPMCompliance },
348     { "gray87", 222, 222, 222, 1, X11Compliance | XPMCompliance },
349     { "gray88", 224, 224, 224, 1, X11Compliance | XPMCompliance },
350     { "gray89", 227, 227, 227, 1, X11Compliance | XPMCompliance },
351     { "gray9", 23, 23, 23, 1, X11Compliance | XPMCompliance },
352     { "gray90", 229, 229, 229, 1, X11Compliance | XPMCompliance },
353     { "gray91", 232, 232, 232, 1, X11Compliance | XPMCompliance },
354     { "gray92", 235, 235, 235, 1, X11Compliance | XPMCompliance },
355     { "gray93", 237, 237, 237, 1, X11Compliance | XPMCompliance },
356     { "gray94", 240, 240, 240, 1, X11Compliance | XPMCompliance },
357     { "gray95", 242, 242, 242, 1, X11Compliance | XPMCompliance },
358     { "gray96", 245, 245, 245, 1, X11Compliance | XPMCompliance },
359     { "gray97", 247, 247, 247, 1, X11Compliance | XPMCompliance },
360     { "gray98", 250, 250, 250, 1, X11Compliance | XPMCompliance },
361     { "gray99", 252, 252, 252, 1, X11Compliance | XPMCompliance },
362     { "green", 0, 255, 0, 1, X11Compliance | XPMCompliance },
363     { "green1", 0, 255, 0, 1, X11Compliance },
364     { "green2", 0, 238, 0, 1, X11Compliance },
365     { "green3", 0, 205, 0, 1, X11Compliance },
366     { "green4", 0, 139, 0, 1, X11Compliance },
367     { "GreenYellow", 173, 255, 47, 1, X11Compliance | XPMCompliance },
368     { "grey", 190, 190, 190, 1, SVGCompliance | X11Compliance },
369     { "grey0", 0, 0, 0, 1, SVGCompliance | X11Compliance },
370     { "grey1", 3, 3, 3, 1, SVGCompliance | X11Compliance },
371     { "grey10", 26, 26, 26, 1, SVGCompliance | X11Compliance },
372     { "grey100", 255, 255, 255, 1, SVGCompliance | X11Compliance },
373     { "grey11", 28, 28, 28, 1, SVGCompliance | X11Compliance },
374     { "grey12", 31, 31, 31, 1, SVGCompliance | X11Compliance },
375     { "grey13", 33, 33, 33, 1, SVGCompliance | X11Compliance },
376     { "grey14", 36, 36, 36, 1, SVGCompliance | X11Compliance },
377     { "grey15", 38, 38, 38, 1, SVGCompliance | X11Compliance },
378     { "grey16", 41, 41, 41, 1, SVGCompliance | X11Compliance },
379     { "grey17", 43, 43, 43, 1, SVGCompliance | X11Compliance },
380     { "grey18", 46, 46, 46, 1, SVGCompliance | X11Compliance },
381     { "grey19", 48, 48, 48, 1, SVGCompliance | X11Compliance },
382     { "grey2", 5, 5, 5, 1, SVGCompliance | X11Compliance },
383     { "grey20", 51, 51, 51, 1, SVGCompliance | X11Compliance },
384     { "grey21", 54, 54, 54, 1, SVGCompliance | X11Compliance },
385     { "grey22", 56, 56, 56, 1, SVGCompliance | X11Compliance },
386     { "grey23", 59, 59, 59, 1, SVGCompliance | X11Compliance },
387     { "grey24", 61, 61, 61, 1, SVGCompliance | X11Compliance },
388     { "grey25", 64, 64, 64, 1, SVGCompliance | X11Compliance },
389     { "grey26", 66, 66, 66, 1, SVGCompliance | X11Compliance },
390     { "grey27", 69, 69, 69, 1, SVGCompliance | X11Compliance },
391     { "grey28", 71, 71, 71, 1, SVGCompliance | X11Compliance },
392     { "grey29", 74, 74, 74, 1, SVGCompliance | X11Compliance },
393     { "grey3", 8, 8, 8, 1, SVGCompliance | X11Compliance },
394     { "grey30", 77, 77, 77, 1, SVGCompliance | X11Compliance },
395     { "grey31", 79, 79, 79, 1, SVGCompliance | X11Compliance },
396     { "grey32", 82, 82, 82, 1, SVGCompliance | X11Compliance },
397     { "grey33", 84, 84, 84, 1, SVGCompliance | X11Compliance },
398     { "grey34", 87, 87, 87, 1, SVGCompliance | X11Compliance },
399     { "grey35", 89, 89, 89, 1, SVGCompliance | X11Compliance },
400     { "grey36", 92, 92, 92, 1, SVGCompliance | X11Compliance },
401     { "grey37", 94, 94, 94, 1, SVGCompliance | X11Compliance },
402     { "grey38", 97, 97, 97, 1, SVGCompliance | X11Compliance },
403     { "grey39", 99, 99, 99, 1, SVGCompliance | X11Compliance },
404     { "grey4", 10, 10, 10, 1, SVGCompliance | X11Compliance },
405     { "grey40", 102, 102, 102, 1, SVGCompliance | X11Compliance },
406     { "grey41", 105, 105, 105, 1, SVGCompliance | X11Compliance },
407     { "grey42", 107, 107, 107, 1, SVGCompliance | X11Compliance },
408     { "grey43", 110, 110, 110, 1, SVGCompliance | X11Compliance },
409     { "grey44", 112, 112, 112, 1, SVGCompliance | X11Compliance },
410     { "grey45", 115, 115, 115, 1, SVGCompliance | X11Compliance },
411     { "grey46", 117, 117, 117, 1, SVGCompliance | X11Compliance },
412     { "grey47", 120, 120, 120, 1, SVGCompliance | X11Compliance },
413     { "grey48", 122, 122, 122, 1, SVGCompliance | X11Compliance },
414     { "grey49", 125, 125, 125, 1, SVGCompliance | X11Compliance },
415     { "grey5", 13, 13, 13, 1, SVGCompliance | X11Compliance },
416     { "grey50", 127, 127, 127, 1, SVGCompliance | X11Compliance },
417     { "grey51", 130, 130, 130, 1, SVGCompliance | X11Compliance },
418     { "grey52", 133, 133, 133, 1, SVGCompliance | X11Compliance },
419     { "grey53", 135, 135, 135, 1, SVGCompliance | X11Compliance },
420     { "grey54", 138, 138, 138, 1, SVGCompliance | X11Compliance },
421     { "grey55", 140, 140, 140, 1, SVGCompliance | X11Compliance },
422     { "grey56", 143, 143, 143, 1, SVGCompliance | X11Compliance },
423     { "grey57", 145, 145, 145, 1, SVGCompliance | X11Compliance },
424     { "grey58", 148, 148, 148, 1, SVGCompliance | X11Compliance },
425     { "grey59", 150, 150, 150, 1, SVGCompliance | X11Compliance },
426     { "grey6", 15, 15, 15, 1, SVGCompliance | X11Compliance },
427     { "grey60", 153, 153, 153, 1, SVGCompliance | X11Compliance },
428     { "grey61", 156, 156, 156, 1, SVGCompliance | X11Compliance },
429     { "grey62", 158, 158, 158, 1, SVGCompliance | X11Compliance },
430     { "grey63", 161, 161, 161, 1, SVGCompliance | X11Compliance },
431     { "grey64", 163, 163, 163, 1, SVGCompliance | X11Compliance },
432     { "grey65", 166, 166, 166, 1, SVGCompliance | X11Compliance },
433     { "grey66", 168, 168, 168, 1, SVGCompliance | X11Compliance },
434     { "grey67", 171, 171, 171, 1, SVGCompliance | X11Compliance },
435     { "grey68", 173, 173, 173, 1, SVGCompliance | X11Compliance },
436     { "grey69", 176, 176, 176, 1, SVGCompliance | X11Compliance },
437     { "grey7", 18, 18, 18, 1, SVGCompliance | X11Compliance },
438     { "grey70", 179, 179, 179, 1, SVGCompliance | X11Compliance },
439     { "grey71", 181, 181, 181, 1, SVGCompliance | X11Compliance },
440     { "grey72", 184, 184, 184, 1, SVGCompliance | X11Compliance },
441     { "grey73", 186, 186, 186, 1, SVGCompliance | X11Compliance },
442     { "grey74", 189, 189, 189, 1, SVGCompliance | X11Compliance },
443     { "grey75", 191, 191, 191, 1, SVGCompliance | X11Compliance },
444     { "grey76", 194, 194, 194, 1, SVGCompliance | X11Compliance },
445     { "grey77", 196, 196, 196, 1, SVGCompliance | X11Compliance },
446     { "grey78", 199, 199, 199, 1, SVGCompliance | X11Compliance },
447     { "grey79", 201, 201, 201, 1, SVGCompliance | X11Compliance },
448     { "grey8", 20, 20, 20, 1, SVGCompliance | X11Compliance },
449     { "grey80", 204, 204, 204, 1, SVGCompliance | X11Compliance },
450     { "grey81", 207, 207, 207, 1, SVGCompliance | X11Compliance },
451     { "grey82", 209, 209, 209, 1, SVGCompliance | X11Compliance },
452     { "grey83", 212, 212, 212, 1, SVGCompliance | X11Compliance },
453     { "grey84", 214, 214, 214, 1, SVGCompliance | X11Compliance },
454     { "grey85", 217, 217, 217, 1, SVGCompliance | X11Compliance },
455     { "grey86", 219, 219, 219, 1, SVGCompliance | X11Compliance },
456     { "grey87", 222, 222, 222, 1, SVGCompliance | X11Compliance },
457     { "grey88", 224, 224, 224, 1, SVGCompliance | X11Compliance },
458     { "grey89", 227, 227, 227, 1, SVGCompliance | X11Compliance },
459     { "grey9", 23, 23, 23, 1, SVGCompliance | X11Compliance },
460     { "grey90", 229, 229, 229, 1, SVGCompliance | X11Compliance },
461     { "grey91", 232, 232, 232, 1, SVGCompliance | X11Compliance },
462     { "grey92", 235, 235, 235, 1, SVGCompliance | X11Compliance },
463     { "grey93", 237, 237, 237, 1, SVGCompliance | X11Compliance },
464     { "grey94", 240, 240, 240, 1, SVGCompliance | X11Compliance },
465     { "grey95", 242, 242, 242, 1, SVGCompliance | X11Compliance },
466     { "grey96", 245, 245, 245, 1, SVGCompliance | X11Compliance },
467     { "grey97", 247, 247, 247, 1, SVGCompliance | X11Compliance },
468     { "grey98", 250, 250, 250, 1, SVGCompliance | X11Compliance },
469     { "grey99", 252, 252, 252, 1, SVGCompliance | X11Compliance },
470     { "honeydew", 240, 255, 240, 1, SVGCompliance | X11Compliance | XPMCompliance },
471     { "honeydew1", 240, 255, 240, 1, X11Compliance },
472     { "honeydew2", 224, 238, 224, 1, X11Compliance },
473     { "honeydew3", 193, 205, 193, 1, X11Compliance },
474     { "honeydew4", 131, 139, 131, 1, X11Compliance },
475     { "HotPink", 255, 105, 180, 1, SVGCompliance | X11Compliance | XPMCompliance },
476     { "HotPink1", 255, 110, 180, 1, X11Compliance },
477     { "HotPink2", 238, 106, 167, 1, X11Compliance },
478     { "HotPink3", 205, 96, 144, 1, X11Compliance },
479     { "HotPink4", 139, 58, 98, 1, X11Compliance },
480     { "IndianRed", 205, 92, 92, 1, SVGCompliance | X11Compliance | XPMCompliance },
481     { "IndianRed1", 255, 106, 106, 1, X11Compliance },
482     { "IndianRed2", 238, 99, 99, 1, X11Compliance },
483     { "IndianRed3", 205, 85, 85, 1, X11Compliance },
484     { "IndianRed4", 139, 58, 58, 1, X11Compliance },
485     { "indigo", 75, 0, 130, 1, SVGCompliance },
486     { "ivory", 255, 255, 240, 1, SVGCompliance | X11Compliance | XPMCompliance },
487     { "ivory1", 255, 255, 240, 1, X11Compliance },
488     { "ivory2", 238, 238, 224, 1, X11Compliance },
489     { "ivory3", 205, 205, 193, 1, X11Compliance },
490     { "ivory4", 139, 139, 131, 1, X11Compliance },
491     { "khaki", 240, 230, 140, 1, SVGCompliance | X11Compliance | XPMCompliance },
492     { "khaki1", 255, 246, 143, 1, X11Compliance },
493     { "khaki2", 238, 230, 133, 1, X11Compliance },
494     { "khaki3", 205, 198, 115, 1, X11Compliance },
495     { "khaki4", 139, 134, 78, 1, X11Compliance },
496     { "lavender", 230, 230, 250, 1, SVGCompliance | X11Compliance | XPMCompliance },
497     { "LavenderBlush", 255, 240, 245, 1, SVGCompliance | X11Compliance | XPMCompliance },
498     { "LavenderBlush1", 255, 240, 245, 1, X11Compliance },
499     { "LavenderBlush2", 238, 224, 229, 1, X11Compliance },
500     { "LavenderBlush3", 205, 193, 197, 1, X11Compliance },
501     { "LavenderBlush4", 139, 131, 134, 1, X11Compliance },
502     { "LawnGreen", 124, 252, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
503     { "LemonChiffon", 255, 250, 205, 1, SVGCompliance | X11Compliance | XPMCompliance },
504     { "LemonChiffon1", 255, 250, 205, 1, X11Compliance },
505     { "LemonChiffon2", 238, 233, 191, 1, X11Compliance },
506     { "LemonChiffon3", 205, 201, 165, 1, X11Compliance },
507     { "LemonChiffon4", 139, 137, 112, 1, X11Compliance },
508     { "LightBlue", 173, 216, 230, 1, SVGCompliance | X11Compliance | XPMCompliance },
509     { "LightBlue1", 191, 239, 255, 1, X11Compliance },
510     { "LightBlue2", 178, 223, 238, 1, X11Compliance },
511     { "LightBlue3", 154, 192, 205, 1, X11Compliance },
512     { "LightBlue4", 104, 131, 139, 1, X11Compliance },
513     { "LightCoral", 240, 128, 128, 1, SVGCompliance | X11Compliance | XPMCompliance },
514     { "LightCyan", 224, 255, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
515     { "LightCyan1", 224, 255, 255, 1, X11Compliance },
516     { "LightCyan2", 209, 238, 238, 1, X11Compliance },
517     { "LightCyan3", 180, 205, 205, 1, X11Compliance },
518     { "LightCyan4", 122, 139, 139, 1, X11Compliance },
519     { "LightGoldenrod", 238, 221, 130, 1, X11Compliance | XPMCompliance },
520     { "LightGoldenrod1", 255, 236, 139, 1, X11Compliance },
521     { "LightGoldenrod2", 238, 220, 130, 1, X11Compliance },
522     { "LightGoldenrod3", 205, 190, 112, 1, X11Compliance },
523     { "LightGoldenrod4", 139, 129, 76, 1, X11Compliance },
524     { "LightGoldenrodYellow", 250, 250, 210, 1, SVGCompliance | X11Compliance | XPMCompliance },
525     { "LightGray", 211, 211, 211, 1, SVGCompliance | X11Compliance | XPMCompliance },
526     { "LightGreen", 144, 238, 144, 1, SVGCompliance | X11Compliance },
527     { "LightGrey", 211, 211, 211, 1, SVGCompliance | X11Compliance },
528     { "LightPink", 255, 182, 193, 1, SVGCompliance | X11Compliance | XPMCompliance },
529     { "LightPink1", 255, 174, 185, 1, X11Compliance },
530     { "LightPink2", 238, 162, 173, 1, X11Compliance },
531     { "LightPink3", 205, 140, 149, 1, X11Compliance },
532     { "LightPink4", 139, 95, 101, 1, X11Compliance },
533     { "LightSalmon", 255, 160, 122, 1, SVGCompliance | X11Compliance | XPMCompliance },
534     { "LightSalmon1", 255, 160, 122, 1, X11Compliance },
535     { "LightSalmon2", 238, 149, 114, 1, X11Compliance },
536     { "LightSalmon3", 205, 129, 98, 1, X11Compliance },
537     { "LightSalmon4", 139, 87, 66, 1, X11Compliance },
538     { "LightSeaGreen", 32, 178, 170, 1, SVGCompliance | X11Compliance | XPMCompliance },
539     { "LightSkyBlue", 135, 206, 250, 1, SVGCompliance | X11Compliance | XPMCompliance },
540     { "LightSkyBlue1", 176, 226, 255, 1, X11Compliance },
541     { "LightSkyBlue2", 164, 211, 238, 1, X11Compliance },
542     { "LightSkyBlue3", 141, 182, 205, 1, X11Compliance },
543     { "LightSkyBlue4", 96, 123, 139, 1, X11Compliance },
544     { "LightSlateBlue", 132, 112, 255, 1, X11Compliance | XPMCompliance },
545     { "LightSlateGray", 119, 136, 153, 1, SVGCompliance | X11Compliance | XPMCompliance },
546     { "LightSlateGrey", 119, 136, 153, 1, SVGCompliance | X11Compliance },
547     { "LightSteelBlue", 176, 196, 222, 1, SVGCompliance | X11Compliance | XPMCompliance },
548     { "LightSteelBlue1", 202, 225, 255, 1, X11Compliance },
549     { "LightSteelBlue2", 188, 210, 238, 1, X11Compliance },
550     { "LightSteelBlue3", 162, 181, 205, 1, X11Compliance },
551     { "LightSteelBlue4", 110, 123, 139, 1, X11Compliance },
552     { "LightYellow", 255, 255, 224, 1, SVGCompliance | X11Compliance | XPMCompliance },
553     { "LightYellow1", 255, 255, 224, 1, X11Compliance },
554     { "LightYellow2", 238, 238, 209, 1, X11Compliance },
555     { "LightYellow3", 205, 205, 180, 1, X11Compliance },
556     { "LightYellow4", 139, 139, 122, 1, X11Compliance },
557     { "lime", 0, 255, 0, 1, SVGCompliance },
558     { "LimeGreen", 50, 205, 50, 1, SVGCompliance | X11Compliance | XPMCompliance },
559     { "linen", 250, 240, 230, 1, SVGCompliance | X11Compliance | XPMCompliance },
560     { "magenta1", 255, 0, 255, 1, X11Compliance },
561     { "magenta2", 238, 0, 238, 1, X11Compliance },
562     { "magenta3", 205, 0, 205, 1, X11Compliance },
563     { "magenta4", 139, 0, 139, 1, X11Compliance },
564     { "maroon", 128, 0, 0, 1, SVGCompliance },
565     { "maroon", 176, 48, 96, 1, X11Compliance | XPMCompliance },
566     { "maroon1", 255, 52, 179, 1, X11Compliance },
567     { "maroon2", 238, 48, 167, 1, X11Compliance },
568     { "maroon3", 205, 41, 144, 1, X11Compliance },
569     { "maroon4", 139, 28, 98, 1, X11Compliance },
570     { "MediumAquamarine", 102, 205, 170, 1, SVGCompliance | X11Compliance | XPMCompliance },
571     { "MediumBlue", 0, 0, 205, 1, SVGCompliance | X11Compliance | XPMCompliance },
572     { "MediumForestGreen", 50, 129, 75, 1, X11Compliance | XPMCompliance },
573     { "MediumGoldenRod", 209, 193, 102, 1, X11Compliance | XPMCompliance },
574     { "MediumOrchid", 186, 85, 211, 1, SVGCompliance | X11Compliance | XPMCompliance },
575     { "MediumOrchid1", 224, 102, 255, 1, X11Compliance },
576     { "MediumOrchid2", 209, 95, 238, 1, X11Compliance },
577     { "MediumOrchid3", 180, 82, 205, 1, X11Compliance },
578     { "MediumOrchid4", 122, 55, 139, 1, X11Compliance },
579     { "MediumPurple", 147, 112, 219, 1, SVGCompliance | X11Compliance | XPMCompliance },
580     { "MediumPurple1", 171, 130, 255, 1, X11Compliance },
581     { "MediumPurple2", 159, 121, 238, 1, X11Compliance },
582     { "MediumPurple3", 137, 104, 205, 1, X11Compliance },
583     { "MediumPurple4", 93, 71, 139, 1, X11Compliance },
584     { "MediumSeaGreen", 60, 179, 113, 1, SVGCompliance | X11Compliance | XPMCompliance },
585     { "MediumSlateBlue", 123, 104, 238, 1, SVGCompliance | X11Compliance | XPMCompliance },
586     { "MediumSpringGreen", 0, 250, 154, 1, SVGCompliance | X11Compliance | XPMCompliance },
587     { "MediumTurquoise", 72, 209, 204, 1, SVGCompliance | X11Compliance | XPMCompliance },
588     { "MediumVioletRed", 199, 21, 133, 1, SVGCompliance | X11Compliance | XPMCompliance },
589     { "MidnightBlue", 25, 25, 112, 1, SVGCompliance | X11Compliance | XPMCompliance },
590     { "MintCream", 245, 255, 250, 1, SVGCompliance | X11Compliance | XPMCompliance },
591     { "MistyRose", 255, 228, 225, 1, SVGCompliance | X11Compliance | XPMCompliance },
592     { "MistyRose1", 255, 228, 225, 1, X11Compliance },
593     { "MistyRose2", 238, 213, 210, 1, X11Compliance },
594     { "MistyRose3", 205, 183, 181, 1, X11Compliance },
595     { "MistyRose4", 139, 125, 123, 1, X11Compliance },
596     { "moccasin", 255, 228, 181, 1, SVGCompliance | X11Compliance | XPMCompliance },
597     { "NavajoWhite", 255, 222, 173, 1, SVGCompliance | X11Compliance | XPMCompliance },
598     { "NavajoWhite1", 255, 222, 173, 1, X11Compliance },
599     { "NavajoWhite2", 238, 207, 161, 1, X11Compliance },
600     { "NavajoWhite3", 205, 179, 139, 1, X11Compliance },
601     { "NavajoWhite4", 139, 121, 94, 1, X11Compliance },
602     { "navy", 0, 0, 128, 1, SVGCompliance | X11Compliance | XPMCompliance },
603     { "NavyBlue", 0, 0, 128, 1, X11Compliance | XPMCompliance },
604     { "matte", 0, 0, 0, 0, SVGCompliance },
605     { "OldLace", 253, 245, 230, 1, SVGCompliance | X11Compliance | XPMCompliance },
606     { "olive", 128, 128, 0, 1, SVGCompliance },
607     { "OliveDrab", 107, 142, 35, 1, SVGCompliance | X11Compliance | XPMCompliance },
608     { "OliveDrab1", 192, 255, 62, 1, X11Compliance },
609     { "OliveDrab2", 179, 238, 58, 1, X11Compliance },
610     { "OliveDrab3", 154, 205, 50, 1, X11Compliance },
611     { "OliveDrab4", 105, 139, 34, 1, X11Compliance },
612     { "opaque", 0, 0, 0, 1, SVGCompliance },
613     { "orange", 255, 165, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
614     { "orange1", 255, 165, 0, 1, X11Compliance },
615     { "orange2", 238, 154, 0, 1, X11Compliance },
616     { "orange3", 205, 133, 0, 1, X11Compliance },
617     { "orange4", 139, 90, 0, 1, X11Compliance },
618     { "OrangeRed", 255, 69, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
619     { "OrangeRed1", 255, 69, 0, 1, X11Compliance },
620     { "OrangeRed2", 238, 64, 0, 1, X11Compliance },
621     { "OrangeRed3", 205, 55, 0, 1, X11Compliance },
622     { "OrangeRed4", 139, 37, 0, 1, X11Compliance },
623     { "orchid", 218, 112, 214, 1, SVGCompliance | X11Compliance | XPMCompliance },
624     { "orchid1", 255, 131, 250, 1, X11Compliance },
625     { "orchid2", 238, 122, 233, 1, X11Compliance },
626     { "orchid3", 205, 105, 201, 1, X11Compliance },
627     { "orchid4", 139, 71, 137, 1, X11Compliance },
628     { "PaleGoldenrod", 238, 232, 170, 1, SVGCompliance | X11Compliance | XPMCompliance },
629     { "PaleGreen", 152, 251, 152, 1, SVGCompliance | X11Compliance | XPMCompliance },
630     { "PaleGreen1", 154, 255, 154, 1, X11Compliance },
631     { "PaleGreen2", 144, 238, 144, 1, X11Compliance },
632     { "PaleGreen3", 124, 205, 124, 1, X11Compliance },
633     { "PaleGreen4", 84, 139, 84, 1, X11Compliance },
634     { "PaleTurquoise", 175, 238, 238, 1, SVGCompliance | X11Compliance | XPMCompliance },
635     { "PaleTurquoise1", 187, 255, 255, 1, X11Compliance },
636     { "PaleTurquoise2", 174, 238, 238, 1, X11Compliance },
637     { "PaleTurquoise3", 150, 205, 205, 1, X11Compliance },
638     { "PaleTurquoise4", 102, 139, 139, 1, X11Compliance },
639     { "PaleVioletRed", 219, 112, 147, 1, SVGCompliance | X11Compliance | XPMCompliance },
640     { "PaleVioletRed1", 255, 130, 171, 1, X11Compliance },
641     { "PaleVioletRed2", 238, 121, 159, 1, X11Compliance },
642     { "PaleVioletRed3", 205, 104, 137, 1, X11Compliance },
643     { "PaleVioletRed4", 139, 71, 93, 1, X11Compliance },
644     { "PapayaWhip", 255, 239, 213, 1, SVGCompliance | X11Compliance | XPMCompliance },
645     { "PeachPuff", 255, 218, 185, 1, SVGCompliance | X11Compliance | XPMCompliance },
646     { "PeachPuff1", 255, 218, 185, 1, X11Compliance },
647     { "PeachPuff2", 238, 203, 173, 1, X11Compliance },
648     { "PeachPuff3", 205, 175, 149, 1, X11Compliance },
649     { "PeachPuff4", 139, 119, 101, 1, X11Compliance },
650     { "peru", 205, 133, 63, 1, SVGCompliance | X11Compliance | XPMCompliance },
651     { "pink", 255, 192, 203, 1, SVGCompliance | X11Compliance | XPMCompliance },
652     { "pink1", 255, 181, 197, 1, X11Compliance },
653     { "pink2", 238, 169, 184, 1, X11Compliance },
654     { "pink3", 205, 145, 158, 1, X11Compliance },
655     { "pink4", 139, 99, 108, 1, X11Compliance },
656     { "plum", 221, 160, 221, 1, SVGCompliance | X11Compliance | XPMCompliance },
657     { "plum1", 255, 187, 255, 1, X11Compliance },
658     { "plum2", 238, 174, 238, 1, X11Compliance },
659     { "plum3", 205, 150, 205, 1, X11Compliance },
660     { "plum4", 139, 102, 139, 1, X11Compliance },
661     { "PowderBlue", 176, 224, 230, 1, SVGCompliance | X11Compliance | XPMCompliance },
662     { "purple", 128, 0, 128, 1, SVGCompliance },
663     { "purple", 160, 32, 240, 1, X11Compliance | XPMCompliance },
664     { "purple1", 155, 48, 255, 1, X11Compliance },
665     { "purple2", 145, 44, 238, 1, X11Compliance },
666     { "purple3", 125, 38, 205, 1, X11Compliance },
667     { "purple4", 85, 26, 139, 1, X11Compliance },
668     { "red1", 255, 0, 0, 1, X11Compliance },
669     { "red2", 238, 0, 0, 1, X11Compliance },
670     { "red3", 205, 0, 0, 1, X11Compliance },
671     { "red4", 139, 0, 0, 1, X11Compliance },
672     { "RosyBrown", 188, 143, 143, 1, SVGCompliance | X11Compliance | XPMCompliance },
673     { "RosyBrown1", 255, 193, 193, 1, X11Compliance },
674     { "RosyBrown2", 238, 180, 180, 1, X11Compliance },
675     { "RosyBrown3", 205, 155, 155, 1, X11Compliance },
676     { "RosyBrown4", 139, 105, 105, 1, X11Compliance },
677     { "RoyalBlue", 65, 105, 225, 1, SVGCompliance | X11Compliance | XPMCompliance },
678     { "RoyalBlue1", 72, 118, 255, 1, X11Compliance },
679     { "RoyalBlue2", 67, 110, 238, 1, X11Compliance },
680     { "RoyalBlue3", 58, 95, 205, 1, X11Compliance },
681     { "RoyalBlue4", 39, 64, 139, 1, X11Compliance },
682     { "SaddleBrown", 139, 69, 19, 1, SVGCompliance | X11Compliance | XPMCompliance },
683     { "salmon", 250, 128, 114, 1, SVGCompliance | X11Compliance | XPMCompliance },
684     { "salmon1", 255, 140, 105, 1, X11Compliance },
685     { "salmon2", 238, 130, 98, 1, X11Compliance },
686     { "salmon3", 205, 112, 84, 1, X11Compliance },
687     { "salmon4", 139, 76, 57, 1, X11Compliance },
688     { "SandyBrown", 244, 164, 96, 1, SVGCompliance | X11Compliance | XPMCompliance },
689     { "SeaGreen", 46, 139, 87, 1, SVGCompliance | X11Compliance | XPMCompliance },
690     { "SeaGreen1", 84, 255, 159, 1, X11Compliance },
691     { "SeaGreen2", 78, 238, 148, 1, X11Compliance },
692     { "SeaGreen3", 67, 205, 128, 1, X11Compliance },
693     { "SeaGreen4", 46, 139, 87, 1, X11Compliance },
694     { "seashell", 255, 245, 238, 1, SVGCompliance | X11Compliance | XPMCompliance },
695     { "seashell1", 255, 245, 238, 1, X11Compliance },
696     { "seashell2", 238, 229, 222, 1, X11Compliance },
697     { "seashell3", 205, 197, 191, 1, X11Compliance },
698     { "seashell4", 139, 134, 130, 1, X11Compliance },
699     { "sienna", 160, 82, 45, 1, SVGCompliance | X11Compliance | XPMCompliance },
700     { "sienna1", 255, 130, 71, 1, X11Compliance },
701     { "sienna2", 238, 121, 66, 1, X11Compliance },
702     { "sienna3", 205, 104, 57, 1, X11Compliance },
703     { "sienna4", 139, 71, 38, 1, X11Compliance },
704     { "silver", 192, 192, 192, 1, SVGCompliance },
705     { "SkyBlue", 135, 206, 235, 1, SVGCompliance | X11Compliance | XPMCompliance },
706     { "SkyBlue1", 135, 206, 255, 1, X11Compliance },
707     { "SkyBlue2", 126, 192, 238, 1, X11Compliance },
708     { "SkyBlue3", 108, 166, 205, 1, X11Compliance },
709     { "SkyBlue4", 74, 112, 139, 1, X11Compliance },
710     { "SlateBlue", 106, 90, 205, 1, SVGCompliance | X11Compliance | XPMCompliance },
711     { "SlateBlue1", 131, 111, 255, 1, X11Compliance },
712     { "SlateBlue2", 122, 103, 238, 1, X11Compliance },
713     { "SlateBlue3", 105, 89, 205, 1, X11Compliance },
714     { "SlateBlue4", 71, 60, 139, 1, X11Compliance },
715     { "SlateGray", 112, 128, 144, 1, SVGCompliance | X11Compliance | XPMCompliance },
716     { "SlateGray1", 198, 226, 255, 1, X11Compliance },
717     { "SlateGray2", 185, 211, 238, 1, X11Compliance },
718     { "SlateGray3", 159, 182, 205, 1, X11Compliance },
719     { "SlateGray4", 108, 123, 139, 1, X11Compliance },
720     { "SlateGrey", 112, 128, 144, 1, SVGCompliance | X11Compliance },
721     { "snow", 255, 250, 250, 1, SVGCompliance | X11Compliance | XPMCompliance },
722     { "snow1", 255, 250, 250, 1, X11Compliance },
723     { "snow2", 238, 233, 233, 1, X11Compliance },
724     { "snow3", 205, 201, 201, 1, X11Compliance },
725     { "snow4", 139, 137, 137, 1, X11Compliance },
726     { "SpringGreen", 0, 255, 127, 1, SVGCompliance | X11Compliance | XPMCompliance },
727     { "SpringGreen1", 0, 255, 127, 1, X11Compliance },
728     { "SpringGreen2", 0, 238, 118, 1, X11Compliance },
729     { "SpringGreen3", 0, 205, 102, 1, X11Compliance },
730     { "SpringGreen4", 0, 139, 69, 1, X11Compliance },
731     { "SteelBlue", 70, 130, 180, 1, SVGCompliance | X11Compliance | XPMCompliance },
732     { "SteelBlue1", 99, 184, 255, 1, X11Compliance },
733     { "SteelBlue2", 92, 172, 238, 1, X11Compliance },
734     { "SteelBlue3", 79, 148, 205, 1, X11Compliance },
735     { "SteelBlue4", 54, 100, 139, 1, X11Compliance },
736     { "tan", 210, 180, 140, 1, SVGCompliance | X11Compliance | XPMCompliance },
737     { "tan1", 255, 165, 79, 1, X11Compliance },
738     { "tan2", 238, 154, 73, 1, X11Compliance },
739     { "tan3", 205, 133, 63, 1, X11Compliance },
740     { "tan4", 139, 90, 43, 1, X11Compliance },
741     { "teal", 0, 128, 128, 1, SVGCompliance },
742     { "thistle", 216, 191, 216, 1, SVGCompliance | X11Compliance | XPMCompliance },
743     { "thistle1", 255, 225, 255, 1, X11Compliance },
744     { "thistle2", 238, 210, 238, 1, X11Compliance },
745     { "thistle3", 205, 181, 205, 1, X11Compliance },
746     { "thistle4", 139, 123, 139, 1, X11Compliance },
747     { "tomato", 255, 99, 71, 1, SVGCompliance | X11Compliance | XPMCompliance },
748     { "tomato1", 255, 99, 71, 1, X11Compliance },
749     { "tomato2", 238, 92, 66, 1, X11Compliance },
750     { "tomato3", 205, 79, 57, 1, X11Compliance },
751     { "tomato4", 139, 54, 38, 1, X11Compliance },
752     { "transparent", 0, 0, 0, 0, SVGCompliance },
753     { "turquoise", 64, 224, 208, 1, SVGCompliance | X11Compliance | XPMCompliance },
754     { "turquoise1", 0, 245, 255, 1, X11Compliance },
755     { "turquoise2", 0, 229, 238, 1, X11Compliance },
756     { "turquoise3", 0, 197, 205, 1, X11Compliance },
757     { "turquoise4", 0, 134, 139, 1, X11Compliance },
758     { "violet", 238, 130, 238, 1, SVGCompliance | X11Compliance | XPMCompliance },
759     { "VioletRed", 208, 32, 144, 1, X11Compliance | XPMCompliance },
760     { "VioletRed1", 255, 62, 150, 1, X11Compliance },
761     { "VioletRed2", 238, 58, 140, 1, X11Compliance },
762     { "VioletRed3", 205, 50, 120, 1, X11Compliance },
763     { "VioletRed4", 139, 34, 82, 1, X11Compliance },
764     { "wheat", 245, 222, 179, 1, SVGCompliance | X11Compliance | XPMCompliance },
765     { "wheat1", 255, 231, 186, 1, X11Compliance },
766     { "wheat2", 238, 216, 174, 1, X11Compliance },
767     { "wheat3", 205, 186, 150, 1, X11Compliance },
768     { "wheat4", 139, 126, 102, 1, X11Compliance },
769     { "WhiteSmoke", 245, 245, 245, 1, SVGCompliance | X11Compliance | XPMCompliance },
770     { "yellow1", 255, 255, 0, 1, X11Compliance },
771     { "yellow2", 238, 238, 0, 1, X11Compliance },
772     { "yellow3", 205, 205, 0, 1, X11Compliance },
773     { "yellow4", 139, 139, 0, 1, X11Compliance },
774     { "YellowGreen", 154, 205, 50, 1, SVGCompliance | X11Compliance | XPMCompliance },
775     { (const char *) NULL, 0, 0, 0, 0, UndefinedCompliance }
776   };
777 \f
778 /*
779   Static declarations.
780 */
781 static LinkedListInfo
782   *color_list = (LinkedListInfo *) NULL;
783
784 static SemaphoreInfo
785   *color_semaphore = (SemaphoreInfo *) NULL;
786
787 static volatile MagickBooleanType
788   instantiate_color = MagickFalse;
789 \f
790 /*
791   Forward declarations.
792 */
793 static MagickBooleanType
794   InitializeColorList(ExceptionInfo *),
795   LoadColorLists(const char *,ExceptionInfo *);
796 \f
797 /*
798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799 %                                                                             %
800 %                                                                             %
801 %                                                                             %
802 +   C o n c a t e n a t e C o l o r C o m p o n e n t                         %
803 %                                                                             %
804 %                                                                             %
805 %                                                                             %
806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
807 %
808 %  ConcatenateColorComponent() returns the pixel as a canonical string.
809 %
810 %  The format of the ConcatenateColorComponent() method is:
811 %
812 %      void ConcatenateColorComponent(const MagickPixelPacket *pixel,
813 %        const ChannelType channel,const ComplianceType compliance,char *tuple)
814 %
815 %  A description of each parameter follows.
816 %
817 %    o pixel:  The pixel.
818 %
819 %    channel:  The channel.
820 %
821 %    o compliance: Adhere to this color standard: SVG, X11, or XPM.
822 %
823 %    tuple:  The color tuple.
824 %
825 */
826 MagickExport void ConcatenateColorComponent(const MagickPixelPacket *pixel,
827   const ChannelType channel,const ComplianceType compliance,char *tuple)
828 {
829   char
830     component[MaxTextExtent];
831
832   MagickRealType
833     color;
834
835   color=0.0;
836   switch (channel)
837   {
838     case RedChannel:
839     {
840       color=pixel->red;
841       break;
842     }
843     case GreenChannel:
844     {
845       color=pixel->green;
846       break;
847     }
848     case BlueChannel:
849     {
850       color=pixel->blue;
851       break;
852     }
853     case AlphaChannel:
854     {
855       color=QuantumRange-pixel->opacity;
856       break;
857     }
858     case IndexChannel:
859     {
860       color=pixel->index;
861       break;
862     }
863     default:
864       break;
865   }
866   if (compliance != SVGCompliance)
867     {
868       if (pixel->depth > 16)
869         {
870           (void) FormatMagickString(component,MaxTextExtent,"%10lu",
871             (unsigned long) ScaleQuantumToLong(RoundToQuantum(color)));
872           (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
873           return;
874         }
875       if (pixel->depth > 8)
876         {
877           (void) FormatMagickString(component,MaxTextExtent,"%5d",
878             ScaleQuantumToShort(RoundToQuantum(color)));
879           (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
880           return;
881         }
882       (void) FormatMagickString(component,MaxTextExtent,"%3d",
883         ScaleQuantumToChar(RoundToQuantum(color)));
884       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
885       return;
886     }
887   if (channel == OpacityChannel)
888     {
889       (void) FormatMagickString(component,MaxTextExtent,"%g",
890         (double) (QuantumScale*color));
891       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
892       return;
893     }
894   if (pixel->depth > 8)
895     {
896       (void) FormatMagickString(component,MaxTextExtent,"%g%%",
897         (double) (100.0*QuantumScale*color));
898       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
899       return;
900     }
901   (void) FormatMagickString(component,MaxTextExtent,"%d",
902     ScaleQuantumToChar(RoundToQuantum(color)));
903   (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
904 }
905 \f
906 /*
907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908 %                                                                             %
909 %                                                                             %
910 %                                                                             %
911 +   D e s t r o y C o l o r F a c i l i t y                                   %
912 %                                                                             %
913 %                                                                             %
914 %                                                                             %
915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
916 %
917 %  DestroyColorFacility() destroys the color facility.
918 %
919 %  The format of the DestroyColorFacility method is:
920 %
921 %      DestroyColorFacility(void)
922 %
923 */
924
925 static void *DestroyColorElement(void *color_info)
926 {
927   register ColorInfo
928     *p;
929
930   p=(ColorInfo *) color_info;
931   if (p->exempt  == MagickFalse)
932     {
933       if (p->path != (char *) NULL)
934         p->path=DestroyString(p->path);
935       if (p->name != (char *) NULL)
936         p->name=DestroyString(p->name);
937     }
938   p=(ColorInfo *) RelinquishMagickMemory(p);
939   return((void *) NULL);
940 }
941
942 MagickExport void DestroyColorFacility(void)
943 {
944   AcquireSemaphoreInfo(&color_semaphore);
945   if (color_list != (LinkedListInfo *) NULL)
946     color_list=DestroyLinkedList(color_list,DestroyColorElement);
947   instantiate_color=MagickFalse;
948   RelinquishSemaphoreInfo(color_semaphore);
949   DestroySemaphoreInfo(&color_semaphore);
950 }
951 \f
952 /*
953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
954 %                                                                             %
955 %                                                                             %
956 %                                                                             %
957 +   G e t C o l o r I n f o                                                   %
958 %                                                                             %
959 %                                                                             %
960 %                                                                             %
961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
962 %
963 %  GetColorInfo() searches the color list for the specified name and if found
964 %  returns attributes for that color.
965 %
966 %  The format of the GetColorInfo method is:
967 %
968 %      const PixelPacket *GetColorInfo(const char *name,
969 %        ExceptionInfo *exception)
970 %
971 %  A description of each parameter follows:
972 %
973 %    o color_info: search the color list for the specified name and if found
974 %      return attributes for that color.
975 %
976 %    o name: the color name.
977 %
978 %    o exception: return any errors or warnings in this structure.
979 %
980 */
981 MagickExport const ColorInfo *GetColorInfo(const char *name,
982   ExceptionInfo *exception)
983 {
984   char
985     colorname[MaxTextExtent];
986
987   register const ColorInfo
988     *p;
989
990   register char
991     *q;
992
993   assert(exception != (ExceptionInfo *) NULL);
994   if ((color_list == (LinkedListInfo *) NULL) ||
995       (instantiate_color == MagickFalse))
996     if (InitializeColorList(exception) == MagickFalse)
997       return((const ColorInfo *) NULL);
998   if ((color_list == (LinkedListInfo *) NULL) ||
999       (IsLinkedListEmpty(color_list) != MagickFalse))
1000     return((const ColorInfo *) NULL);
1001   if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
1002     return((const ColorInfo *) GetValueFromLinkedList(color_list,0));
1003   /*
1004     Strip names of whitespace.
1005   */
1006   (void) CopyMagickString(colorname,name,MaxTextExtent);
1007   for (q=colorname; *q != '\0'; q++)
1008   {
1009     if (isspace((int) ((unsigned char) *q)) == 0)
1010       continue;
1011     (void) CopyMagickString(q,q+1,MaxTextExtent);
1012     q--;
1013   }
1014   /*
1015     Search for color tag.
1016   */
1017   AcquireSemaphoreInfo(&color_semaphore);
1018   ResetLinkedListIterator(color_list);
1019   p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
1020   while (p != (const ColorInfo *) NULL)
1021   {
1022     if (LocaleCompare(colorname,p->name) == 0)
1023       break;
1024     p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
1025   }
1026   if (p == (ColorInfo *) NULL)
1027     (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
1028       "UnrecognizedColor","`%s'",name);
1029   else
1030     (void) InsertValueInLinkedList(color_list,0,
1031       RemoveElementByValueFromLinkedList(color_list,p));
1032   RelinquishSemaphoreInfo(color_semaphore);
1033   return(p);
1034 }
1035 \f
1036 /*
1037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038 %                                                                             %
1039 %                                                                             %
1040 %                                                                             %
1041 %   G e t C o l o r I n f o L i s t                                           %
1042 %                                                                             %
1043 %                                                                             %
1044 %                                                                             %
1045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046 %
1047 %  GetColorInfoList() returns any colors that match the specified pattern.
1048 %
1049 %  The format of the GetColorInfoList function is:
1050 %
1051 %      const ColorInfo **GetColorInfoList(const char *pattern,
1052 %        unsigned long *number_colors,ExceptionInfo *exception)
1053 %
1054 %  A description of each parameter follows:
1055 %
1056 %    o pattern: Specifies a pointer to a text string containing a pattern.
1057 %
1058 %    o number_colors:  This integer returns the number of colors in the list.
1059 %
1060 %    o exception: return any errors or warnings in this structure.
1061 %
1062 */
1063
1064 #if defined(__cplusplus) || defined(c_plusplus)
1065 extern "C" {
1066 #endif
1067
1068 static int ColorInfoCompare(const void *x,const void *y)
1069 {
1070   const ColorInfo
1071     **p,
1072     **q;
1073
1074   p=(const ColorInfo **) x,
1075   q=(const ColorInfo **) y;
1076   if (LocaleCompare((*p)->path,(*q)->path) == 0)
1077     return(LocaleCompare((*p)->name,(*q)->name));
1078   return(LocaleCompare((*p)->path,(*q)->path));
1079 }
1080
1081 #if defined(__cplusplus) || defined(c_plusplus)
1082 }
1083 #endif
1084
1085 MagickExport const ColorInfo **GetColorInfoList(const char *pattern,
1086   unsigned long *number_colors,ExceptionInfo *exception)
1087 {
1088   const ColorInfo
1089     **colors;
1090
1091   register const ColorInfo
1092     *p;
1093
1094   register long
1095     i;
1096
1097   /*
1098     Allocate color list.
1099   */
1100   assert(pattern != (char *) NULL);
1101   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
1102   assert(number_colors != (unsigned long *) NULL);
1103   *number_colors=0;
1104   p=GetColorInfo("*",exception);
1105   if (p == (const ColorInfo *) NULL)
1106     return((const ColorInfo **) NULL);
1107   colors=(const ColorInfo **) AcquireQuantumMemory((size_t)
1108     GetNumberOfElementsInLinkedList(color_list)+1UL,sizeof(*colors));
1109   if (colors == (const ColorInfo **) NULL)
1110     return((const ColorInfo **) NULL);
1111   /*
1112     Generate color list.
1113   */
1114   AcquireSemaphoreInfo(&color_semaphore);
1115   ResetLinkedListIterator(color_list);
1116   p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
1117   for (i=0; p != (const ColorInfo *) NULL; )
1118   {
1119     if ((p->stealth == MagickFalse) &&
1120         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
1121       colors[i++]=p;
1122     p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
1123   }
1124   RelinquishSemaphoreInfo(color_semaphore);
1125   qsort((void *) colors,(size_t) i,sizeof(*colors),ColorInfoCompare);
1126   colors[i]=(ColorInfo *) NULL;
1127   *number_colors=(unsigned long) i;
1128   return(colors);
1129 }
1130 \f
1131 /*
1132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1133 %                                                                             %
1134 %                                                                             %
1135 %                                                                             %
1136 %   G e t C o l o r L i s t                                                   %
1137 %                                                                             %
1138 %                                                                             %
1139 %                                                                             %
1140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1141 %
1142 %  GetColorList() returns any colors that match the specified pattern.
1143 %
1144 %  The format of the GetColorList function is:
1145 %
1146 %      char **GetColorList(const char *pattern,unsigned long *number_colors,
1147 %        ExceptionInfo *exception)
1148 %
1149 %  A description of each parameter follows:
1150 %
1151 %    o pattern: Specifies a pointer to a text string containing a pattern.
1152 %
1153 %    o number_colors:  This integer returns the number of colors in the list.
1154 %
1155 %    o exception: return any errors or warnings in this structure.
1156 %
1157 */
1158
1159 #if defined(__cplusplus) || defined(c_plusplus)
1160 extern "C" {
1161 #endif
1162
1163 static int ColorCompare(const void *x,const void *y)
1164 {
1165   register const char
1166     **p,
1167     **q;
1168
1169   p=(const char **) x;
1170   q=(const char **) y;
1171   return(LocaleCompare(*p,*q));
1172 }
1173
1174 #if defined(__cplusplus) || defined(c_plusplus)
1175 }
1176 #endif
1177
1178 MagickExport char **GetColorList(const char *pattern,
1179   unsigned long *number_colors,ExceptionInfo *exception)
1180 {
1181   char
1182     **colors;
1183
1184   register const ColorInfo
1185     *p;
1186
1187   register long
1188     i;
1189
1190   /*
1191     Allocate color list.
1192   */
1193   assert(pattern != (char *) NULL);
1194   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
1195   assert(number_colors != (unsigned long *) NULL);
1196   *number_colors=0;
1197   p=GetColorInfo("*",exception);
1198   if (p == (const ColorInfo *) NULL)
1199     return((char **) NULL);
1200   colors=(char **) AcquireQuantumMemory((size_t)
1201     GetNumberOfElementsInLinkedList(color_list)+1UL,sizeof(*colors));
1202   if (colors == (char **) NULL)
1203     return((char **) NULL);
1204   /*
1205     Generate color list.
1206   */
1207   AcquireSemaphoreInfo(&color_semaphore);
1208   ResetLinkedListIterator(color_list);
1209   p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
1210   for (i=0; p != (const ColorInfo *) NULL; )
1211   {
1212     if ((p->stealth == MagickFalse) &&
1213         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
1214       colors[i++]=ConstantString(p->name);
1215     p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
1216   }
1217   RelinquishSemaphoreInfo(color_semaphore);
1218   qsort((void *) colors,(size_t) i,sizeof(*colors),ColorCompare);
1219   colors[i]=(char *) NULL;
1220   *number_colors=(unsigned long) i;
1221   return(colors);
1222 }
1223 \f
1224 /*
1225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1226 %                                                                             %
1227 %                                                                             %
1228 %                                                                             %
1229 +   G e t C o l o r T u p l e                                                 %
1230 %                                                                             %
1231 %                                                                             %
1232 %                                                                             %
1233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1234 %
1235 %  GetColorTuple() returns a color as a color tuple string (e.g. rgba(255,0,0))
1236 %  or hex string (e.g. #FF0000).
1237 %
1238 %  The format of the GetColorTuple method is:
1239 %
1240 %      GetColorTuple(const MagickPixelPacket *pixel,const MagickBooleanType hex,
1241 %        char *tuple)
1242 %
1243 %  A description of each parameter follows.
1244 %
1245 %    o pixel: the pixel.
1246 %
1247 %    o hex: A value other than zero returns the tuple in a hexidecimal format.
1248 %
1249 %    o tuple: Return the color tuple as this string.
1250 %
1251 */
1252
1253 static void ConcatentateHexColorComponent(const MagickPixelPacket *pixel,
1254   const ChannelType channel,char *tuple)
1255 {
1256   char
1257     component[MaxTextExtent];
1258
1259   MagickRealType
1260     color;
1261
1262   color=0.0;
1263   switch (channel)
1264   {
1265     case RedChannel:
1266     {
1267       color=pixel->red;
1268       break;
1269     }
1270     case GreenChannel:
1271     {
1272       color=pixel->green;
1273       break;
1274     }
1275     case BlueChannel:
1276     {
1277       color=pixel->blue;
1278       break;
1279     }
1280     case OpacityChannel:
1281     {
1282       color=(MagickRealType) QuantumRange-pixel->opacity;
1283       break;
1284     }
1285     case IndexChannel:
1286     {
1287       color=pixel->index;
1288       break;
1289     }
1290     default:
1291       break;
1292   }
1293   if (pixel->depth > 32)
1294     {
1295       (void) FormatMagickString(component,MaxTextExtent,"%08lX",
1296         ScaleQuantumToLong(RoundToQuantum(color)));
1297       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
1298       return;
1299     }
1300   if (pixel->depth > 16)
1301     {
1302       (void) FormatMagickString(component,MaxTextExtent,"%08X",
1303         (unsigned int) ScaleQuantumToLong(RoundToQuantum(color)));
1304       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
1305       return;
1306     }
1307   if (pixel->depth > 8)
1308     {
1309       (void) FormatMagickString(component,MaxTextExtent,"%04X",
1310         ScaleQuantumToShort(RoundToQuantum(color)));
1311       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
1312       return;
1313     }
1314   (void) FormatMagickString(component,MaxTextExtent,"%02X",
1315     ScaleQuantumToChar(RoundToQuantum(color)));
1316   (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
1317   return;
1318 }
1319
1320 MagickExport void GetColorTuple(const MagickPixelPacket *pixel,
1321   const MagickBooleanType hex,char *tuple)
1322 {
1323   MagickPixelPacket
1324     color;
1325
1326   assert(pixel != (const MagickPixelPacket *) NULL);
1327   assert(tuple != (char *) NULL);
1328   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tuple);
1329   *tuple='\0';
1330   if (hex != MagickFalse)
1331     {
1332       /*
1333         Convert pixel to hex color.
1334       */
1335       (void) ConcatenateMagickString(tuple,"#",MaxTextExtent);
1336       ConcatentateHexColorComponent(pixel,RedChannel,tuple);
1337       ConcatentateHexColorComponent(pixel,GreenChannel,tuple);
1338       ConcatentateHexColorComponent(pixel,BlueChannel,tuple);
1339       if (pixel->colorspace == CMYKColorspace)
1340         ConcatentateHexColorComponent(pixel,IndexChannel,tuple);
1341       if ((pixel->matte != MagickFalse) && (pixel->opacity != OpaqueOpacity))
1342         ConcatentateHexColorComponent(pixel,OpacityChannel,tuple);
1343       return;
1344     }
1345   /*
1346     Convert pixel to rgb() or cmyk() color.
1347   */
1348   color=(*pixel);
1349   if (color.depth > 8)
1350     {
1351 #define SVGCompliant(component) ((MagickRealType) \
1352    ScaleCharToQuantum(ScaleQuantumToChar(RoundToQuantum(component))));
1353
1354       MagickStatusType
1355         status;
1356
1357       /*
1358         SVG requires color depths > 8 expressed as percentages.
1359       */
1360       status=color.red == SVGCompliant(color.red);
1361       status&=color.green == SVGCompliant(color.green);
1362       status&=color.blue == SVGCompliant(color.blue);
1363       if (color.colorspace != CMYKColorspace)
1364         status&=color.index == SVGCompliant(color.index);
1365       if (color.matte != MagickFalse)
1366         status&=color.opacity == SVGCompliant(color.opacity);
1367       if (status != MagickFalse)
1368         color.depth=8;
1369     }
1370   (void) ConcatenateMagickString(tuple,MagickOptionToMnemonic(
1371     MagickColorspaceOptions,(long) color.colorspace),MaxTextExtent);
1372   if (color.matte != MagickFalse)
1373     (void) ConcatenateMagickString(tuple,"a",MaxTextExtent);
1374   (void) ConcatenateMagickString(tuple,"(",MaxTextExtent);
1375   ConcatenateColorComponent(&color,RedChannel,SVGCompliance,tuple);
1376   (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
1377   ConcatenateColorComponent(&color,GreenChannel,SVGCompliance,tuple);
1378   (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
1379   ConcatenateColorComponent(&color,BlueChannel,SVGCompliance,tuple);
1380   if (color.colorspace == CMYKColorspace)
1381     {
1382       (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
1383       ConcatenateColorComponent(&color,IndexChannel,SVGCompliance,tuple);
1384     }
1385   if (color.matte != MagickFalse)
1386     {
1387       (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
1388       ConcatenateColorComponent(&color,AlphaChannel,SVGCompliance,tuple);
1389     }
1390   (void) ConcatenateMagickString(tuple,")",MaxTextExtent);
1391   LocaleLower(tuple);
1392   return;
1393 }
1394 \f
1395 /*
1396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1397 %                                                                             %
1398 %                                                                             %
1399 %                                                                             %
1400 +   I n i t i a l i z e C o l o r L i s t                                     %
1401 %                                                                             %
1402 %                                                                             %
1403 %                                                                             %
1404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1405 %
1406 %  InitializeColorList() initializes the color list.
1407 %
1408 %  The format of the InitializeColorList method is:
1409 %
1410 %      MagickBooleanType InitializeColorList(ExceptionInfo *exception)
1411 %
1412 %  A description of each parameter follows.
1413 %
1414 %    o exception: return any errors or warnings in this structure.
1415 %
1416 */
1417 static MagickBooleanType InitializeColorList(ExceptionInfo *exception)
1418 {
1419   if ((color_list == (LinkedListInfo *) NULL) &&
1420       (instantiate_color == MagickFalse))
1421     {
1422       AcquireSemaphoreInfo(&color_semaphore);
1423       if ((color_list == (LinkedListInfo *) NULL) &&
1424           (instantiate_color == MagickFalse))
1425         {
1426           (void) LoadColorLists(ColorFilename,exception);
1427           instantiate_color=MagickTrue;
1428         }
1429       RelinquishSemaphoreInfo(color_semaphore);
1430     }
1431   return(color_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
1432 }
1433 \f
1434 /*
1435 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1436 %                                                                             %
1437 %                                                                             %
1438 %                                                                             %
1439 +   I n s t a n t i a t e C o l o r F a c i l i t y                           %
1440 %                                                                             %
1441 %                                                                             %
1442 %                                                                             %
1443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1444 %
1445 %  InstantiateColorFacility() instantiates the color facility.
1446 %
1447 %  The format of the InstantiateColorFacility method is:
1448 %
1449 %      MagickBooleanType InstantiateColorFacility(void)
1450 %
1451 */
1452 MagickExport MagickBooleanType InstantiateColorFacility(void)
1453 {
1454   AcquireSemaphoreInfo(&color_semaphore);
1455   RelinquishSemaphoreInfo(color_semaphore);
1456   return(MagickTrue);
1457 }
1458 \f
1459 /*
1460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1461 %                                                                             %
1462 %                                                                             %
1463 %                                                                             %
1464 +   I s C o l o r S i m i l a r                                               %
1465 %                                                                             %
1466 %                                                                             %
1467 %                                                                             %
1468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1469 %
1470 %  IsColorSimilar() returns MagickTrue if the distance between two colors is
1471 %  less than the specified distance in a linear three dimensional color space.
1472 %  This method is used by ColorFloodFill() and other algorithms which
1473 %  compare two colors.
1474 %
1475 %  The format of the IsColorSimilar method is:
1476 %
1477 %      void IsColorSimilar(const Image *image,const PixelPacket *p,
1478 %        const PixelPacket *q)
1479 %
1480 %  A description of each parameter follows:
1481 %
1482 %    o image: the image.
1483 %
1484 %    o p: Pixel p.
1485 %
1486 %    o q: Pixel q.
1487 %
1488 */
1489
1490 static inline double MagickMax(const double x,const double y)
1491 {
1492   if (x > y)
1493     return(x);
1494   return(y);
1495 }
1496
1497 MagickExport MagickBooleanType IsColorSimilar(const Image *image,
1498   const PixelPacket *p,const PixelPacket *q)
1499 {
1500   MagickRealType
1501     fuzz,
1502     pixel;
1503
1504   register MagickRealType
1505     alpha,
1506     beta,
1507     distance;
1508
1509   if ((image->fuzz == 0.0) && (image->matte == MagickFalse))
1510     return(IsColorEqual(p,q));
1511   fuzz=3.0*MagickMax(image->fuzz,MagickSQ1_2)*MagickMax(image->fuzz,
1512     MagickSQ1_2);
1513   alpha=1.0;
1514   beta=1.0;
1515   if (image->matte != MagickFalse)
1516     {
1517       alpha=(MagickRealType) (QuantumScale*(QuantumRange-p->opacity));
1518       beta=(MagickRealType) (QuantumScale*(QuantumRange-q->opacity));
1519     }
1520   pixel=alpha*p->red-beta*q->red;
1521   distance=pixel*pixel;
1522   if (distance > fuzz)
1523     return(MagickFalse);
1524   pixel=alpha*p->green-beta*q->green;
1525   distance+=pixel*pixel;
1526   if (distance > fuzz)
1527     return(MagickFalse);
1528   pixel=alpha*p->blue-beta*q->blue;
1529   distance+=pixel*pixel;
1530   if (distance > fuzz)
1531     return(MagickFalse);
1532   return(MagickTrue);
1533 }
1534 \f
1535 /*
1536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1537 %                                                                             %
1538 %                                                                             %
1539 %                                                                             %
1540 +   I s I m a g e S i m i l a r                                               %
1541 %                                                                             %
1542 %                                                                             %
1543 %                                                                             %
1544 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1545 %
1546 %  IsImageSimilar() returns true if the target is similar to a region of the
1547 %  image.
1548 %
1549 %  The format of the IsImageSimilar method is:
1550 %
1551 %      MagickBooleanType IsImageSimilar(const Image *image,
1552 %        const Image *target_image,long *x_offset,long *y_offset,
1553 %        ExceptionInfo *exception)
1554 %
1555 %  A description of each parameter follows:
1556 %
1557 %    o image: the image.
1558 %
1559 %    o target_image: the target image.
1560 %
1561 %    o x_offset: On input the starting x position to search for a match;
1562 %      on output the x position of the first match found.
1563 %
1564 %    o y_offset: On input the starting y position to search for a match;
1565 %      on output the y position of the first match found.
1566 %
1567 %    o exception: return any errors or warnings in this structure.
1568 %
1569 */
1570 MagickExport MagickBooleanType IsImageSimilar(const Image *image,
1571   const Image *target_image,long *x_offset,long *y_offset,
1572   ExceptionInfo *exception)
1573 {
1574 #define SearchImageText  "  Searching image...  "
1575
1576   long
1577     j,
1578     y;
1579
1580   MagickBooleanType
1581     status;
1582
1583   MagickPixelPacket
1584     target,
1585     pixel;
1586
1587   register const PixelPacket
1588     *p,
1589     *q;
1590
1591   register const IndexPacket
1592     *indexes,
1593     *target_indexes;
1594
1595   register long
1596     i,
1597     x;
1598
1599   CacheView
1600     *image_view,
1601     *target_view;
1602
1603   assert(image != (Image *) NULL);
1604   assert(image->signature == MagickSignature);
1605   if (image->debug != MagickFalse)
1606     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1607   assert(target_image != (Image *) NULL);
1608   assert(target_image->signature == MagickSignature);
1609   assert(x_offset != (long *) NULL);
1610   assert(y_offset != (long *) NULL);
1611   assert(exception != (ExceptionInfo *) NULL);
1612   x=0;
1613   GetMagickPixelPacket(image,&pixel);
1614   GetMagickPixelPacket(image,&target);
1615   image_view=AcquireCacheView(image);
1616   target_view=AcquireCacheView(target_image);
1617   for (y=(*y_offset); y < (long) image->rows; y++)
1618   {
1619     for (x=y == 0 ? *x_offset : 0; x < (long) image->columns; x++)
1620     {
1621       for (j=0; j < (long) target_image->rows; j++)
1622       {
1623         for (i=0; i < (long) target_image->columns; i++)
1624         {
1625           p=GetCacheViewVirtualPixels(image_view,x+i,y+j,1,1,exception);
1626           indexes=GetCacheViewVirtualIndexQueue(image_view);
1627           SetMagickPixelPacket(image,p,indexes,&pixel);
1628           q=GetCacheViewVirtualPixels(target_view,i,j,1,1,exception);
1629           target_indexes=GetCacheViewVirtualIndexQueue(target_view);
1630           SetMagickPixelPacket(image,q,target_indexes,&target);
1631           if (IsMagickColorSimilar(&pixel,&target) == MagickFalse)
1632             break;
1633         }
1634         if (i < (long) target_image->columns)
1635           break;
1636       }
1637       if (j == (long) target_image->rows)
1638         break;
1639     }
1640     if (x < (long) image->columns)
1641       break;
1642     if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1643         (QuantumTick(y,image->rows) != MagickFalse))
1644       {
1645         status=image->progress_monitor(SearchImageText,y,image->rows,
1646           image->client_data);
1647         if (status == MagickFalse)
1648           break;
1649       }
1650   }
1651   target_view=DestroyCacheView(target_view);
1652   image_view=DestroyCacheView(image_view);
1653   *x_offset=x;
1654   *y_offset=y;
1655   return(y < (long) image->rows ? MagickTrue : MagickFalse);
1656 }
1657 \f
1658 /*
1659 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1660 %                                                                             %
1661 %                                                                             %
1662 %                                                                             %
1663 +   I s M a g i c k C o l o r S i m i l a r                                   %
1664 %                                                                             %
1665 %                                                                             %
1666 %                                                                             %
1667 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1668 %
1669 %  IsMagickColorSimilar() returns true if the distance between two colors is
1670 %  less than the specified distance in a linear three dimensional color space.
1671 %  This method is used by ColorFloodFill() and other algorithms which
1672 %  compare two colors.
1673 %
1674 %  The format of the IsMagickColorSimilar method is:
1675 %
1676 %      MagickBooleanType IsMagickColorSimilar(const MagickPixelPacket *p,
1677 %        const MagickPixelPacket *q)
1678 %
1679 %  A description of each parameter follows:
1680 %
1681 %    o p: Pixel p.
1682 %
1683 %    o q: Pixel q.
1684 %
1685 */
1686 MagickExport MagickBooleanType IsMagickColorSimilar(const MagickPixelPacket *p,
1687   const MagickPixelPacket *q)
1688 {
1689   MagickRealType
1690     fuzz,
1691     pixel;
1692
1693   register MagickRealType
1694     alpha,
1695     beta,
1696     distance;
1697
1698   if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
1699     return(IsMagickColorEqual(p,q));
1700   if (p->fuzz == 0.0)
1701     fuzz=MagickMax(q->fuzz,MagickSQ1_2)*MagickMax(q->fuzz,MagickSQ1_2);
1702   else
1703     if (q->fuzz == 0.0)
1704       fuzz=3.0*MagickMax(p->fuzz,MagickSQ1_2)*MagickMax(p->fuzz,MagickSQ1_2);
1705     else
1706       fuzz=3.0*MagickMax(p->fuzz,MagickSQ1_2)*MagickMax(q->fuzz,MagickSQ1_2);
1707   alpha=1.0;
1708   if (p->matte != MagickFalse)
1709     alpha=(MagickRealType) (QuantumScale*(QuantumRange-p->opacity));
1710   beta=1.0;
1711   if (q->matte != MagickFalse)
1712     beta=(MagickRealType) (QuantumScale*(QuantumRange-q->opacity));
1713   if (p->colorspace == CMYKColorspace)
1714     {
1715       alpha*=(MagickRealType) (QuantumScale*(QuantumRange-p->index));
1716       beta*=(MagickRealType) (QuantumScale*(QuantumRange-q->index));
1717     }
1718   pixel=alpha*p->red-beta*q->red;
1719   if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
1720       (p->colorspace == HWBColorspace))
1721     {
1722       if (fabs(p->red-q->red) > (QuantumRange/2))
1723         {
1724           if (p->red > (QuantumRange/2))
1725             pixel=alpha*(p->red-QuantumRange)-beta*q->red;
1726           else
1727             pixel=alpha*p->red-beta*(q->red-QuantumRange);
1728         }
1729         pixel*=2;
1730      }
1731   distance=pixel*pixel;
1732   if (distance > fuzz)
1733     return(MagickFalse);
1734   pixel=alpha*p->green-beta*q->green;
1735   distance+=pixel*pixel;
1736   if (distance > fuzz)
1737     return(MagickFalse);
1738   pixel=alpha*p->blue-beta*q->blue;
1739   distance+=pixel*pixel;
1740   if (distance > fuzz)
1741     return(MagickFalse);
1742   pixel=p->opacity-q->opacity;
1743   distance+=pixel*pixel;
1744   if (distance > fuzz)
1745     return(MagickFalse);
1746   return(MagickTrue);
1747 }
1748 \f
1749 /*
1750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1751 %                                                                             %
1752 %                                                                             %
1753 %                                                                             %
1754 +   I s O p a c i t y S i m i l a r                                           %
1755 %                                                                             %
1756 %                                                                             %
1757 %                                                                             %
1758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1759 %
1760 %  IsOpacitySimilar() returns true if the distance between two opacity
1761 %  values is less than the specified distance in a linear color space.  This
1762 %  method is used by MatteFloodFill() and other algorithms which compare
1763 %  two opacity values.
1764 %
1765 %  The format of the IsOpacitySimilar method is:
1766 %
1767 %      void IsOpacitySimilar(const Image *image,const PixelPacket *p,
1768 %        const PixelPacket *q)
1769 %
1770 %  A description of each parameter follows:
1771 %
1772 %    o image: the image.
1773 %
1774 %    o p: Pixel p.
1775 %
1776 %    o q: Pixel q.
1777 %
1778 */
1779 MagickExport MagickBooleanType IsOpacitySimilar(const Image *image,
1780   const PixelPacket *p,const PixelPacket *q)
1781 {
1782   MagickRealType
1783     fuzz,
1784     pixel;
1785
1786   register MagickRealType
1787     distance;
1788
1789   if (image->matte == MagickFalse)
1790     return(MagickTrue);
1791   if (p->opacity == q->opacity)
1792     return(MagickTrue);
1793   fuzz=MagickMax(image->fuzz,MagickSQ1_2)*MagickMax(image->fuzz,MagickSQ1_2);
1794   pixel=(MagickRealType) p->opacity-(MagickRealType) q->opacity;
1795   distance=pixel*pixel;
1796   if (distance > fuzz)
1797     return(MagickFalse);
1798   return(MagickTrue);
1799 }
1800 \f
1801 /*
1802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1803 %                                                                             %
1804 %                                                                             %
1805 %                                                                             %
1806 %  L i s t C o l o r I n f o                                                  %
1807 %                                                                             %
1808 %                                                                             %
1809 %                                                                             %
1810 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1811 %
1812 %  ListColorInfo() lists color names to the specified file.  Color names
1813 %  are a convenience.  Rather than defining a color by its red, green, and
1814 %  blue intensities just use a color name such as white, blue, or yellow.
1815 %
1816 %  The format of the ListColorInfo method is:
1817 %
1818 %      MagickBooleanType ListColorInfo(FILE *file,ExceptionInfo *exception)
1819 %
1820 %  A description of each parameter follows.
1821 %
1822 %    o file:  List color names to this file handle.
1823 %
1824 %    o exception: return any errors or warnings in this structure.
1825 %
1826 */
1827 MagickExport MagickBooleanType ListColorInfo(FILE *file,
1828   ExceptionInfo *exception)
1829 {
1830   char
1831     tuple[MaxTextExtent];
1832
1833   const char
1834     *path;
1835
1836   const ColorInfo
1837     **color_info;
1838
1839   register long
1840     i;
1841
1842   unsigned long
1843     number_colors;
1844
1845   /*
1846     List name and attributes of each color in the list.
1847   */
1848   if (file == (const FILE *) NULL)
1849     file=stdout;
1850   color_info=GetColorInfoList("*",&number_colors,exception);
1851   if (color_info == (const ColorInfo **) NULL)
1852     return(MagickFalse);
1853   path=(const char *) NULL;
1854   for (i=0; i < (long) number_colors; i++)
1855   {
1856     if (color_info[i]->stealth != MagickFalse)
1857       continue;
1858     if ((path == (const char *) NULL) ||
1859         (LocaleCompare(path,color_info[i]->path) != 0))
1860       {
1861         if (color_info[i]->path != (char *) NULL)
1862           (void) fprintf(file,"\nPath: %s\n\n",color_info[i]->path);
1863         (void) fprintf(file,"Name                  Color                  "
1864           "                       Compliance\n");
1865         (void) fprintf(file,"-------------------------------------------------"
1866           "------------------------------\n");
1867       }
1868     path=color_info[i]->path;
1869     (void) fprintf(file,"%-21.21s ",color_info[i]->name);
1870     GetColorTuple(&color_info[i]->color,MagickFalse,tuple);
1871     (void) fprintf(file,"%-45.45s ",tuple);
1872     if ((color_info[i]->compliance & SVGCompliance) != 0)
1873       (void) fprintf(file,"SVG ");
1874     if ((color_info[i]->compliance & X11Compliance) != 0)
1875       (void) fprintf(file,"X11 ");
1876     if ((color_info[i]->compliance & XPMCompliance) != 0)
1877       (void) fprintf(file,"XPM ");
1878     (void) fprintf(file,"\n");
1879   }
1880   color_info=(const ColorInfo **) RelinquishMagickMemory((void *) color_info);
1881   (void) fflush(file);
1882   return(MagickTrue);
1883 }
1884 \f
1885 /*
1886 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1887 %                                                                             %
1888 %                                                                             %
1889 %                                                                             %
1890 +   L o a d C o l o r L i s t                                                 %
1891 %                                                                             %
1892 %                                                                             %
1893 %                                                                             %
1894 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1895 %
1896 %  LoadColorList() loads the color configuration file which provides a mapping
1897 %  between color attributes and a color name.
1898 %
1899 %  The format of the LoadColorList method is:
1900 %
1901 %      MagickBooleanType LoadColorList(const char *xml,const char *filename,
1902 %        const unsigned long depth,ExceptionInfo *exception)
1903 %
1904 %  A description of each parameter follows:
1905 %
1906 %    o xml:  The color list in XML format.
1907 %
1908 %    o filename:  The color list filename.
1909 %
1910 %    o depth: depth of <include /> statements.
1911 %
1912 %    o exception: return any errors or warnings in this structure.
1913 %
1914 */
1915 static MagickBooleanType LoadColorList(const char *xml,const char *filename,
1916   const unsigned long depth,ExceptionInfo *exception)
1917 {
1918   char
1919     keyword[MaxTextExtent],
1920     *token;
1921
1922   ColorInfo
1923     *color_info;
1924
1925   const char
1926     *q;
1927
1928   MagickBooleanType
1929     status;
1930
1931   /*
1932     Load the color map file.
1933   */
1934   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1935     "Loading color file \"%s\" ...",filename);
1936   if (xml == (char *) NULL)
1937     return(MagickFalse);
1938   if (color_list == (LinkedListInfo *) NULL)
1939     {
1940       color_list=NewLinkedList(0);
1941       if (color_list == (LinkedListInfo *) NULL)
1942         {
1943           ThrowFileException(exception,ResourceLimitError,
1944             "MemoryAllocationFailed",filename);
1945           return(MagickFalse);
1946         }
1947     }
1948   status=MagickTrue;
1949   color_info=(ColorInfo *) NULL;
1950   token=AcquireString(xml);
1951   for (q=(char *) xml; *q != '\0'; )
1952   {
1953     /*
1954       Interpret XML.
1955     */
1956     GetMagickToken(q,&q,token);
1957     if (*token == '\0')
1958       break;
1959     (void) CopyMagickString(keyword,token,MaxTextExtent);
1960     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1961       {
1962         /*
1963           Doctype element.
1964         */
1965         while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1966           GetMagickToken(q,&q,token);
1967         continue;
1968       }
1969     if (LocaleNCompare(keyword,"<!--",4) == 0)
1970       {
1971         /*
1972           Comment element.
1973         */
1974         while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1975           GetMagickToken(q,&q,token);
1976         continue;
1977       }
1978     if (LocaleCompare(keyword,"<include") == 0)
1979       {
1980         /*
1981           Include element.
1982         */
1983         while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1984         {
1985           (void) CopyMagickString(keyword,token,MaxTextExtent);
1986           GetMagickToken(q,&q,token);
1987           if (*token != '=')
1988             continue;
1989           GetMagickToken(q,&q,token);
1990           if (LocaleCompare(keyword,"file") == 0)
1991             {
1992               if (depth > 200)
1993                 (void) ThrowMagickException(exception,GetMagickModule(),
1994                   ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1995               else
1996                 {
1997                   char
1998                     path[MaxTextExtent],
1999                     *xml;
2000
2001                   GetPathComponent(filename,HeadPath,path);
2002                   if (*path != '\0')
2003                     (void) ConcatenateMagickString(path,DirectorySeparator,
2004                       MaxTextExtent);
2005                   if (*token == *DirectorySeparator)
2006                     (void) CopyMagickString(path,token,MaxTextExtent);
2007                   else
2008                     (void) ConcatenateMagickString(path,token,MaxTextExtent);
2009                   xml=FileToString(path,~0,exception);
2010                   if (xml != (char *) NULL)
2011                     {
2012                       status=LoadColorList(xml,path,depth+1,exception);
2013                       xml=(char *) RelinquishMagickMemory(xml);
2014                     }
2015                 }
2016             }
2017         }
2018         continue;
2019       }
2020     if (LocaleCompare(keyword,"<color") == 0)
2021       {
2022         /*
2023           Color element.
2024         */
2025         color_info=(ColorInfo *) AcquireMagickMemory(sizeof(*color_info));
2026         if (color_info == (ColorInfo *) NULL)
2027           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
2028         (void) ResetMagickMemory(color_info,0,sizeof(*color_info));
2029         color_info->path=ConstantString(filename);
2030         color_info->exempt=MagickFalse;
2031         color_info->signature=MagickSignature;
2032         continue;
2033       }
2034     if (color_info == (ColorInfo *) NULL)
2035       continue;
2036     if (LocaleCompare(keyword,"/>") == 0)
2037       {
2038         status=AppendValueToLinkedList(color_list,color_info);
2039         if (status == MagickFalse)
2040           (void) ThrowMagickException(exception,GetMagickModule(),
2041             ResourceLimitError,"MemoryAllocationFailed","`%s'",
2042             color_info->name);
2043         color_info=(ColorInfo *) NULL;
2044       }
2045     GetMagickToken(q,(const char **) NULL,token);
2046     if (*token != '=')
2047       continue;
2048     GetMagickToken(q,&q,token);
2049     GetMagickToken(q,&q,token);
2050     switch (*keyword)
2051     {
2052       case 'C':
2053       case 'c':
2054       {
2055         if (LocaleCompare((char *) keyword,"color") == 0)
2056           {
2057             (void) QueryMagickColor(token,&color_info->color,exception);
2058             break;
2059           }
2060         if (LocaleCompare((char *) keyword,"compliance") == 0)
2061           {
2062             long
2063               compliance;
2064
2065             compliance=color_info->compliance;
2066             if (GlobExpression(token,"*SVG*",MagickTrue) != MagickFalse)
2067               compliance|=SVGCompliance;
2068             if (GlobExpression(token,"*X11*",MagickTrue) != MagickFalse)
2069               compliance|=X11Compliance;
2070             if (GlobExpression(token,"*XPM*",MagickTrue) != MagickFalse)
2071               compliance|=XPMCompliance;
2072             color_info->compliance=(ComplianceType) compliance;
2073             break;
2074           }
2075         break;
2076       }
2077       case 'N':
2078       case 'n':
2079       {
2080         if (LocaleCompare((char *) keyword,"name") == 0)
2081           {
2082             color_info->name=ConstantString(token);
2083             break;
2084           }
2085         break;
2086       }
2087       case 'S':
2088       case 's':
2089       {
2090         if (LocaleCompare((char *) keyword,"stealth") == 0)
2091           {
2092             color_info->stealth=IsMagickTrue(token);
2093             break;
2094           }
2095         break;
2096       }
2097       default:
2098         break;
2099     }
2100   }
2101   token=(char *) RelinquishMagickMemory(token);
2102   return(status);
2103 }
2104 \f
2105 /*
2106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2107 %                                                                             %
2108 %                                                                             %
2109 %                                                                             %
2110 %  L o a d C o l o r L i s t s                                                %
2111 %                                                                             %
2112 %                                                                             %
2113 %                                                                             %
2114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2115 %
2116 %  LoadColorList() loads one or more color configuration file which provides a
2117 %  mapping between color attributes and a color name.
2118 %
2119 %  The format of the LoadColorLists method is:
2120 %
2121 %      MagickBooleanType LoadColorLists(const char *filename,
2122 %        ExceptionInfo *exception)
2123 %
2124 %  A description of each parameter follows:
2125 %
2126 %    o filename: the font file name.
2127 %
2128 %    o exception: return any errors or warnings in this structure.
2129 %
2130 */
2131 static MagickBooleanType LoadColorLists(const char *filename,
2132   ExceptionInfo *exception)
2133 {
2134   const StringInfo
2135     *option;
2136
2137   LinkedListInfo
2138     *options;
2139
2140   MagickRealType
2141     scale;
2142
2143   MagickStatusType
2144     status;
2145
2146   register const ColorMapInfo
2147     *p;
2148
2149   /*
2150     Load built-in color map.
2151   */
2152   status=MagickFalse;
2153   if (color_list == (LinkedListInfo *) NULL)
2154     {
2155       color_list=NewLinkedList(0);
2156       if (color_list == (LinkedListInfo *) NULL)
2157         {
2158           ThrowFileException(exception,ResourceLimitError,
2159             "MemoryAllocationFailed",filename);
2160           return(MagickFalse);
2161         }
2162     }
2163   scale=(MagickRealType) ScaleCharToQuantum(1);
2164   for (p=ColorMap; p->name != (const char *) NULL; p++)
2165   {
2166     ColorInfo
2167       *color_info;
2168
2169     color_info=(ColorInfo *) AcquireMagickMemory(sizeof(*color_info));
2170     if (color_info == (ColorInfo *) NULL)
2171       {
2172         (void) ThrowMagickException(exception,GetMagickModule(),
2173           ResourceLimitError,"MemoryAllocationFailed","`%s'",color_info->name);
2174         continue;
2175       }
2176     (void) ResetMagickMemory(color_info,0,sizeof(*color_info));
2177     color_info->path=(char *) "[built-in]";
2178     color_info->name=(char *) p->name;
2179     GetMagickPixelPacket((Image *) NULL,&color_info->color);
2180     color_info->color.red=scale*p->red;
2181     color_info->color.green=scale*p->green;
2182     color_info->color.blue=scale*p->blue;
2183     color_info->color.opacity=(MagickRealType) (QuantumRange-QuantumRange*
2184       p->alpha);
2185     color_info->compliance=(ComplianceType) p->compliance;
2186     color_info->exempt=MagickTrue;
2187     color_info->signature=MagickSignature;
2188     status=AppendValueToLinkedList(color_list,color_info);
2189     if (status == MagickFalse)
2190       (void) ThrowMagickException(exception,GetMagickModule(),
2191         ResourceLimitError,"MemoryAllocationFailed","`%s'",color_info->name);
2192   }
2193   /*
2194     Load external color map.
2195   */
2196   options=GetConfigureOptions(filename,exception);
2197   option=(const StringInfo *) GetNextValueInLinkedList(options);
2198   while (option != (const StringInfo *) NULL)
2199   {
2200     status|=LoadColorList((const char *) GetStringInfoDatum(option),
2201       GetStringInfoPath(option),0,exception);
2202     option=(const StringInfo *) GetNextValueInLinkedList(options);
2203   }
2204   options=DestroyConfigureOptions(options);
2205   return(status != 0 ? MagickTrue : MagickFalse);
2206 }
2207 \f
2208 /*
2209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2210 %                                                                             %
2211 %                                                                             %
2212 %                                                                             %
2213 %   Q u e r y C o l o r D a t a b a s e                                       %
2214 %                                                                             %
2215 %                                                                             %
2216 %                                                                             %
2217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2218 %
2219 %  QueryColorDatabase() returns the red, green, blue, and opacity intensities
2220 %  for a given color name.
2221 %
2222 %  The format of the QueryColorDatabase method is:
2223 %
2224 %      MagickBooleanType QueryColorDatabase(const char *name,PixelPacket *color,
2225 %        ExceptionInfo *exception)
2226 %
2227 %  A description of each parameter follows:
2228 %
2229 %    o name: the color name (e.g. white, blue, yellow).
2230 %
2231 %    o color: the red, green, blue, and opacity intensities values of the
2232 %      named color in this structure.
2233 %
2234 %    o exception: return any errors or warnings in this structure.
2235 %
2236 */
2237
2238 static inline double MagickMin(const double x,const double y)
2239 {
2240   if (x < y)
2241     return(x);
2242   return(y);
2243 }
2244
2245 MagickExport MagickBooleanType QueryColorDatabase(const char *name,
2246   PixelPacket *color,ExceptionInfo *exception)
2247 {
2248   MagickBooleanType
2249     status;
2250
2251   MagickPixelPacket
2252     pixel;
2253
2254   status=QueryMagickColor(name,&pixel,exception);
2255   color->opacity=RoundToQuantum(pixel.opacity);
2256   if (pixel.colorspace == CMYKColorspace)
2257     {
2258       color->red=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
2259         QuantumRange,(MagickRealType) (QuantumScale*pixel.red*(QuantumRange-
2260         pixel.index)+pixel.index))));
2261       color->green=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
2262         QuantumRange,(MagickRealType) (QuantumScale*pixel.green*(QuantumRange-
2263         pixel.index)+pixel.index))));
2264       color->blue=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
2265         QuantumRange,(MagickRealType) (QuantumScale*pixel.blue*(QuantumRange-
2266         pixel.index)+pixel.index))));
2267       return(status);
2268     }
2269   color->red=RoundToQuantum(pixel.red);
2270   color->green=RoundToQuantum(pixel.green);
2271   color->blue=RoundToQuantum(pixel.blue);
2272   return(status);
2273 }
2274 \f
2275 /*
2276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2277 %                                                                             %
2278 %                                                                             %
2279 %                                                                             %
2280 %  Q u e r y C o l o r n a m e                                                %
2281 %                                                                             %
2282 %                                                                             %
2283 %                                                                             %
2284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2285 %
2286 %  QueryColorname() returns a named color for the given color intensity.  If
2287 %  an exact match is not found, a rgb() color is returned instead.
2288 %
2289 %  The format of the QueryColorname method is:
2290 %
2291 %      MagickBooleanType QueryColorname(const Image *image,
2292 %        const PixelPacket *color,const ComplianceType compliance,char *name,
2293 %        ExceptionInfo *exception)
2294 %
2295 %  A description of each parameter follows.
2296 %
2297 %    o image: the image.
2298 %
2299 %    o color: the color intensities.
2300 %
2301 %    o compliance: Adhere to this color standard: SVG, X11, or XPM.
2302 %
2303 %    o name: Return the color name or hex value.
2304 %
2305 %    o exception: return any errors or warnings in this structure.
2306 %
2307 */
2308 MagickExport MagickBooleanType QueryColorname(const Image *image,
2309   const PixelPacket *color,const ComplianceType compliance,char *name,
2310   ExceptionInfo *exception)
2311 {
2312   MagickPixelPacket
2313     pixel;
2314
2315   GetMagickPixelPacket(image,&pixel);
2316   SetMagickPixelPacket(image,color,(IndexPacket *) NULL,&pixel);
2317   return(QueryMagickColorname(image,&pixel,compliance,name,exception));
2318 }
2319 \f
2320 /*
2321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2322 %                                                                             %
2323 %                                                                             %
2324 %                                                                             %
2325 %   Q u e r y M a g i c k C o l o r                                           %
2326 %                                                                             %
2327 %                                                                             %
2328 %                                                                             %
2329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2330 %
2331 %  QueryMagickColor() returns the red, green, blue, and opacity intensities
2332 %  for a given color name.
2333 %
2334 %  The format of the QueryMagickColor method is:
2335 %
2336 %      MagickBooleanType QueryMagickColor(const char *name,
2337 %        MagickPixelPacket *color,ExceptionInfo *exception)
2338 %
2339 %  A description of each parameter follows:
2340 %
2341 %    o name: the color name (e.g. white, blue, yellow).
2342 %
2343 %    o color: the red, green, blue, and opacity intensities values of the
2344 %      named color in this structure.
2345 %
2346 %    o exception: return any errors or warnings in this structure.
2347 %
2348 */
2349 MagickExport MagickBooleanType QueryMagickColor(const char *name,
2350   MagickPixelPacket *color,ExceptionInfo *exception)
2351 {
2352   GeometryInfo
2353     geometry_info;
2354
2355   long
2356     type;
2357
2358   MagickRealType
2359     scale;
2360
2361   MagickStatusType
2362     flags;
2363
2364   register const ColorInfo
2365     *p;
2366
2367   register long
2368     i;
2369
2370   /*
2371     Initialize color return value.
2372   */
2373   assert(name != (const char *) NULL);
2374   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
2375   assert(color != (MagickPixelPacket *) NULL);
2376   GetMagickPixelPacket((Image *) NULL,color);
2377   if ((name == (char *) NULL) || (*name == '\0'))
2378     name=BackgroundColor;
2379   while (isspace((int) ((unsigned char) *name)) != 0)
2380     name++;
2381   if (*name == '#')
2382     {
2383       char
2384         c;
2385
2386       LongPixelPacket
2387         pixel;
2388
2389       QuantumAny
2390         range;
2391
2392       unsigned long
2393         depth,
2394         n;
2395
2396       /*
2397         Parse hex color.
2398       */
2399       (void) ResetMagickMemory(&pixel,0,sizeof(pixel));
2400       name++;
2401       for (n=0; isxdigit((int) ((unsigned char) name[n])) != MagickFalse; n++) ;
2402       if ((n % 3) == 0)
2403         {
2404           do
2405           {
2406             pixel.red=pixel.green;
2407             pixel.green=pixel.blue;
2408             pixel.blue=0;
2409             for (i=(long) (n/3-1); i >= 0; i--)
2410             {
2411               c=(*name++);
2412               pixel.blue<<=4;
2413               if ((c >= '0') && (c <= '9'))
2414                 pixel.blue|=(int) (c-'0');
2415               else
2416                 if ((c >= 'A') && (c <= 'F'))
2417                   pixel.blue|=(int) c-((int) 'A'-10);
2418                 else
2419                   if ((c >= 'a') && (c <= 'f'))
2420                     pixel.blue|=(int) c-((int) 'a'-10);
2421                   else
2422                     return(MagickFalse);
2423             }
2424           } while (isxdigit((int) ((unsigned char) *name)) != MagickFalse);
2425           depth=4*(n/3);
2426         }
2427       else
2428         {
2429           if ((n % 4) != 0)
2430             {
2431               (void) ThrowMagickException(exception,GetMagickModule(),
2432                 OptionWarning,"UnrecognizedColor","`%s'",name);
2433               return(MagickFalse);
2434             }
2435           do
2436           {
2437             pixel.red=pixel.green;
2438             pixel.green=pixel.blue;
2439             pixel.blue=pixel.opacity;
2440             pixel.opacity=0;
2441             for (i=(long) (n/4-1); i >= 0; i--)
2442             {
2443               c=(*name++);
2444               pixel.opacity<<=4;
2445               if ((c >= '0') && (c <= '9'))
2446                 pixel.opacity|=(int) (c-'0');
2447               else
2448                 if ((c >= 'A') && (c <= 'F'))
2449                   pixel.opacity|=(int) c-((int) 'A'-10);
2450                 else
2451                   if ((c >= 'a') && (c <= 'f'))
2452                     pixel.opacity|=(int) c-((int) 'a'-10);
2453                   else
2454                     return(MagickFalse);
2455             }
2456           } while (isxdigit((int) ((unsigned char) *name)) != MagickFalse);
2457           depth=4*(n/4);
2458         }
2459       color->colorspace=RGBColorspace;
2460       color->matte=MagickFalse;
2461       range=GetQuantumRange(depth);
2462       color->red=(MagickRealType) ScaleAnyToQuantum(pixel.red,range);
2463       color->green=(MagickRealType) ScaleAnyToQuantum(pixel.green,range);
2464       color->blue=(MagickRealType) ScaleAnyToQuantum(pixel.blue,range);
2465       color->opacity=(MagickRealType) OpaqueOpacity;
2466       if ((n % 3) != 0)
2467         {
2468           color->matte=MagickTrue;
2469           color->opacity=(MagickRealType) (QuantumRange-ScaleAnyToQuantum(
2470             pixel.opacity,range));
2471         }
2472       color->index=0.0;
2473       return(MagickTrue);
2474     }
2475   if (strchr(name,'(') != (char *) NULL)
2476     {
2477       char
2478         colorspace[MaxTextExtent];
2479
2480       /*
2481         Parse color of the form rgb(100,255,0).
2482       */
2483       (void) CopyMagickString(colorspace,name,MaxTextExtent);
2484       for (i=0; colorspace[i] != '\0'; i++)
2485         if (colorspace[i] == '(')
2486           break;
2487       colorspace[i--]='\0';
2488       LocaleLower(colorspace);
2489       color->matte=MagickFalse;
2490       if ((i > 0) && (colorspace[i] == 'a'))
2491         {
2492           colorspace[i]='\0';
2493           color->matte=MagickTrue;
2494         }
2495       type=ParseMagickOption(MagickColorspaceOptions,MagickFalse,colorspace);
2496       if (type < 0)
2497         {
2498           (void) ThrowMagickException(exception,GetMagickModule(),
2499             OptionWarning,"UnrecognizedColor","`%s'",name);
2500           return(MagickFalse);
2501         }
2502       color->colorspace=(ColorspaceType) type;
2503       SetGeometryInfo(&geometry_info);
2504       flags=ParseGeometry(name+i+1,&geometry_info);
2505       scale=(MagickRealType) ScaleCharToQuantum(1);
2506       if ((flags & PercentValue) != 0)
2507         scale=(MagickRealType) (QuantumRange/100.0);
2508       if ((flags & RhoValue) != 0)
2509         color->red=(MagickRealType) RoundToQuantum(scale*geometry_info.rho);
2510       if ((flags & SigmaValue) != 0)
2511         color->green=(MagickRealType) RoundToQuantum(scale*geometry_info.sigma);
2512       if ((flags & XiValue) != 0)
2513         color->blue=(MagickRealType) RoundToQuantum(scale*geometry_info.xi);
2514       color->opacity=(MagickRealType) OpaqueOpacity;
2515       if ((flags & PsiValue) != 0)
2516         {
2517           if (color->colorspace == CMYKColorspace)
2518             color->index=(MagickRealType) RoundToQuantum(scale*
2519               geometry_info.psi);
2520           else
2521             if (color->matte != MagickFalse)
2522               color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
2523                 (QuantumRange-QuantumRange*geometry_info.psi));
2524         }
2525       if (((flags & ChiValue) != 0) && (color->matte != MagickFalse))
2526         color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
2527           (QuantumRange-QuantumRange*geometry_info.chi));
2528       if (LocaleCompare(colorspace,"gray") == 0)
2529         {
2530           color->green=color->red;
2531           color->blue=color->red;
2532           if (((flags & SigmaValue) != 0) && (color->matte != MagickFalse))
2533             color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
2534               (QuantumRange-QuantumRange*geometry_info.sigma));
2535         }
2536       if ((LocaleCompare(colorspace,"HSB") == 0) ||
2537           (LocaleCompare(colorspace,"HSL") == 0) ||
2538           (LocaleCompare(colorspace,"HWB") == 0))
2539         {
2540           PixelPacket
2541             pixel;
2542
2543           scale=1.0/360.0;
2544           if ((flags & PercentValue) != 0)
2545             scale=1.0/100.0;
2546           geometry_info.rho*=360.0*scale;
2547           scale=1.0/255.0;
2548           if ((flags & PercentValue) != 0)
2549             scale=1.0/100.0;
2550           geometry_info.sigma*=scale;
2551           geometry_info.xi*=scale;
2552           if (LocaleCompare(colorspace,"HSB") == 0)
2553             ConvertHSBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
2554               360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
2555               &pixel.green,&pixel.blue);
2556           else
2557             if (LocaleCompare(colorspace,"HSL") == 0)
2558               ConvertHSLToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
2559                 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
2560                 &pixel.green,&pixel.blue);
2561             else
2562               ConvertHWBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
2563                 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
2564                 &pixel.green,&pixel.blue);
2565           color->colorspace=RGBColorspace;
2566           color->red=(MagickRealType) pixel.red;
2567           color->green=(MagickRealType) pixel.green;
2568           color->blue=(MagickRealType) pixel.blue;
2569         }
2570       return(MagickTrue);
2571     }
2572   /*
2573     Parse named color.
2574   */
2575   p=GetColorInfo(name,exception);
2576   if (p == (const ColorInfo *) NULL)
2577     return(MagickFalse);
2578   color->colorspace=RGBColorspace;
2579   color->matte=p->color.opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
2580   color->red=(MagickRealType) p->color.red;
2581   color->green=(MagickRealType) p->color.green;
2582   color->blue=(MagickRealType) p->color.blue;
2583   color->opacity=(MagickRealType) p->color.opacity;
2584   color->index=0.0;
2585   return(MagickTrue);
2586 }
2587 \f
2588 /*
2589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2590 %                                                                             %
2591 %                                                                             %
2592 %                                                                             %
2593 %  Q u e r y M a g i c k C o l o r n a m e                                    %
2594 %                                                                             %
2595 %                                                                             %
2596 %                                                                             %
2597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2598 %
2599 %  QueryMagickColorname() returns a named color for the given color intensity.
2600 %  If an exact match is not found, a hex value is returned instead.  For
2601 %  example an intensity of rgb:(0,0,0) returns black whereas rgb:(223,223,223)
2602 %  returns #dfdfdf.
2603 %
2604 %  The format of the QueryMagickColorname method is:
2605 %
2606 %      MagickBooleanType QueryMagickColorname(const Image *image,
2607 %        const PixelPacket *color,const ComplianceType compliance,char *name,
2608 %        ExceptionInfo *exception)
2609 %
2610 %  A description of each parameter follows.
2611 %
2612 %    o image: the image.
2613 %
2614 %    o color: the color intensities.
2615 %
2616 %    o Compliance: Adhere to this color standard: SVG, X11, or XPM.
2617 %
2618 %    o name: Return the color name or hex value.
2619 %
2620 %    o exception: return any errors or warnings in this structure.
2621 %
2622 */
2623 MagickExport MagickBooleanType QueryMagickColorname(const Image *image,
2624   const MagickPixelPacket *color,const ComplianceType compliance,
2625   char *name,ExceptionInfo *exception)
2626 {
2627   MagickPixelPacket
2628     pixel;
2629
2630   MagickRealType
2631     opacity;
2632
2633   register const ColorInfo
2634     *p;
2635
2636   *name='\0';
2637   pixel=(*color);
2638   if (compliance == XPMCompliance)
2639     {
2640       pixel.matte=MagickFalse;
2641       pixel.depth=(unsigned long) MagickMin(1.0*image->depth,16.0);
2642       GetColorTuple(&pixel,MagickTrue,name);
2643       return(MagickTrue);
2644     }
2645   GetColorTuple(&pixel,compliance != SVGCompliance ? MagickTrue : MagickFalse,
2646     name);
2647   (void) GetColorInfo("*",exception);
2648   ResetLinkedListIterator(color_list);
2649   opacity=image->matte != MagickFalse ? color->opacity : OpaqueOpacity;
2650   p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
2651   while (p != (const ColorInfo *) NULL)
2652   {
2653     if (((p->compliance & compliance) != 0) && ((p->color.red == color->red)) &&
2654          (p->color.green == color->green) && (p->color.blue == color->blue) &&
2655          (p->color.opacity == opacity))
2656       {
2657         (void) CopyMagickString(name,p->name,MaxTextExtent);
2658         break;
2659       }
2660     p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
2661   }
2662   return(MagickTrue);
2663 }