]> 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 L i s t                                           %
912 %                                                                             %
913 %                                                                             %
914 %                                                                             %
915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
916 %
917 %  DestroyColorList() deallocates memory associated with the color list.
918 %
919 %  The format of the DestroyColorList method is:
920 %
921 %      DestroyColorList(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 DestroyColorList(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 s C o l o r S i m i l a r                                               %
1440 %                                                                             %
1441 %                                                                             %
1442 %                                                                             %
1443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1444 %
1445 %  IsColorSimilar() returns MagickTrue if the distance between two colors is
1446 %  less than the specified distance in a linear three dimensional color space.
1447 %  This method is used by ColorFloodFill() and other algorithms which
1448 %  compare two colors.
1449 %
1450 %  The format of the IsColorSimilar method is:
1451 %
1452 %      void IsColorSimilar(const Image *image,const PixelPacket *p,
1453 %        const PixelPacket *q)
1454 %
1455 %  A description of each parameter follows:
1456 %
1457 %    o image: the image.
1458 %
1459 %    o p: Pixel p.
1460 %
1461 %    o q: Pixel q.
1462 %
1463 */
1464
1465 static inline double MagickMax(const double x,const double y)
1466 {
1467   if (x > y)
1468     return(x);
1469   return(y);
1470 }
1471
1472 MagickExport MagickBooleanType IsColorSimilar(const Image *image,
1473   const PixelPacket *p,const PixelPacket *q)
1474 {
1475   MagickRealType
1476     fuzz,
1477     pixel;
1478
1479   register MagickRealType
1480     alpha,
1481     beta,
1482     distance;
1483
1484   if ((image->fuzz == 0.0) && (image->matte == MagickFalse))
1485     return(IsColorEqual(p,q));
1486   fuzz=3.0*MagickMax(image->fuzz,MagickSQ1_2)*MagickMax(image->fuzz,
1487     MagickSQ1_2);
1488   alpha=1.0;
1489   beta=1.0;
1490   if (image->matte != MagickFalse)
1491     {
1492       alpha=(MagickRealType) (QuantumScale*(QuantumRange-p->opacity));
1493       beta=(MagickRealType) (QuantumScale*(QuantumRange-q->opacity));
1494     }
1495   pixel=alpha*p->red-beta*q->red;
1496   distance=pixel*pixel;
1497   if (distance > fuzz)
1498     return(MagickFalse);
1499   pixel=alpha*p->green-beta*q->green;
1500   distance+=pixel*pixel;
1501   if (distance > fuzz)
1502     return(MagickFalse);
1503   pixel=alpha*p->blue-beta*q->blue;
1504   distance+=pixel*pixel;
1505   if (distance > fuzz)
1506     return(MagickFalse);
1507   return(MagickTrue);
1508 }
1509 \f
1510 /*
1511 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1512 %                                                                             %
1513 %                                                                             %
1514 %                                                                             %
1515 +   I s I m a g e S i m i l a r                                               %
1516 %                                                                             %
1517 %                                                                             %
1518 %                                                                             %
1519 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1520 %
1521 %  IsImageSimilar() returns true if the target is similar to a region of the
1522 %  image.
1523 %
1524 %  The format of the IsImageSimilar method is:
1525 %
1526 %      MagickBooleanType IsImageSimilar(const Image *image,
1527 %        const Image *target_image,long *x_offset,long *y_offset,
1528 %        ExceptionInfo *exception)
1529 %
1530 %  A description of each parameter follows:
1531 %
1532 %    o image: the image.
1533 %
1534 %    o target_image: the target image.
1535 %
1536 %    o x_offset: On input the starting x position to search for a match;
1537 %      on output the x position of the first match found.
1538 %
1539 %    o y_offset: On input the starting y position to search for a match;
1540 %      on output the y position of the first match found.
1541 %
1542 %    o exception: return any errors or warnings in this structure.
1543 %
1544 */
1545 MagickExport MagickBooleanType IsImageSimilar(const Image *image,
1546   const Image *target_image,long *x_offset,long *y_offset,
1547   ExceptionInfo *exception)
1548 {
1549 #define SearchImageText  "  Searching image...  "
1550
1551   long
1552     j,
1553     y;
1554
1555   MagickBooleanType
1556     status;
1557
1558   MagickPixelPacket
1559     target,
1560     pixel;
1561
1562   register const PixelPacket
1563     *p,
1564     *q;
1565
1566   register const IndexPacket
1567     *indexes,
1568     *target_indexes;
1569
1570   register long
1571     i,
1572     x;
1573
1574   CacheView
1575     *image_view,
1576     *target_view;
1577
1578   assert(image != (Image *) NULL);
1579   assert(image->signature == MagickSignature);
1580   if (image->debug != MagickFalse)
1581     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1582   assert(target_image != (Image *) NULL);
1583   assert(target_image->signature == MagickSignature);
1584   assert(x_offset != (long *) NULL);
1585   assert(y_offset != (long *) NULL);
1586   assert(exception != (ExceptionInfo *) NULL);
1587   x=0;
1588   GetMagickPixelPacket(image,&pixel);
1589   GetMagickPixelPacket(image,&target);
1590   image_view=AcquireCacheView(image);
1591   target_view=AcquireCacheView(target_image);
1592   for (y=(*y_offset); y < (long) image->rows; y++)
1593   {
1594     for (x=y == 0 ? *x_offset : 0; x < (long) image->columns; x++)
1595     {
1596       for (j=0; j < (long) target_image->rows; j++)
1597       {
1598         for (i=0; i < (long) target_image->columns; i++)
1599         {
1600           p=GetCacheViewVirtualPixels(image_view,x+i,y+j,1,1,exception);
1601           indexes=GetCacheViewVirtualIndexQueue(image_view);
1602           SetMagickPixelPacket(image,p,indexes,&pixel);
1603           q=GetCacheViewVirtualPixels(target_view,i,j,1,1,exception);
1604           target_indexes=GetCacheViewVirtualIndexQueue(target_view);
1605           SetMagickPixelPacket(image,q,target_indexes,&target);
1606           if (IsMagickColorSimilar(&pixel,&target) == MagickFalse)
1607             break;
1608         }
1609         if (i < (long) target_image->columns)
1610           break;
1611       }
1612       if (j == (long) target_image->rows)
1613         break;
1614     }
1615     if (x < (long) image->columns)
1616       break;
1617     if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1618         (QuantumTick(y,image->rows) != MagickFalse))
1619       {
1620         status=image->progress_monitor(SearchImageText,y,image->rows,
1621           image->client_data);
1622         if (status == MagickFalse)
1623           break;
1624       }
1625   }
1626   target_view=DestroyCacheView(target_view);
1627   image_view=DestroyCacheView(image_view);
1628   *x_offset=x;
1629   *y_offset=y;
1630   return(y < (long) image->rows ? MagickTrue : MagickFalse);
1631 }
1632 \f
1633 /*
1634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1635 %                                                                             %
1636 %                                                                             %
1637 %                                                                             %
1638 +   I s M a g i c k C o l o r S i m i l a r                                   %
1639 %                                                                             %
1640 %                                                                             %
1641 %                                                                             %
1642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1643 %
1644 %  IsMagickColorSimilar() returns true if the distance between two colors is
1645 %  less than the specified distance in a linear three dimensional color space.
1646 %  This method is used by ColorFloodFill() and other algorithms which
1647 %  compare two colors.
1648 %
1649 %  The format of the IsMagickColorSimilar method is:
1650 %
1651 %      MagickBooleanType IsMagickColorSimilar(const MagickPixelPacket *p,
1652 %        const MagickPixelPacket *q)
1653 %
1654 %  A description of each parameter follows:
1655 %
1656 %    o p: Pixel p.
1657 %
1658 %    o q: Pixel q.
1659 %
1660 */
1661 MagickExport MagickBooleanType IsMagickColorSimilar(const MagickPixelPacket *p,
1662   const MagickPixelPacket *q)
1663 {
1664   MagickRealType
1665     fuzz,
1666     pixel;
1667
1668   register MagickRealType
1669     alpha,
1670     beta,
1671     distance;
1672
1673   if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
1674     return(IsMagickColorEqual(p,q));
1675   if (p->fuzz == 0.0)
1676     fuzz=MagickMax(q->fuzz,MagickSQ1_2)*MagickMax(q->fuzz,MagickSQ1_2);
1677   else
1678     if (q->fuzz == 0.0)
1679       fuzz=3.0*MagickMax(p->fuzz,MagickSQ1_2)*MagickMax(p->fuzz,MagickSQ1_2);
1680     else
1681       fuzz=3.0*MagickMax(p->fuzz,MagickSQ1_2)*MagickMax(q->fuzz,MagickSQ1_2);
1682   alpha=1.0;
1683   if (p->matte != MagickFalse)
1684     alpha=(MagickRealType) (QuantumScale*(QuantumRange-p->opacity));
1685   beta=1.0;
1686   if (q->matte != MagickFalse)
1687     beta=(MagickRealType) (QuantumScale*(QuantumRange-q->opacity));
1688   if (p->colorspace == CMYKColorspace)
1689     {
1690       alpha*=(MagickRealType) (QuantumScale*(QuantumRange-p->index));
1691       beta*=(MagickRealType) (QuantumScale*(QuantumRange-q->index));
1692     }
1693   pixel=alpha*p->red-beta*q->red;
1694   if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
1695       (p->colorspace == HWBColorspace))
1696     {
1697       if (fabs(p->red-q->red) > (QuantumRange/2))
1698         {
1699           if (p->red > (QuantumRange/2))
1700             pixel=alpha*(p->red-QuantumRange)-beta*q->red;
1701           else
1702             pixel=alpha*p->red-beta*(q->red-QuantumRange);
1703         }
1704         pixel*=2;
1705      }
1706   distance=pixel*pixel;
1707   if (distance > fuzz)
1708     return(MagickFalse);
1709   pixel=alpha*p->green-beta*q->green;
1710   distance+=pixel*pixel;
1711   if (distance > fuzz)
1712     return(MagickFalse);
1713   pixel=alpha*p->blue-beta*q->blue;
1714   distance+=pixel*pixel;
1715   if (distance > fuzz)
1716     return(MagickFalse);
1717   pixel=p->opacity-q->opacity;
1718   distance+=pixel*pixel;
1719   if (distance > fuzz)
1720     return(MagickFalse);
1721   return(MagickTrue);
1722 }
1723 \f
1724 /*
1725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1726 %                                                                             %
1727 %                                                                             %
1728 %                                                                             %
1729 +   I s O p a c i t y S i m i l a r                                           %
1730 %                                                                             %
1731 %                                                                             %
1732 %                                                                             %
1733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1734 %
1735 %  IsOpacitySimilar() returns true if the distance between two opacity
1736 %  values is less than the specified distance in a linear color space.  This
1737 %  method is used by MatteFloodFill() and other algorithms which compare
1738 %  two opacity values.
1739 %
1740 %  The format of the IsOpacitySimilar method is:
1741 %
1742 %      void IsOpacitySimilar(const Image *image,const PixelPacket *p,
1743 %        const PixelPacket *q)
1744 %
1745 %  A description of each parameter follows:
1746 %
1747 %    o image: the image.
1748 %
1749 %    o p: Pixel p.
1750 %
1751 %    o q: Pixel q.
1752 %
1753 */
1754 MagickExport MagickBooleanType IsOpacitySimilar(const Image *image,
1755   const PixelPacket *p,const PixelPacket *q)
1756 {
1757   MagickRealType
1758     fuzz,
1759     pixel;
1760
1761   register MagickRealType
1762     distance;
1763
1764   if (image->matte == MagickFalse)
1765     return(MagickTrue);
1766   if (p->opacity == q->opacity)
1767     return(MagickTrue);
1768   fuzz=MagickMax(image->fuzz,MagickSQ1_2)*MagickMax(image->fuzz,MagickSQ1_2);
1769   pixel=(MagickRealType) p->opacity-(MagickRealType) q->opacity;
1770   distance=pixel*pixel;
1771   if (distance > fuzz)
1772     return(MagickFalse);
1773   return(MagickTrue);
1774 }
1775 \f
1776 /*
1777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1778 %                                                                             %
1779 %                                                                             %
1780 %                                                                             %
1781 %  L i s t C o l o r I n f o                                                  %
1782 %                                                                             %
1783 %                                                                             %
1784 %                                                                             %
1785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1786 %
1787 %  ListColorInfo() lists color names to the specified file.  Color names
1788 %  are a convenience.  Rather than defining a color by its red, green, and
1789 %  blue intensities just use a color name such as white, blue, or yellow.
1790 %
1791 %  The format of the ListColorInfo method is:
1792 %
1793 %      MagickBooleanType ListColorInfo(FILE *file,ExceptionInfo *exception)
1794 %
1795 %  A description of each parameter follows.
1796 %
1797 %    o file:  List color names to this file handle.
1798 %
1799 %    o exception: return any errors or warnings in this structure.
1800 %
1801 */
1802 MagickExport MagickBooleanType ListColorInfo(FILE *file,
1803   ExceptionInfo *exception)
1804 {
1805   char
1806     tuple[MaxTextExtent];
1807
1808   const char
1809     *path;
1810
1811   const ColorInfo
1812     **color_info;
1813
1814   register long
1815     i;
1816
1817   unsigned long
1818     number_colors;
1819
1820   /*
1821     List name and attributes of each color in the list.
1822   */
1823   if (file == (const FILE *) NULL)
1824     file=stdout;
1825   color_info=GetColorInfoList("*",&number_colors,exception);
1826   if (color_info == (const ColorInfo **) NULL)
1827     return(MagickFalse);
1828   path=(const char *) NULL;
1829   for (i=0; i < (long) number_colors; i++)
1830   {
1831     if (color_info[i]->stealth != MagickFalse)
1832       continue;
1833     if ((path == (const char *) NULL) ||
1834         (LocaleCompare(path,color_info[i]->path) != 0))
1835       {
1836         if (color_info[i]->path != (char *) NULL)
1837           (void) fprintf(file,"\nPath: %s\n\n",color_info[i]->path);
1838         (void) fprintf(file,"Name                  Color                  "
1839           "                       Compliance\n");
1840         (void) fprintf(file,"-------------------------------------------------"
1841           "------------------------------\n");
1842       }
1843     path=color_info[i]->path;
1844     (void) fprintf(file,"%-21.21s ",color_info[i]->name);
1845     GetColorTuple(&color_info[i]->color,MagickFalse,tuple);
1846     (void) fprintf(file,"%-45.45s ",tuple);
1847     if ((color_info[i]->compliance & SVGCompliance) != 0)
1848       (void) fprintf(file,"SVG ");
1849     if ((color_info[i]->compliance & X11Compliance) != 0)
1850       (void) fprintf(file,"X11 ");
1851     if ((color_info[i]->compliance & XPMCompliance) != 0)
1852       (void) fprintf(file,"XPM ");
1853     (void) fprintf(file,"\n");
1854   }
1855   color_info=(const ColorInfo **) RelinquishMagickMemory((void *) color_info);
1856   (void) fflush(file);
1857   return(MagickTrue);
1858 }
1859 \f
1860 /*
1861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1862 %                                                                             %
1863 %                                                                             %
1864 %                                                                             %
1865 +   L o a d C o l o r L i s t                                                 %
1866 %                                                                             %
1867 %                                                                             %
1868 %                                                                             %
1869 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1870 %
1871 %  LoadColorList() loads the color configuration file which provides a mapping
1872 %  between color attributes and a color name.
1873 %
1874 %  The format of the LoadColorList method is:
1875 %
1876 %      MagickBooleanType LoadColorList(const char *xml,const char *filename,
1877 %        const unsigned long depth,ExceptionInfo *exception)
1878 %
1879 %  A description of each parameter follows:
1880 %
1881 %    o xml:  The color list in XML format.
1882 %
1883 %    o filename:  The color list filename.
1884 %
1885 %    o depth: depth of <include /> statements.
1886 %
1887 %    o exception: return any errors or warnings in this structure.
1888 %
1889 */
1890 static MagickBooleanType LoadColorList(const char *xml,const char *filename,
1891   const unsigned long depth,ExceptionInfo *exception)
1892 {
1893   char
1894     keyword[MaxTextExtent],
1895     *token;
1896
1897   ColorInfo
1898     *color_info;
1899
1900   const char
1901     *q;
1902
1903   MagickBooleanType
1904     status;
1905
1906   /*
1907     Load the color map file.
1908   */
1909   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1910     "Loading color file \"%s\" ...",filename);
1911   if (xml == (char *) NULL)
1912     return(MagickFalse);
1913   if (color_list == (LinkedListInfo *) NULL)
1914     {
1915       color_list=NewLinkedList(0);
1916       if (color_list == (LinkedListInfo *) NULL)
1917         {
1918           ThrowFileException(exception,ResourceLimitError,
1919             "MemoryAllocationFailed",filename);
1920           return(MagickFalse);
1921         }
1922     }
1923   status=MagickTrue;
1924   color_info=(ColorInfo *) NULL;
1925   token=AcquireString(xml);
1926   for (q=(char *) xml; *q != '\0'; )
1927   {
1928     /*
1929       Interpret XML.
1930     */
1931     GetMagickToken(q,&q,token);
1932     if (*token == '\0')
1933       break;
1934     (void) CopyMagickString(keyword,token,MaxTextExtent);
1935     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1936       {
1937         /*
1938           Doctype element.
1939         */
1940         while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1941           GetMagickToken(q,&q,token);
1942         continue;
1943       }
1944     if (LocaleNCompare(keyword,"<!--",4) == 0)
1945       {
1946         /*
1947           Comment element.
1948         */
1949         while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1950           GetMagickToken(q,&q,token);
1951         continue;
1952       }
1953     if (LocaleCompare(keyword,"<include") == 0)
1954       {
1955         /*
1956           Include element.
1957         */
1958         while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1959         {
1960           (void) CopyMagickString(keyword,token,MaxTextExtent);
1961           GetMagickToken(q,&q,token);
1962           if (*token != '=')
1963             continue;
1964           GetMagickToken(q,&q,token);
1965           if (LocaleCompare(keyword,"file") == 0)
1966             {
1967               if (depth > 200)
1968                 (void) ThrowMagickException(exception,GetMagickModule(),
1969                   ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1970               else
1971                 {
1972                   char
1973                     path[MaxTextExtent],
1974                     *xml;
1975
1976                   GetPathComponent(filename,HeadPath,path);
1977                   if (*path != '\0')
1978                     (void) ConcatenateMagickString(path,DirectorySeparator,
1979                       MaxTextExtent);
1980                   if (*token == *DirectorySeparator)
1981                     (void) CopyMagickString(path,token,MaxTextExtent);
1982                   else
1983                     (void) ConcatenateMagickString(path,token,MaxTextExtent);
1984                   xml=FileToString(path,~0,exception);
1985                   if (xml != (char *) NULL)
1986                     {
1987                       status=LoadColorList(xml,path,depth+1,exception);
1988                       xml=(char *) RelinquishMagickMemory(xml);
1989                     }
1990                 }
1991             }
1992         }
1993         continue;
1994       }
1995     if (LocaleCompare(keyword,"<color") == 0)
1996       {
1997         /*
1998           Color element.
1999         */
2000         color_info=(ColorInfo *) AcquireMagickMemory(sizeof(*color_info));
2001         if (color_info == (ColorInfo *) NULL)
2002           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
2003         (void) ResetMagickMemory(color_info,0,sizeof(*color_info));
2004         color_info->path=ConstantString(filename);
2005         color_info->exempt=MagickFalse;
2006         color_info->signature=MagickSignature;
2007         continue;
2008       }
2009     if (color_info == (ColorInfo *) NULL)
2010       continue;
2011     if (LocaleCompare(keyword,"/>") == 0)
2012       {
2013         status=AppendValueToLinkedList(color_list,color_info);
2014         if (status == MagickFalse)
2015           (void) ThrowMagickException(exception,GetMagickModule(),
2016             ResourceLimitError,"MemoryAllocationFailed","`%s'",
2017             color_info->name);
2018         color_info=(ColorInfo *) NULL;
2019       }
2020     GetMagickToken(q,(const char **) NULL,token);
2021     if (*token != '=')
2022       continue;
2023     GetMagickToken(q,&q,token);
2024     GetMagickToken(q,&q,token);
2025     switch (*keyword)
2026     {
2027       case 'C':
2028       case 'c':
2029       {
2030         if (LocaleCompare((char *) keyword,"color") == 0)
2031           {
2032             (void) QueryMagickColor(token,&color_info->color,exception);
2033             break;
2034           }
2035         if (LocaleCompare((char *) keyword,"compliance") == 0)
2036           {
2037             long
2038               compliance;
2039
2040             compliance=color_info->compliance;
2041             if (GlobExpression(token,"*SVG*",MagickTrue) != MagickFalse)
2042               compliance|=SVGCompliance;
2043             if (GlobExpression(token,"*X11*",MagickTrue) != MagickFalse)
2044               compliance|=X11Compliance;
2045             if (GlobExpression(token,"*XPM*",MagickTrue) != MagickFalse)
2046               compliance|=XPMCompliance;
2047             color_info->compliance=(ComplianceType) compliance;
2048             break;
2049           }
2050         break;
2051       }
2052       case 'N':
2053       case 'n':
2054       {
2055         if (LocaleCompare((char *) keyword,"name") == 0)
2056           {
2057             color_info->name=ConstantString(token);
2058             break;
2059           }
2060         break;
2061       }
2062       case 'S':
2063       case 's':
2064       {
2065         if (LocaleCompare((char *) keyword,"stealth") == 0)
2066           {
2067             color_info->stealth=IsMagickTrue(token);
2068             break;
2069           }
2070         break;
2071       }
2072       default:
2073         break;
2074     }
2075   }
2076   token=(char *) RelinquishMagickMemory(token);
2077   return(status);
2078 }
2079 \f
2080 /*
2081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2082 %                                                                             %
2083 %                                                                             %
2084 %                                                                             %
2085 %  L o a d C o l o r L i s t s                                                %
2086 %                                                                             %
2087 %                                                                             %
2088 %                                                                             %
2089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2090 %
2091 %  LoadColorList() loads one or more color configuration file which provides a
2092 %  mapping between color attributes and a color name.
2093 %
2094 %  The format of the LoadColorLists method is:
2095 %
2096 %      MagickBooleanType LoadColorLists(const char *filename,
2097 %        ExceptionInfo *exception)
2098 %
2099 %  A description of each parameter follows:
2100 %
2101 %    o filename: the font file name.
2102 %
2103 %    o exception: return any errors or warnings in this structure.
2104 %
2105 */
2106 static MagickBooleanType LoadColorLists(const char *filename,
2107   ExceptionInfo *exception)
2108 {
2109   const StringInfo
2110     *option;
2111
2112   LinkedListInfo
2113     *options;
2114
2115   MagickRealType
2116     scale;
2117
2118   MagickStatusType
2119     status;
2120
2121   register const ColorMapInfo
2122     *p;
2123
2124   /*
2125     Load built-in color map.
2126   */
2127   status=MagickFalse;
2128   if (color_list == (LinkedListInfo *) NULL)
2129     {
2130       color_list=NewLinkedList(0);
2131       if (color_list == (LinkedListInfo *) NULL)
2132         {
2133           ThrowFileException(exception,ResourceLimitError,
2134             "MemoryAllocationFailed",filename);
2135           return(MagickFalse);
2136         }
2137     }
2138   scale=(MagickRealType) ScaleCharToQuantum(1);
2139   for (p=ColorMap; p->name != (const char *) NULL; p++)
2140   {
2141     ColorInfo
2142       *color_info;
2143
2144     color_info=(ColorInfo *) AcquireMagickMemory(sizeof(*color_info));
2145     if (color_info == (ColorInfo *) NULL)
2146       {
2147         (void) ThrowMagickException(exception,GetMagickModule(),
2148           ResourceLimitError,"MemoryAllocationFailed","`%s'",color_info->name);
2149         continue;
2150       }
2151     (void) ResetMagickMemory(color_info,0,sizeof(*color_info));
2152     color_info->path=(char *) "[built-in]";
2153     color_info->name=(char *) p->name;
2154     GetMagickPixelPacket((Image *) NULL,&color_info->color);
2155     color_info->color.red=scale*p->red;
2156     color_info->color.green=scale*p->green;
2157     color_info->color.blue=scale*p->blue;
2158     color_info->color.opacity=(MagickRealType) (QuantumRange-QuantumRange*
2159       p->alpha);
2160     color_info->compliance=(ComplianceType) p->compliance;
2161     color_info->exempt=MagickTrue;
2162     color_info->signature=MagickSignature;
2163     status=AppendValueToLinkedList(color_list,color_info);
2164     if (status == MagickFalse)
2165       (void) ThrowMagickException(exception,GetMagickModule(),
2166         ResourceLimitError,"MemoryAllocationFailed","`%s'",color_info->name);
2167   }
2168   /*
2169     Load external color map.
2170   */
2171   options=GetConfigureOptions(filename,exception);
2172   option=(const StringInfo *) GetNextValueInLinkedList(options);
2173   while (option != (const StringInfo *) NULL)
2174   {
2175     status|=LoadColorList((const char *) GetStringInfoDatum(option),
2176       GetStringInfoPath(option),0,exception);
2177     option=(const StringInfo *) GetNextValueInLinkedList(options);
2178   }
2179   options=DestroyConfigureOptions(options);
2180   return(status != 0 ? MagickTrue : MagickFalse);
2181 }
2182 \f
2183 /*
2184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2185 %                                                                             %
2186 %                                                                             %
2187 %                                                                             %
2188 %   Q u e r y C o l o r D a t a b a s e                                       %
2189 %                                                                             %
2190 %                                                                             %
2191 %                                                                             %
2192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2193 %
2194 %  QueryColorDatabase() returns the red, green, blue, and opacity intensities
2195 %  for a given color name.
2196 %
2197 %  The format of the QueryColorDatabase method is:
2198 %
2199 %      MagickBooleanType QueryColorDatabase(const char *name,PixelPacket *color,
2200 %        ExceptionInfo *exception)
2201 %
2202 %  A description of each parameter follows:
2203 %
2204 %    o name: the color name (e.g. white, blue, yellow).
2205 %
2206 %    o color: the red, green, blue, and opacity intensities values of the
2207 %      named color in this structure.
2208 %
2209 %    o exception: return any errors or warnings in this structure.
2210 %
2211 */
2212
2213 static inline double MagickMin(const double x,const double y)
2214 {
2215   if (x < y)
2216     return(x);
2217   return(y);
2218 }
2219
2220 MagickExport MagickBooleanType QueryColorDatabase(const char *name,
2221   PixelPacket *color,ExceptionInfo *exception)
2222 {
2223   MagickBooleanType
2224     status;
2225
2226   MagickPixelPacket
2227     pixel;
2228
2229   status=QueryMagickColor(name,&pixel,exception);
2230   color->opacity=RoundToQuantum(pixel.opacity);
2231   if (pixel.colorspace == CMYKColorspace)
2232     {
2233       color->red=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
2234         QuantumRange,(MagickRealType) (QuantumScale*pixel.red*(QuantumRange-
2235         pixel.index)+pixel.index))));
2236       color->green=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
2237         QuantumRange,(MagickRealType) (QuantumScale*pixel.green*(QuantumRange-
2238         pixel.index)+pixel.index))));
2239       color->blue=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
2240         QuantumRange,(MagickRealType) (QuantumScale*pixel.blue*(QuantumRange-
2241         pixel.index)+pixel.index))));
2242       return(status);
2243     }
2244   color->red=RoundToQuantum(pixel.red);
2245   color->green=RoundToQuantum(pixel.green);
2246   color->blue=RoundToQuantum(pixel.blue);
2247   return(status);
2248 }
2249 \f
2250 /*
2251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2252 %                                                                             %
2253 %                                                                             %
2254 %                                                                             %
2255 %  Q u e r y C o l o r n a m e                                                %
2256 %                                                                             %
2257 %                                                                             %
2258 %                                                                             %
2259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2260 %
2261 %  QueryColorname() returns a named color for the given color intensity.  If
2262 %  an exact match is not found, a rgb() color is returned instead.
2263 %
2264 %  The format of the QueryColorname method is:
2265 %
2266 %      MagickBooleanType QueryColorname(const Image *image,
2267 %        const PixelPacket *color,const ComplianceType compliance,char *name,
2268 %        ExceptionInfo *exception)
2269 %
2270 %  A description of each parameter follows.
2271 %
2272 %    o image: the image.
2273 %
2274 %    o color: the color intensities.
2275 %
2276 %    o compliance: Adhere to this color standard: SVG, X11, or XPM.
2277 %
2278 %    o name: Return the color name or hex value.
2279 %
2280 %    o exception: return any errors or warnings in this structure.
2281 %
2282 */
2283 MagickExport MagickBooleanType QueryColorname(const Image *image,
2284   const PixelPacket *color,const ComplianceType compliance,char *name,
2285   ExceptionInfo *exception)
2286 {
2287   MagickPixelPacket
2288     pixel;
2289
2290   GetMagickPixelPacket(image,&pixel);
2291   SetMagickPixelPacket(image,color,(IndexPacket *) NULL,&pixel);
2292   return(QueryMagickColorname(image,&pixel,compliance,name,exception));
2293 }
2294 \f
2295 /*
2296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2297 %                                                                             %
2298 %                                                                             %
2299 %                                                                             %
2300 %   Q u e r y M a g i c k C o l o r                                           %
2301 %                                                                             %
2302 %                                                                             %
2303 %                                                                             %
2304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2305 %
2306 %  QueryMagickColor() returns the red, green, blue, and opacity intensities
2307 %  for a given color name.
2308 %
2309 %  The format of the QueryMagickColor method is:
2310 %
2311 %      MagickBooleanType QueryMagickColor(const char *name,
2312 %        MagickPixelPacket *color,ExceptionInfo *exception)
2313 %
2314 %  A description of each parameter follows:
2315 %
2316 %    o name: the color name (e.g. white, blue, yellow).
2317 %
2318 %    o color: the red, green, blue, and opacity intensities values of the
2319 %      named color in this structure.
2320 %
2321 %    o exception: return any errors or warnings in this structure.
2322 %
2323 */
2324 MagickExport MagickBooleanType QueryMagickColor(const char *name,
2325   MagickPixelPacket *color,ExceptionInfo *exception)
2326 {
2327   GeometryInfo
2328     geometry_info;
2329
2330   long
2331     type;
2332
2333   MagickRealType
2334     scale;
2335
2336   MagickStatusType
2337     flags;
2338
2339   register const ColorInfo
2340     *p;
2341
2342   register long
2343     i;
2344
2345   /*
2346     Initialize color return value.
2347   */
2348   assert(name != (const char *) NULL);
2349   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
2350   assert(color != (MagickPixelPacket *) NULL);
2351   GetMagickPixelPacket((Image *) NULL,color);
2352   if ((name == (char *) NULL) || (*name == '\0'))
2353     name=BackgroundColor;
2354   while (isspace((int) ((unsigned char) *name)) != 0)
2355     name++;
2356   if (*name == '#')
2357     {
2358       char
2359         c;
2360
2361       LongPixelPacket
2362         pixel;
2363
2364       QuantumAny
2365         range;
2366
2367       unsigned long
2368         depth,
2369         n;
2370
2371       /*
2372         Parse hex color.
2373       */
2374       (void) ResetMagickMemory(&pixel,0,sizeof(pixel));
2375       name++;
2376       for (n=0; isxdigit((int) ((unsigned char) name[n])) != MagickFalse; n++) ;
2377       if ((n % 3) == 0)
2378         {
2379           do
2380           {
2381             pixel.red=pixel.green;
2382             pixel.green=pixel.blue;
2383             pixel.blue=0;
2384             for (i=(long) (n/3-1); i >= 0; i--)
2385             {
2386               c=(*name++);
2387               pixel.blue<<=4;
2388               if ((c >= '0') && (c <= '9'))
2389                 pixel.blue|=(int) (c-'0');
2390               else
2391                 if ((c >= 'A') && (c <= 'F'))
2392                   pixel.blue|=(int) c-((int) 'A'-10);
2393                 else
2394                   if ((c >= 'a') && (c <= 'f'))
2395                     pixel.blue|=(int) c-((int) 'a'-10);
2396                   else
2397                     return(MagickFalse);
2398             }
2399           } while (isxdigit((int) ((unsigned char) *name)) != MagickFalse);
2400           depth=4*(n/3);
2401         }
2402       else
2403         {
2404           if ((n % 4) != 0)
2405             {
2406               (void) ThrowMagickException(exception,GetMagickModule(),
2407                 OptionWarning,"UnrecognizedColor","`%s'",name);
2408               return(MagickFalse);
2409             }
2410           do
2411           {
2412             pixel.red=pixel.green;
2413             pixel.green=pixel.blue;
2414             pixel.blue=pixel.opacity;
2415             pixel.opacity=0;
2416             for (i=(long) (n/4-1); i >= 0; i--)
2417             {
2418               c=(*name++);
2419               pixel.opacity<<=4;
2420               if ((c >= '0') && (c <= '9'))
2421                 pixel.opacity|=(int) (c-'0');
2422               else
2423                 if ((c >= 'A') && (c <= 'F'))
2424                   pixel.opacity|=(int) c-((int) 'A'-10);
2425                 else
2426                   if ((c >= 'a') && (c <= 'f'))
2427                     pixel.opacity|=(int) c-((int) 'a'-10);
2428                   else
2429                     return(MagickFalse);
2430             }
2431           } while (isxdigit((int) ((unsigned char) *name)) != MagickFalse);
2432           depth=4*(n/4);
2433         }
2434       color->colorspace=RGBColorspace;
2435       color->matte=MagickFalse;
2436       range=GetQuantumRange(depth);
2437       color->red=(MagickRealType) ScaleAnyToQuantum(pixel.red,range);
2438       color->green=(MagickRealType) ScaleAnyToQuantum(pixel.green,range);
2439       color->blue=(MagickRealType) ScaleAnyToQuantum(pixel.blue,range);
2440       color->opacity=(MagickRealType) OpaqueOpacity;
2441       if ((n % 3) != 0)
2442         {
2443           color->matte=MagickTrue;
2444           color->opacity=(MagickRealType) (QuantumRange-ScaleAnyToQuantum(
2445             pixel.opacity,range));
2446         }
2447       color->index=0.0;
2448       return(MagickTrue);
2449     }
2450   if (strchr(name,'(') != (char *) NULL)
2451     {
2452       char
2453         colorspace[MaxTextExtent];
2454
2455       /*
2456         Parse color of the form rgb(100,255,0).
2457       */
2458       (void) CopyMagickString(colorspace,name,MaxTextExtent);
2459       for (i=0; colorspace[i] != '\0'; i++)
2460         if (colorspace[i] == '(')
2461           break;
2462       colorspace[i--]='\0';
2463       LocaleLower(colorspace);
2464       color->matte=MagickFalse;
2465       if ((i > 0) && (colorspace[i] == 'a'))
2466         {
2467           colorspace[i]='\0';
2468           color->matte=MagickTrue;
2469         }
2470       type=ParseMagickOption(MagickColorspaceOptions,MagickFalse,colorspace);
2471       if (type < 0)
2472         {
2473           (void) ThrowMagickException(exception,GetMagickModule(),
2474             OptionWarning,"UnrecognizedColor","`%s'",name);
2475           return(MagickFalse);
2476         }
2477       color->colorspace=(ColorspaceType) type;
2478       SetGeometryInfo(&geometry_info);
2479       flags=ParseGeometry(name+i+1,&geometry_info);
2480       scale=(MagickRealType) ScaleCharToQuantum(1);
2481       if ((flags & PercentValue) != 0)
2482         scale=(MagickRealType) (QuantumRange/100.0);
2483       if ((flags & RhoValue) != 0)
2484         color->red=(MagickRealType) RoundToQuantum(scale*geometry_info.rho);
2485       if ((flags & SigmaValue) != 0)
2486         color->green=(MagickRealType) RoundToQuantum(scale*geometry_info.sigma);
2487       if ((flags & XiValue) != 0)
2488         color->blue=(MagickRealType) RoundToQuantum(scale*geometry_info.xi);
2489       color->opacity=(MagickRealType) OpaqueOpacity;
2490       if ((flags & PsiValue) != 0)
2491         {
2492           if (color->colorspace == CMYKColorspace)
2493             color->index=(MagickRealType) RoundToQuantum(scale*
2494               geometry_info.psi);
2495           else
2496             if (color->matte != MagickFalse)
2497               color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
2498                 (QuantumRange-QuantumRange*geometry_info.psi));
2499         }
2500       if (((flags & ChiValue) != 0) && (color->matte != MagickFalse))
2501         color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
2502           (QuantumRange-QuantumRange*geometry_info.chi));
2503       if (LocaleCompare(colorspace,"gray") == 0)
2504         {
2505           color->green=color->red;
2506           color->blue=color->red;
2507           if (((flags & SigmaValue) != 0) && (color->matte != MagickFalse))
2508             color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
2509               (QuantumRange-QuantumRange*geometry_info.sigma));
2510         }
2511       if ((LocaleCompare(colorspace,"HSB") == 0) ||
2512           (LocaleCompare(colorspace,"HSL") == 0) ||
2513           (LocaleCompare(colorspace,"HWB") == 0))
2514         {
2515           PixelPacket
2516             pixel;
2517
2518           scale=1.0/360.0;
2519           if ((flags & PercentValue) != 0)
2520             scale=1.0/100.0;
2521           geometry_info.rho*=360.0*scale;
2522           scale=1.0/255.0;
2523           if ((flags & PercentValue) != 0)
2524             scale=1.0/100.0;
2525           geometry_info.sigma*=scale;
2526           geometry_info.xi*=scale;
2527           if (LocaleCompare(colorspace,"HSB") == 0)
2528             ConvertHSBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
2529               360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
2530               &pixel.green,&pixel.blue);
2531           else
2532             if (LocaleCompare(colorspace,"HSL") == 0)
2533               ConvertHSLToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
2534                 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
2535                 &pixel.green,&pixel.blue);
2536             else
2537               ConvertHWBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
2538                 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
2539                 &pixel.green,&pixel.blue);
2540           color->colorspace=RGBColorspace;
2541           color->red=(MagickRealType) pixel.red;
2542           color->green=(MagickRealType) pixel.green;
2543           color->blue=(MagickRealType) pixel.blue;
2544         }
2545       return(MagickTrue);
2546     }
2547   /*
2548     Parse named color.
2549   */
2550   p=GetColorInfo(name,exception);
2551   if (p == (const ColorInfo *) NULL)
2552     return(MagickFalse);
2553   color->colorspace=RGBColorspace;
2554   color->matte=p->color.opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
2555   color->red=(MagickRealType) p->color.red;
2556   color->green=(MagickRealType) p->color.green;
2557   color->blue=(MagickRealType) p->color.blue;
2558   color->opacity=(MagickRealType) p->color.opacity;
2559   color->index=0.0;
2560   return(MagickTrue);
2561 }
2562 \f
2563 /*
2564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2565 %                                                                             %
2566 %                                                                             %
2567 %                                                                             %
2568 %  Q u e r y M a g i c k C o l o r n a m e                                    %
2569 %                                                                             %
2570 %                                                                             %
2571 %                                                                             %
2572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2573 %
2574 %  QueryMagickColorname() returns a named color for the given color intensity.
2575 %  If an exact match is not found, a hex value is returned instead.  For
2576 %  example an intensity of rgb:(0,0,0) returns black whereas rgb:(223,223,223)
2577 %  returns #dfdfdf.
2578 %
2579 %  The format of the QueryMagickColorname method is:
2580 %
2581 %      MagickBooleanType QueryMagickColorname(const Image *image,
2582 %        const PixelPacket *color,const ComplianceType compliance,char *name,
2583 %        ExceptionInfo *exception)
2584 %
2585 %  A description of each parameter follows.
2586 %
2587 %    o image: the image.
2588 %
2589 %    o color: the color intensities.
2590 %
2591 %    o Compliance: Adhere to this color standard: SVG, X11, or XPM.
2592 %
2593 %    o name: Return the color name or hex value.
2594 %
2595 %    o exception: return any errors or warnings in this structure.
2596 %
2597 */
2598 MagickExport MagickBooleanType QueryMagickColorname(const Image *image,
2599   const MagickPixelPacket *color,const ComplianceType compliance,
2600   char *name,ExceptionInfo *exception)
2601 {
2602   MagickPixelPacket
2603     pixel;
2604
2605   MagickRealType
2606     opacity;
2607
2608   register const ColorInfo
2609     *p;
2610
2611   *name='\0';
2612   pixel=(*color);
2613   if (compliance == XPMCompliance)
2614     {
2615       pixel.matte=MagickFalse;
2616       pixel.depth=(unsigned long) MagickMin(1.0*image->depth,16.0);
2617       GetColorTuple(&pixel,MagickTrue,name);
2618       return(MagickTrue);
2619     }
2620   GetColorTuple(&pixel,compliance != SVGCompliance ? MagickTrue : MagickFalse,
2621     name);
2622   (void) GetColorInfo("*",exception);
2623   ResetLinkedListIterator(color_list);
2624   opacity=image->matte != MagickFalse ? color->opacity : OpaqueOpacity;
2625   p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
2626   while (p != (const ColorInfo *) NULL)
2627   {
2628     if (((p->compliance & compliance) != 0) && ((p->color.red == color->red)) &&
2629          (p->color.green == color->green) && (p->color.blue == color->blue) &&
2630          (p->color.opacity == opacity))
2631       {
2632         (void) CopyMagickString(name,p->name,MaxTextExtent);
2633         break;
2634       }
2635     p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
2636   }
2637   return(MagickTrue);
2638 }