2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 % CCCC OOO L OOO RRRR %
9 % CCCC OOO LLLLL OOO R R %
12 % MagickCore Color Methods %
19 % Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
25 % http://www.imagemagick.org/script/license.php %
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. %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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).
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"
72 #define ColorFilename "colors.xml"
78 *ColorMap = (const char *)
79 "<?xml version=\"1.0\"?>"
81 " <color name=\"none\" color=\"rgba(0,0,0,0)\" compliance=\"SVG\" />"
82 " <color name=\"black\" color=\"rgb(0,0,0)\" compliance=\"SVG, X11, XPM\" />"
83 " <color name=\"red\" color=\"rgb(255,0,0)\" compliance=\"SVG, X11, XPM\" />"
84 " <color name=\"magenta\" color=\"rgb(255,0,255)\" compliance=\"SVG, X11, XPM\" />"
85 " <color name=\"green\" color=\"rgb(0,128,0)\" compliance=\"SVG\" />"
86 " <color name=\"cyan\" color=\"rgb(0,255,255)\" compliance=\"SVG, X11, XPM\" />"
87 " <color name=\"blue\" color=\"rgb(0,0,255)\" compliance=\"SVG, X11, XPM\" />"
88 " <color name=\"yellow\" color=\"rgb(255,255,0)\" compliance=\"SVG, X11, XPM\" />"
89 " <color name=\"white\" color=\"rgb(255,255,255)\" compliance=\"SVG, X11\" />"
90 " <color name=\"AliceBlue\" color=\"rgb(240,248,255)\" compliance=\"SVG, X11, XPM\" />"
91 " <color name=\"AntiqueWhite\" color=\"rgb(250,235,215)\" compliance=\"SVG, X11, XPM\" />"
92 " <color name=\"aqua\" color=\"rgb(0,255,255)\" compliance=\"SVG\" />"
93 " <color name=\"aquamarine\" color=\"rgb(127,255,212)\" compliance=\"SVG, X11, XPM\" />"
94 " <color name=\"azure\" color=\"rgb(240,255,255)\" compliance=\"SVG, X11, XPM\" />"
95 " <color name=\"beige\" color=\"rgb(245,245,220)\" compliance=\"SVG, X11, XPM\" />"
96 " <color name=\"bisque\" color=\"rgb(255,228,196)\" compliance=\"SVG, X11, XPM\" />"
97 " <color name=\"BlanchedAlmond\" color=\"rgb(255,235,205)\" compliance=\"SVG, X11, XPM\" />"
98 " <color name=\"BlueViolet\" color=\"rgb(138,43,226)\" compliance=\"SVG, X11, XPM\" />"
99 " <color name=\"brown\" color=\"rgb(165,42,42)\" compliance=\"SVG, X11, XPM\" />"
100 " <color name=\"burlywood\" color=\"rgb(222,184,135)\" compliance=\"SVG, X11, XPM\" />"
101 " <color name=\"CadetBlue\" color=\"rgb(95,158,160)\" compliance=\"SVG, X11, XPM\" />"
102 " <color name=\"chartreuse\" color=\"rgb(127,255,0)\" compliance=\"SVG, X11, XPM\" />"
103 " <color name=\"chocolate\" color=\"rgb(210,105,30)\" compliance=\"SVG, X11, XPM\" />"
104 " <color name=\"coral\" color=\"rgb(255,127,80)\" compliance=\"SVG, X11, XPM\" />"
105 " <color name=\"CornflowerBlue\" color=\"rgb(100,149,237)\" compliance=\"SVG, X11, XPM\" />"
106 " <color name=\"cornsilk\" color=\"rgb(255,248,220)\" compliance=\"SVG, X11, XPM\" />"
107 " <color name=\"crimson\" color=\"rgb(220,20,60)\" compliance=\"SVG\" />"
108 " <color name=\"DarkBlue\" color=\"rgb(0,0,139)\" compliance=\"SVG, X11\" />"
109 " <color name=\"DarkCyan\" color=\"rgb(0,139,139)\" compliance=\"SVG, X11\" />"
110 " <color name=\"DarkGoldenrod\" color=\"rgb(184,134,11)\" compliance=\"SVG, X11, XPM\" />"
111 " <color name=\"DarkGray\" color=\"rgb(169,169,169)\" compliance=\"SVG, X11\" />"
112 " <color name=\"DarkGreen\" color=\"rgb(0,100,0)\" compliance=\"SVG, X11, XPM\" />"
113 " <color name=\"DarkGrey\" color=\"rgb(169,169,169)\" compliance=\"SVG, X11\" />"
114 " <color name=\"DarkKhaki\" color=\"rgb(189,183,107)\" compliance=\"SVG, X11, XPM\" />"
115 " <color name=\"DarkMagenta\" color=\"rgb(139,0,139)\" compliance=\"SVG, X11\" />"
116 " <color name=\"DarkOliveGreen\" color=\"rgb(85,107,47)\" compliance=\"SVG, X11, XPM\" />"
117 " <color name=\"DarkOrange\" color=\"rgb(255,140,0)\" compliance=\"SVG, X11, XPM\" />"
118 " <color name=\"DarkOrchid\" color=\"rgb(153,50,204)\" compliance=\"SVG, X11, XPM\" />"
119 " <color name=\"DarkRed\" color=\"rgb(139,0,0)\" compliance=\"SVG, X11\" />"
120 " <color name=\"DarkSalmon\" color=\"rgb(233,150,122)\" compliance=\"SVG, X11, XPM\" />"
121 " <color name=\"DarkSeaGreen\" color=\"rgb(143,188,143)\" compliance=\"SVG, X11, XPM\" />"
122 " <color name=\"DarkSlateBlue\" color=\"rgb(72,61,139)\" compliance=\"SVG, X11, XPM\" />"
123 " <color name=\"DarkSlateGray\" color=\"rgb(47,79,79)\" compliance=\"SVG, X11, XPM\" />"
124 " <color name=\"DarkSlateGrey\" color=\"rgb(47,79,79)\" compliance=\"SVG, X11\" />"
125 " <color name=\"DarkTurquoise\" color=\"rgb(0,206,209)\" compliance=\"SVG, X11, XPM\" />"
126 " <color name=\"DarkViolet\" color=\"rgb(148,0,211)\" compliance=\"SVG, X11, XPM\" />"
127 " <color name=\"DeepPink\" color=\"rgb(255,20,147)\" compliance=\"SVG, X11, XPM\" />"
128 " <color name=\"DeepSkyBlue\" color=\"rgb(0,191,255)\" compliance=\"SVG, X11, XPM\" />"
129 " <color name=\"DimGray\" color=\"rgb(105,105,105)\" compliance=\"SVG, X11, XPM\" />"
130 " <color name=\"DimGrey\" color=\"rgb(105,105,105)\" compliance=\"SVG, X11\" />"
131 " <color name=\"DodgerBlue\" color=\"rgb(30,144,255)\" compliance=\"SVG, X11, XPM\" />"
132 " <color name=\"firebrick\" color=\"rgb(178,34,34)\" compliance=\"SVG, X11, XPM\" />"
133 " <color name=\"FloralWhite\" color=\"rgb(255,250,240)\" compliance=\"SVG, X11, XPM\" />"
134 " <color name=\"ForestGreen\" color=\"rgb(34,139,34)\" compliance=\"SVG, X11, XPM\" />"
135 " <color name=\"fractal\" color=\"rgb(128,128,128)\" compliance=\"SVG\" />"
136 " <color name=\"fuchsia\" color=\"rgb(255,0,255)\" compliance=\"SVG\" />"
137 " <color name=\"gainsboro\" color=\"rgb(220,220,220)\" compliance=\"SVG, X11, XPM\" />"
138 " <color name=\"GhostWhite\" color=\"rgb(248,248,255)\" compliance=\"SVG, X11, XPM\" />"
139 " <color name=\"gold\" color=\"rgb(255,215,0)\" compliance=\"X11, XPM\" />"
140 " <color name=\"goldenrod\" color=\"rgb(218,165,32)\" compliance=\"SVG, X11, XPM\" />"
141 " <color name=\"gray\" color=\"rgb(126,126,126)\" compliance=\"SVG\" />"
142 " <color name=\"gray74\" color=\"rgb(189,189,189)\" compliance=\"SVG, X11\" />"
143 " <color name=\"gray100\" color=\"rgb(255,255,255)\" compliance=\"SVG, X11\" />"
144 " <color name=\"grey\" color=\"rgb(190,190,190)\" compliance=\"SVG, X11\" />"
145 " <color name=\"grey0\" color=\"rgb(0,0,0)\" compliance=\"SVG, X11\" />"
146 " <color name=\"grey1\" color=\"rgb(3,3,3)\" compliance=\"SVG, X11\" />"
147 " <color name=\"grey10\" color=\"rgb(26,26,26)\" compliance=\"SVG, X11\" />"
148 " <color name=\"grey100\" color=\"rgb(255,255,255)\" compliance=\"SVG, X11\" />"
149 " <color name=\"grey11\" color=\"rgb(28,28,28)\" compliance=\"SVG, X11\" />"
150 " <color name=\"grey12\" color=\"rgb(31,31,31)\" compliance=\"SVG, X11\" />"
151 " <color name=\"grey13\" color=\"rgb(33,33,33)\" compliance=\"SVG, X11\" />"
152 " <color name=\"grey14\" color=\"rgb(36,36,36)\" compliance=\"SVG, X11\" />"
153 " <color name=\"grey15\" color=\"rgb(38,38,38)\" compliance=\"SVG, X11\" />"
154 " <color name=\"grey16\" color=\"rgb(41,41,41)\" compliance=\"SVG, X11\" />"
155 " <color name=\"grey17\" color=\"rgb(43,43,43)\" compliance=\"SVG, X11\" />"
156 " <color name=\"grey18\" color=\"rgb(45,45,45)\" compliance=\"SVG, X11\" />"
157 " <color name=\"grey19\" color=\"rgb(48,48,48)\" compliance=\"SVG, X11\" />"
158 " <color name=\"grey2\" color=\"rgb(5,5,5)\" compliance=\"SVG, X11\" />"
159 " <color name=\"grey20\" color=\"rgb(51,51,51)\" compliance=\"SVG, X11\" />"
160 " <color name=\"grey21\" color=\"rgb(54,54,54)\" compliance=\"SVG, X11\" />"
161 " <color name=\"grey22\" color=\"rgb(56,56,56)\" compliance=\"SVG, X11\" />"
162 " <color name=\"grey23\" color=\"rgb(59,59,59)\" compliance=\"SVG, X11\" />"
163 " <color name=\"grey24\" color=\"rgb(61,61,61)\" compliance=\"SVG, X11\" />"
164 " <color name=\"grey25\" color=\"rgb(64,64,64)\" compliance=\"SVG, X11\" />"
165 " <color name=\"grey26\" color=\"rgb(66,66,66)\" compliance=\"SVG, X11\" />"
166 " <color name=\"grey27\" color=\"rgb(69,69,69)\" compliance=\"SVG, X11\" />"
167 " <color name=\"grey28\" color=\"rgb(71,71,71)\" compliance=\"SVG, X11\" />"
168 " <color name=\"grey29\" color=\"rgb(74,74,74)\" compliance=\"SVG, X11\" />"
169 " <color name=\"grey3\" color=\"rgb(8,8,8)\" compliance=\"SVG, X11\" />"
170 " <color name=\"grey30\" color=\"rgb(77,77,77)\" compliance=\"SVG, X11\" />"
171 " <color name=\"grey31\" color=\"rgb(79,79,79)\" compliance=\"SVG, X11\" />"
172 " <color name=\"grey32\" color=\"rgb(82,82,82)\" compliance=\"SVG, X11\" />"
173 " <color name=\"grey33\" color=\"rgb(84,84,84)\" compliance=\"SVG, X11\" />"
174 " <color name=\"grey34\" color=\"rgb(87,87,87)\" compliance=\"SVG, X11\" />"
175 " <color name=\"grey35\" color=\"rgb(89,89,89)\" compliance=\"SVG, X11\" />"
176 " <color name=\"grey36\" color=\"rgb(92,92,92)\" compliance=\"SVG, X11\" />"
177 " <color name=\"grey37\" color=\"rgb(94,94,94)\" compliance=\"SVG, X11\" />"
178 " <color name=\"grey38\" color=\"rgb(97,97,97)\" compliance=\"SVG, X11\" />"
179 " <color name=\"grey39\" color=\"rgb(99,99,99)\" compliance=\"SVG, X11\" />"
180 " <color name=\"grey4\" color=\"rgb(10,10,10)\" compliance=\"SVG, X11\" />"
181 " <color name=\"grey40\" color=\"rgb(102,102,102)\" compliance=\"SVG, X11\" />"
182 " <color name=\"grey41\" color=\"rgb(105,105,105)\" compliance=\"SVG, X11\" />"
183 " <color name=\"grey42\" color=\"rgb(107,107,107)\" compliance=\"SVG, X11\" />"
184 " <color name=\"grey43\" color=\"rgb(110,110,110)\" compliance=\"SVG, X11\" />"
185 " <color name=\"grey44\" color=\"rgb(112,112,112)\" compliance=\"SVG, X11\" />"
186 " <color name=\"grey45\" color=\"rgb(115,115,115)\" compliance=\"SVG, X11\" />"
187 " <color name=\"grey45\" color=\"rgb(117,117,117)\" compliance=\"SVG, X11\" />"
188 " <color name=\"grey47\" color=\"rgb(120,120,120)\" compliance=\"SVG, X11\" />"
189 " <color name=\"grey48\" color=\"rgb(122,122,122)\" compliance=\"SVG, X11\" />"
190 " <color name=\"grey49\" color=\"rgb(125,125,125)\" compliance=\"SVG, X11\" />"
191 " <color name=\"grey5\" color=\"rgb(13,13,13)\" compliance=\"SVG, X11\" />"
192 " <color name=\"grey50\" color=\"rgb(50%,50%,50%)\" compliance=\"SVG, X11\" />"
193 " <color name=\"grey51\" color=\"rgb(130,130,130)\" compliance=\"SVG, X11\" />"
194 " <color name=\"grey52\" color=\"rgb(133,133,133)\" compliance=\"SVG, X11\" />"
195 " <color name=\"grey53\" color=\"rgb(135,135,135)\" compliance=\"SVG, X11\" />"
196 " <color name=\"grey54\" color=\"rgb(138,138,138)\" compliance=\"SVG, X11\" />"
197 " <color name=\"grey55\" color=\"rgb(140,140,140)\" compliance=\"SVG, X11\" />"
198 " <color name=\"grey56\" color=\"rgb(143,143,143)\" compliance=\"SVG, X11\" />"
199 " <color name=\"grey57\" color=\"rgb(145,145,145)\" compliance=\"SVG, X11\" />"
200 " <color name=\"grey58\" color=\"rgb(148,148,148)\" compliance=\"SVG, X11\" />"
201 " <color name=\"grey59\" color=\"rgb(150,150,150)\" compliance=\"SVG, X11\" />"
202 " <color name=\"grey6\" color=\"rgb(15,15,15)\" compliance=\"SVG, X11\" />"
203 " <color name=\"grey60\" color=\"rgb(153,153,153)\" compliance=\"SVG, X11\" />"
204 " <color name=\"grey61\" color=\"rgb(156,156,156)\" compliance=\"SVG, X11\" />"
205 " <color name=\"grey62\" color=\"rgb(158,158,158)\" compliance=\"SVG, X11\" />"
206 " <color name=\"grey63\" color=\"rgb(161,161,161)\" compliance=\"SVG, X11\" />"
207 " <color name=\"grey64\" color=\"rgb(163,163,163)\" compliance=\"SVG, X11\" />"
208 " <color name=\"grey65\" color=\"rgb(166,166,166)\" compliance=\"SVG, X11\" />"
209 " <color name=\"grey66\" color=\"rgb(168,168,168)\" compliance=\"SVG, X11\" />"
210 " <color name=\"grey67\" color=\"rgb(171,171,171)\" compliance=\"SVG, X11\" />"
211 " <color name=\"grey68\" color=\"rgb(173,173,173)\" compliance=\"SVG, X11\" />"
212 " <color name=\"grey69\" color=\"rgb(176,176,176)\" compliance=\"SVG, X11\" />"
213 " <color name=\"grey7\" color=\"rgb(18,18,18)\" compliance=\"SVG, X11\" />"
214 " <color name=\"grey70\" color=\"rgb(179,179,179)\" compliance=\"SVG, X11\" />"
215 " <color name=\"grey71\" color=\"rgb(181,181,181)\" compliance=\"SVG, X11\" />"
216 " <color name=\"grey72\" color=\"rgb(184,184,184)\" compliance=\"SVG, X11\" />"
217 " <color name=\"grey73\" color=\"rgb(186,186,186)\" compliance=\"SVG, X11\" />"
218 " <color name=\"grey74\" color=\"rgb(189,189,189)\" compliance=\"SVG, X11\" />"
219 " <color name=\"grey75\" color=\"rgb(191,191,191)\" compliance=\"SVG, X11\" />"
220 " <color name=\"grey76\" color=\"rgb(194,194,194)\" compliance=\"SVG, X11\" />"
221 " <color name=\"grey77\" color=\"rgb(196,196,196)\" compliance=\"SVG, X11\" />"
222 " <color name=\"grey78\" color=\"rgb(199,199,199)\" compliance=\"SVG, X11\" />"
223 " <color name=\"grey79\" color=\"rgb(201,201,201)\" compliance=\"SVG, X11\" />"
224 " <color name=\"grey8\" color=\"rgb(20,20,20)\" compliance=\"SVG, X11\" />"
225 " <color name=\"grey80\" color=\"rgb(204,204,204)\" compliance=\"SVG, X11\" />"
226 " <color name=\"grey81\" color=\"rgb(207,207,207)\" compliance=\"SVG, X11\" />"
227 " <color name=\"grey82\" color=\"rgb(209,209,209)\" compliance=\"SVG, X11\" />"
228 " <color name=\"grey83\" color=\"rgb(212,212,212)\" compliance=\"SVG, X11\" />"
229 " <color name=\"grey84\" color=\"rgb(214,214,214)\" compliance=\"SVG, X11\" />"
230 " <color name=\"grey85\" color=\"rgb(217,217,217)\" compliance=\"SVG, X11\" />"
231 " <color name=\"grey86\" color=\"rgb(219,219,219)\" compliance=\"SVG, X11\" />"
232 " <color name=\"grey87\" color=\"rgb(222,222,222)\" compliance=\"SVG, X11\" />"
233 " <color name=\"grey88\" color=\"rgb(224,224,224)\" compliance=\"SVG, X11\" />"
234 " <color name=\"grey89\" color=\"rgb(227,227,227)\" compliance=\"SVG, X11\" />"
235 " <color name=\"grey9\" color=\"rgb(23,23,23)\" compliance=\"SVG, X11\" />"
236 " <color name=\"grey90\" color=\"rgb(229,229,229)\" compliance=\"SVG, X11\" />"
237 " <color name=\"grey91\" color=\"rgb(232,232,232)\" compliance=\"SVG, X11\" />"
238 " <color name=\"grey92\" color=\"rgb(235,235,235)\" compliance=\"SVG, X11\" />"
239 " <color name=\"grey93\" color=\"rgb(237,237,237)\" compliance=\"SVG, X11\" />"
240 " <color name=\"grey94\" color=\"rgb(240,240,240)\" compliance=\"SVG, X11\" />"
241 " <color name=\"grey95\" color=\"rgb(242,242,242)\" compliance=\"SVG, X11\" />"
242 " <color name=\"grey96\" color=\"rgb(245,245,245)\" compliance=\"SVG, X11\" />"
243 " <color name=\"grey97\" color=\"rgb(247,247,247)\" compliance=\"SVG, X11\" />"
244 " <color name=\"grey98\" color=\"rgb(250,250,250)\" compliance=\"SVG, X11\" />"
245 " <color name=\"grey99\" color=\"rgb(252,252,252)\" compliance=\"SVG, X11\" />"
246 " <color name=\"honeydew\" color=\"rgb(240,255,240)\" compliance=\"SVG, X11, XPM\" />"
247 " <color name=\"HotPink\" color=\"rgb(255,105,180)\" compliance=\"SVG, X11, XPM\" />"
248 " <color name=\"IndianRed\" color=\"rgb(205,92,92)\" compliance=\"SVG, X11, XPM\" />"
249 " <color name=\"indigo\" color=\"rgb(75,0,130)\" compliance=\"SVG\" />"
250 " <color name=\"ivory\" color=\"rgb(255,255,240)\" compliance=\"SVG, X11, XPM\" />"
251 " <color name=\"khaki\" color=\"rgb(240,230,140)\" compliance=\"SVG, X11, XPM\" />"
252 " <color name=\"lavender\" color=\"rgb(230,230,250)\" compliance=\"SVG, X11, XPM\" />"
253 " <color name=\"LavenderBlush\" color=\"rgb(255,240,245)\" compliance=\"SVG, X11, XPM\" />"
254 " <color name=\"LawnGreen\" color=\"rgb(124,252,0)\" compliance=\"SVG, X11, XPM\" />"
255 " <color name=\"LemonChiffon\" color=\"rgb(255,250,205)\" compliance=\"SVG, X11, XPM\" />"
256 " <color name=\"LightBlue\" color=\"rgb(173,216,230)\" compliance=\"SVG, X11, XPM\" />"
257 " <color name=\"LightCoral\" color=\"rgb(240,128,128)\" compliance=\"SVG, X11, XPM\" />"
258 " <color name=\"LightCyan\" color=\"rgb(224,255,255)\" compliance=\"SVG, X11, XPM\" />"
259 " <color name=\"LightGoldenrodYellow\" color=\"rgb(250,250,210)\" compliance=\"SVG, X11, XPM\" />"
260 " <color name=\"LightGray\" color=\"rgb(211,211,211)\" compliance=\"SVG, X11, XPM\" />"
261 " <color name=\"LightGreen\" color=\"rgb(144,238,144)\" compliance=\"SVG, X11\" />"
262 " <color name=\"LightGrey\" color=\"rgb(211,211,211)\" compliance=\"SVG, X11\" />"
263 " <color name=\"LightPink\" color=\"rgb(255,182,193)\" compliance=\"SVG, X11, XPM\" />"
264 " <color name=\"LightSalmon\" color=\"rgb(255,160,122)\" compliance=\"SVG, X11, XPM\" />"
265 " <color name=\"LightSeaGreen\" color=\"rgb(32,178,170)\" compliance=\"SVG, X11, XPM\" />"
266 " <color name=\"LightSkyBlue\" color=\"rgb(135,206,250)\" compliance=\"SVG, X11, XPM\" />"
267 " <color name=\"LightSlateGray\" color=\"rgb(119,136,153)\" compliance=\"SVG, X11, XPM\" />"
268 " <color name=\"LightSlateGrey\" color=\"rgb(119,136,153)\" compliance=\"SVG, X11\" />"
269 " <color name=\"LightSteelBlue\" color=\"rgb(176,196,222)\" compliance=\"SVG, X11, XPM\" />"
270 " <color name=\"LightYellow\" color=\"rgb(255,255,224)\" compliance=\"SVG, X11, XPM\" />"
271 " <color name=\"lime\" color=\"rgb(0,255,0)\" compliance=\"SVG\" />"
272 " <color name=\"LimeGreen\" color=\"rgb(50,205,50)\" compliance=\"SVG, X11, XPM\" />"
273 " <color name=\"linen\" color=\"rgb(250,240,230)\" compliance=\"SVG, X11, XPM\" />"
274 " <color name=\"maroon\" color=\"rgb(128,0,0)\" compliance=\"SVG\" />"
275 " <color name=\"MediumAquamarine\" color=\"rgb(102,205,170)\" compliance=\"SVG, X11, XPM\" />"
276 " <color name=\"MediumBlue\" color=\"rgb(0,0,205)\" compliance=\"SVG, X11, XPM\" />"
277 " <color name=\"MediumOrchid\" color=\"rgb(186,85,211)\" compliance=\"SVG, X11, XPM\" />"
278 " <color name=\"MediumPurple\" color=\"rgb(147,112,219)\" compliance=\"SVG, X11, XPM\" />"
279 " <color name=\"MediumSeaGreen\" color=\"rgb(60,179,113)\" compliance=\"SVG, X11, XPM\" />"
280 " <color name=\"MediumSlateBlue\" color=\"rgb(123,104,238)\" compliance=\"SVG, X11, XPM\" />"
281 " <color name=\"MediumSpringGreen\" color=\"rgb(0,250,154)\" compliance=\"SVG, X11, XPM\" />"
282 " <color name=\"MediumTurquoise\" color=\"rgb(72,209,204)\" compliance=\"SVG, X11, XPM\" />"
283 " <color name=\"MediumVioletRed\" color=\"rgb(199,21,133)\" compliance=\"SVG, X11, XPM\" />"
284 " <color name=\"MidnightBlue\" color=\"rgb(25,25,112)\" compliance=\"SVG, X11, XPM\" />"
285 " <color name=\"MintCream\" color=\"rgb(245,255,250)\" compliance=\"SVG, X11, XPM\" />"
286 " <color name=\"MistyRose\" color=\"rgb(255,228,225)\" compliance=\"SVG, X11, XPM\" />"
287 " <color name=\"moccasin\" color=\"rgb(255,228,181)\" compliance=\"SVG, X11, XPM\" />"
288 " <color name=\"NavajoWhite\" color=\"rgb(255,222,173)\" compliance=\"SVG, X11, XPM\" />"
289 " <color name=\"navy\" color=\"rgb(0,0,128)\" compliance=\"SVG, X11, XPM\" />"
290 " <color name=\"matte\" color=\"rgb(0,0,0,0)\" compliance=\"SVG\" />"
291 " <color name=\"OldLace\" color=\"rgb(253,245,230)\" compliance=\"SVG, X11, XPM\" />"
292 " <color name=\"olive\" color=\"rgb(128,128,0)\" compliance=\"SVG\" />"
293 " <color name=\"OliveDrab\" color=\"rgb(107,142,35)\" compliance=\"SVG, X11, XPM\" />"
294 " <color name=\"opaque\" color=\"rgb(0,0,0)\" compliance=\"SVG\" />"
295 " <color name=\"orange\" color=\"rgb(255,165,0)\" compliance=\"SVG, X11, XPM\" />"
296 " <color name=\"OrangeRed\" color=\"rgb(255,69,0)\" compliance=\"SVG, X11, XPM\" />"
297 " <color name=\"orchid\" color=\"rgb(218,112,214)\" compliance=\"SVG, X11, XPM\" />"
298 " <color name=\"PaleGoldenrod\" color=\"rgb(238,232,170)\" compliance=\"SVG, X11, XPM\" />"
299 " <color name=\"PaleGreen\" color=\"rgb(152,251,152)\" compliance=\"SVG, X11, XPM\" />"
300 " <color name=\"PaleTurquoise\" color=\"rgb(175,238,238)\" compliance=\"SVG, X11, XPM\" />"
301 " <color name=\"PaleVioletRed\" color=\"rgb(219,112,147)\" compliance=\"SVG, X11, XPM\" />"
302 " <color name=\"PapayaWhip\" color=\"rgb(255,239,213)\" compliance=\"SVG, X11, XPM\" />"
303 " <color name=\"PeachPuff\" color=\"rgb(255,218,185)\" compliance=\"SVG, X11, XPM\" />"
304 " <color name=\"peru\" color=\"rgb(205,133,63)\" compliance=\"SVG, X11, XPM\" />"
305 " <color name=\"pink\" color=\"rgb(255,192,203)\" compliance=\"SVG, X11, XPM\" />"
306 " <color name=\"plum\" color=\"rgb(221,160,221)\" compliance=\"SVG, X11, XPM\" />"
307 " <color name=\"PowderBlue\" color=\"rgb(176,224,230)\" compliance=\"SVG, X11, XPM\" />"
308 " <color name=\"purple\" color=\"rgb(128,0,128)\" compliance=\"SVG\" />"
309 " <color name=\"RosyBrown\" color=\"rgb(188,143,143)\" compliance=\"SVG, X11, XPM\" />"
310 " <color name=\"RoyalBlue\" color=\"rgb(65,105,225)\" compliance=\"SVG, X11, XPM\" />"
311 " <color name=\"SaddleBrown\" color=\"rgb(139,69,19)\" compliance=\"SVG, X11, XPM\" />"
312 " <color name=\"salmon\" color=\"rgb(250,128,114)\" compliance=\"SVG, X11, XPM\" />"
313 " <color name=\"SandyBrown\" color=\"rgb(244,164,96)\" compliance=\"SVG, X11, XPM\" />"
314 " <color name=\"SeaGreen\" color=\"rgb(45,139,87)\" compliance=\"SVG, X11, XPM\" />"
315 " <color name=\"seashell\" color=\"rgb(255,245,238)\" compliance=\"SVG, X11, XPM\" />"
316 " <color name=\"sienna\" color=\"rgb(160,82,45)\" compliance=\"SVG, X11, XPM\" />"
317 " <color name=\"silver\" color=\"rgb(192,192,192)\" compliance=\"SVG\" />"
318 " <color name=\"SkyBlue\" color=\"rgb(135,206,235)\" compliance=\"SVG, X11, XPM\" />"
319 " <color name=\"SlateBlue\" color=\"rgb(106,90,205)\" compliance=\"SVG, X11, XPM\" />"
320 " <color name=\"SlateGray\" color=\"rgb(112,128,144)\" compliance=\"SVG, X11, XPM\" />"
321 " <color name=\"SlateGrey\" color=\"rgb(112,128,144)\" compliance=\"SVG, X11\" />"
322 " <color name=\"snow\" color=\"rgb(255,250,250)\" compliance=\"SVG, X11, XPM\" />"
323 " <color name=\"SpringGreen\" color=\"rgb(0,255,127)\" compliance=\"SVG, X11, XPM\" />"
324 " <color name=\"SteelBlue\" color=\"rgb(70,130,180)\" compliance=\"SVG, X11, XPM\" />"
325 " <color name=\"tan\" color=\"rgb(210,180,140)\" compliance=\"SVG, X11, XPM\" />"
326 " <color name=\"teal\" color=\"rgb(0,128,128)\" compliance=\"SVG\" />"
327 " <color name=\"thistle\" color=\"rgb(216,191,216)\" compliance=\"SVG, X11, XPM\" />"
328 " <color name=\"tomato\" color=\"rgb(255,99,71)\" compliance=\"SVG, X11, XPM\" />"
329 " <color name=\"transparent\" color=\"rgba(0,0,0,0)\" compliance=\"SVG\" />"
330 " <color name=\"turquoise\" color=\"rgb(64,224,208)\" compliance=\"SVG, X11, XPM\" />"
331 " <color name=\"violet\" color=\"rgb(238,130,238)\" compliance=\"SVG, X11, XPM\" />"
332 " <color name=\"wheat\" color=\"rgb(245,222,179)\" compliance=\"SVG, X11, XPM\" />"
333 " <color name=\"WhiteSmoke\" color=\"rgb(245,245,245)\" compliance=\"SVG, X11, XPM\" />"
334 " <color name=\"YellowGreen\" color=\"rgb(154,205,50)\" compliance=\"SVG, X11, XPM\" />"
340 static LinkedListInfo
341 *color_list = (LinkedListInfo *) NULL;
344 *color_semaphore = (SemaphoreInfo *) NULL;
346 static volatile MagickBooleanType
347 instantiate_color = MagickFalse;
350 Forward declarations.
352 static MagickBooleanType
353 InitializeColorList(ExceptionInfo *),
354 LoadColorLists(const char *,ExceptionInfo *);
357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361 + 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 %
365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367 % ConcatenateColorComponent() returns the pixel as a canonical string.
369 % The format of the ConcatenateColorComponent() method is:
371 % void ConcatenateColorComponent(const MagickPixelPacket *pixel,
372 % const ChannelType channel,const ComplianceType compliance,char *tuple)
374 % A description of each parameter follows.
376 % o pixel: The pixel.
378 % channel: The channel.
380 % o compliance: Adhere to this color standard: SVG, X11, or XPM.
382 % tuple: The color tuple.
385 MagickExport void ConcatenateColorComponent(const MagickPixelPacket *pixel,
386 const ChannelType channel,const ComplianceType compliance,char *tuple)
389 component[MaxTextExtent];
414 color=QuantumRange-pixel->opacity;
425 if (compliance != SVGCompliance)
427 if (pixel->depth > 16)
429 (void) FormatMagickString(component,MaxTextExtent,"%10lu",
430 (unsigned long) ScaleQuantumToLong(RoundToQuantum(color)));
431 (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
434 if (pixel->depth > 8)
436 (void) FormatMagickString(component,MaxTextExtent,"%5d",
437 ScaleQuantumToShort(RoundToQuantum(color)));
438 (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
441 (void) FormatMagickString(component,MaxTextExtent,"%3d",
442 ScaleQuantumToChar(RoundToQuantum(color)));
443 (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
446 if (channel == OpacityChannel)
448 (void) FormatMagickString(component,MaxTextExtent,"%g",
449 (double) (QuantumScale*color));
450 (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
453 if (pixel->depth > 8)
455 (void) FormatMagickString(component,MaxTextExtent,"%g%%",
456 (double) (100.0*QuantumScale*color));
457 (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
460 (void) FormatMagickString(component,MaxTextExtent,"%d",
461 ScaleQuantumToChar(RoundToQuantum(color)));
462 (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470 + D e s t r o y C o l o r L i s t %
474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
476 % DestroyColorList() deallocates memory associated with the color list.
478 % The format of the DestroyColorList method is:
480 % DestroyColorList(void)
484 static void *DestroyColorElement(void *color_info)
489 p=(ColorInfo *) color_info;
490 if (p->path != (char *) NULL)
491 p->path=DestroyString(p->path);
492 if (p->name != (char *) NULL)
493 p->name=DestroyString(p->name);
494 p=(ColorInfo *) RelinquishMagickMemory(p);
495 return((void *) NULL);
498 MagickExport void DestroyColorList(void)
500 AcquireSemaphoreInfo(&color_semaphore);
501 if (color_list != (LinkedListInfo *) NULL)
502 color_list=DestroyLinkedList(color_list,DestroyColorElement);
503 instantiate_color=MagickFalse;
504 RelinquishSemaphoreInfo(color_semaphore);
505 DestroySemaphoreInfo(&color_semaphore);
509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
513 + G e t C o l o r I n f o %
517 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
519 % GetColorInfo() searches the color list for the specified name and if found
520 % returns attributes for that color.
522 % The format of the GetColorInfo method is:
524 % const PixelPacket *GetColorInfo(const char *name,
525 % ExceptionInfo *exception)
527 % A description of each parameter follows:
529 % o color_info: search the color list for the specified name and if found
530 % return attributes for that color.
532 % o name: the color name.
534 % o exception: return any errors or warnings in this structure.
537 MagickExport const ColorInfo *GetColorInfo(const char *name,
538 ExceptionInfo *exception)
541 colorname[MaxTextExtent];
543 register const ColorInfo
549 assert(exception != (ExceptionInfo *) NULL);
550 if ((color_list == (LinkedListInfo *) NULL) ||
551 (instantiate_color == MagickFalse))
552 if (InitializeColorList(exception) == MagickFalse)
553 return((const ColorInfo *) NULL);
554 if ((color_list == (LinkedListInfo *) NULL) ||
555 (IsLinkedListEmpty(color_list) != MagickFalse))
556 return((const ColorInfo *) NULL);
557 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
558 return((const ColorInfo *) GetValueFromLinkedList(color_list,0));
560 Strip names of whitespace.
562 (void) CopyMagickString(colorname,name,MaxTextExtent);
563 for (q=colorname; *q != '\0'; q++)
565 if (isspace((int) ((unsigned char) *q)) == 0)
567 (void) CopyMagickString(q,q+1,MaxTextExtent);
571 Search for color tag.
573 AcquireSemaphoreInfo(&color_semaphore);
574 ResetLinkedListIterator(color_list);
575 p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
576 while (p != (const ColorInfo *) NULL)
578 if (LocaleCompare(colorname,p->name) == 0)
580 p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
582 if (p == (ColorInfo *) NULL)
583 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
584 "UnrecognizedColor","`%s'",name);
586 (void) InsertValueInLinkedList(color_list,0,
587 RemoveElementByValueFromLinkedList(color_list,p));
588 RelinquishSemaphoreInfo(color_semaphore);
593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
597 % G e t C o l o r I n f o L i s t %
601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603 % GetColorInfoList() returns any colors that match the specified pattern.
605 % The format of the GetColorInfoList function is:
607 % const ColorInfo **GetColorInfoList(const char *pattern,
608 % unsigned long *number_colors,ExceptionInfo *exception)
610 % A description of each parameter follows:
612 % o pattern: Specifies a pointer to a text string containing a pattern.
614 % o number_colors: This integer returns the number of colors in the list.
616 % o exception: return any errors or warnings in this structure.
620 #if defined(__cplusplus) || defined(c_plusplus)
624 static int ColorInfoCompare(const void *x,const void *y)
630 p=(const ColorInfo **) x,
631 q=(const ColorInfo **) y;
632 if (LocaleCompare((*p)->path,(*q)->path) == 0)
633 return(LocaleCompare((*p)->name,(*q)->name));
634 return(LocaleCompare((*p)->path,(*q)->path));
637 #if defined(__cplusplus) || defined(c_plusplus)
641 MagickExport const ColorInfo **GetColorInfoList(const char *pattern,
642 unsigned long *number_colors,ExceptionInfo *exception)
647 register const ColorInfo
656 assert(pattern != (char *) NULL);
657 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
658 assert(number_colors != (unsigned long *) NULL);
660 p=GetColorInfo("*",exception);
661 if (p == (const ColorInfo *) NULL)
662 return((const ColorInfo **) NULL);
663 colors=(const ColorInfo **) AcquireQuantumMemory((size_t)
664 GetNumberOfElementsInLinkedList(color_list)+1UL,sizeof(*colors));
665 if (colors == (const ColorInfo **) NULL)
666 return((const ColorInfo **) NULL);
670 AcquireSemaphoreInfo(&color_semaphore);
671 ResetLinkedListIterator(color_list);
672 p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
673 for (i=0; p != (const ColorInfo *) NULL; )
675 if ((p->stealth == MagickFalse) &&
676 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
678 p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
680 RelinquishSemaphoreInfo(color_semaphore);
681 qsort((void *) colors,(size_t) i,sizeof(*colors),ColorInfoCompare);
682 colors[i]=(ColorInfo *) NULL;
683 *number_colors=(unsigned long) i;
688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
692 % G e t C o l o r L i s t %
696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
698 % GetColorList() returns any colors that match the specified pattern.
700 % The format of the GetColorList function is:
702 % char **GetColorList(const char *pattern,unsigned long *number_colors,
703 % ExceptionInfo *exception)
705 % A description of each parameter follows:
707 % o pattern: Specifies a pointer to a text string containing a pattern.
709 % o number_colors: This integer returns the number of colors in the list.
711 % o exception: return any errors or warnings in this structure.
715 #if defined(__cplusplus) || defined(c_plusplus)
719 static int ColorCompare(const void *x,const void *y)
727 return(LocaleCompare(*p,*q));
730 #if defined(__cplusplus) || defined(c_plusplus)
734 MagickExport char **GetColorList(const char *pattern,
735 unsigned long *number_colors,ExceptionInfo *exception)
740 register const ColorInfo
749 assert(pattern != (char *) NULL);
750 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
751 assert(number_colors != (unsigned long *) NULL);
753 p=GetColorInfo("*",exception);
754 if (p == (const ColorInfo *) NULL)
755 return((char **) NULL);
756 colors=(char **) AcquireQuantumMemory((size_t)
757 GetNumberOfElementsInLinkedList(color_list)+1UL,sizeof(*colors));
758 if (colors == (char **) NULL)
759 return((char **) NULL);
763 AcquireSemaphoreInfo(&color_semaphore);
764 ResetLinkedListIterator(color_list);
765 p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
766 for (i=0; p != (const ColorInfo *) NULL; )
768 if ((p->stealth == MagickFalse) &&
769 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
770 colors[i++]=ConstantString(p->name);
771 p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
773 RelinquishSemaphoreInfo(color_semaphore);
774 qsort((void *) colors,(size_t) i,sizeof(*colors),ColorCompare);
775 colors[i]=(char *) NULL;
776 *number_colors=(unsigned long) i;
781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
785 + G e t C o l o r T u p l e %
789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
791 % GetColorTuple() returns a color as a color tuple string (e.g. rgba(255,0,0))
792 % or hex string (e.g. #FF0000).
794 % The format of the GetColorTuple method is:
796 % GetColorTuple(const MagickPixelPacket *pixel,const MagickBooleanType hex,
799 % A description of each parameter follows.
801 % o pixel: the pixel.
803 % o hex: A value other than zero returns the tuple in a hexidecimal format.
805 % o tuple: Return the color tuple as this string.
809 static void ConcatentateHexColorComponent(const MagickPixelPacket *pixel,
810 const ChannelType channel,char *tuple)
813 component[MaxTextExtent];
838 color=(MagickRealType) QuantumRange-pixel->opacity;
849 if (pixel->depth > 32)
851 (void) FormatMagickString(component,MaxTextExtent,"%08lX",
852 ScaleQuantumToLong(RoundToQuantum(color)));
853 (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
856 if (pixel->depth > 16)
858 (void) FormatMagickString(component,MaxTextExtent,"%08X",
859 (unsigned int) ScaleQuantumToLong(RoundToQuantum(color)));
860 (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
863 if (pixel->depth > 8)
865 (void) FormatMagickString(component,MaxTextExtent,"%04X",
866 ScaleQuantumToShort(RoundToQuantum(color)));
867 (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
870 (void) FormatMagickString(component,MaxTextExtent,"%02X",
871 ScaleQuantumToChar(RoundToQuantum(color)));
872 (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
876 MagickExport void GetColorTuple(const MagickPixelPacket *pixel,
877 const MagickBooleanType hex,char *tuple)
882 assert(pixel != (const MagickPixelPacket *) NULL);
883 assert(tuple != (char *) NULL);
884 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tuple);
886 if (hex != MagickFalse)
889 Convert pixel to hex color.
891 (void) ConcatenateMagickString(tuple,"#",MaxTextExtent);
892 ConcatentateHexColorComponent(pixel,RedChannel,tuple);
893 ConcatentateHexColorComponent(pixel,GreenChannel,tuple);
894 ConcatentateHexColorComponent(pixel,BlueChannel,tuple);
895 if (pixel->colorspace == CMYKColorspace)
896 ConcatentateHexColorComponent(pixel,IndexChannel,tuple);
897 if ((pixel->matte != MagickFalse) && (pixel->opacity != OpaqueOpacity))
898 ConcatentateHexColorComponent(pixel,OpacityChannel,tuple);
902 Convert pixel to rgb() or cmyk() color.
907 #define SVGCompliant(component) ((MagickRealType) \
908 ScaleCharToQuantum(ScaleQuantumToChar(RoundToQuantum(component))));
914 SVG requires color depths > 8 expressed as percentages.
916 status=color.red == SVGCompliant(color.red);
917 status&=color.green == SVGCompliant(color.green);
918 status&=color.blue == SVGCompliant(color.blue);
919 if (color.colorspace != CMYKColorspace)
920 status&=color.index == SVGCompliant(color.index);
921 if (color.matte != MagickFalse)
922 status&=color.opacity == SVGCompliant(color.opacity);
923 if (status != MagickFalse)
926 (void) ConcatenateMagickString(tuple,MagickOptionToMnemonic(
927 MagickColorspaceOptions,(long) color.colorspace),MaxTextExtent);
928 if (color.matte != MagickFalse)
929 (void) ConcatenateMagickString(tuple,"a",MaxTextExtent);
930 (void) ConcatenateMagickString(tuple,"(",MaxTextExtent);
931 ConcatenateColorComponent(&color,RedChannel,SVGCompliance,tuple);
932 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
933 ConcatenateColorComponent(&color,GreenChannel,SVGCompliance,tuple);
934 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
935 ConcatenateColorComponent(&color,BlueChannel,SVGCompliance,tuple);
936 if (color.colorspace == CMYKColorspace)
938 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
939 ConcatenateColorComponent(&color,IndexChannel,SVGCompliance,tuple);
941 if (color.matte != MagickFalse)
943 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
944 ConcatenateColorComponent(&color,AlphaChannel,SVGCompliance,tuple);
946 (void) ConcatenateMagickString(tuple,")",MaxTextExtent);
952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
956 + I n i t i a l i z e C o l o r L i s t %
960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
962 % InitializeColorList() initializes the color list.
964 % The format of the InitializeColorList method is:
966 % MagickBooleanType InitializeColorList(ExceptionInfo *exception)
968 % A description of each parameter follows.
970 % o exception: return any errors or warnings in this structure.
973 static MagickBooleanType InitializeColorList(ExceptionInfo *exception)
975 if ((color_list == (LinkedListInfo *) NULL) &&
976 (instantiate_color == MagickFalse))
978 AcquireSemaphoreInfo(&color_semaphore);
979 if ((color_list == (LinkedListInfo *) NULL) &&
980 (instantiate_color == MagickFalse))
982 (void) LoadColorLists(ColorFilename,exception);
983 instantiate_color=MagickTrue;
985 RelinquishSemaphoreInfo(color_semaphore);
987 return(color_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995 + I s C o l o r S i m i l a r %
999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1001 % IsColorSimilar() returns MagickTrue if the distance between two colors is
1002 % less than the specified distance in a linear three dimensional color space.
1003 % This method is used by ColorFloodFill() and other algorithms which
1004 % compare two colors.
1006 % The format of the IsColorSimilar method is:
1008 % void IsColorSimilar(const Image *image,const PixelPacket *p,
1009 % const PixelPacket *q)
1011 % A description of each parameter follows:
1013 % o image: the image.
1021 static inline double MagickMax(const double x,const double y)
1028 MagickExport MagickBooleanType IsColorSimilar(const Image *image,
1029 const PixelPacket *p,const PixelPacket *q)
1035 register MagickRealType
1040 if ((image->fuzz == 0.0) && (image->matte == MagickFalse))
1041 return(IsColorEqual(p,q));
1042 fuzz=3.0*MagickMax(image->fuzz,MagickSQ1_2)*MagickMax(image->fuzz,
1046 if (image->matte != MagickFalse)
1048 alpha=(MagickRealType) (QuantumScale*(QuantumRange-p->opacity));
1049 beta=(MagickRealType) (QuantumScale*(QuantumRange-q->opacity));
1051 pixel=alpha*p->red-beta*q->red;
1052 distance=pixel*pixel;
1053 if (distance > fuzz)
1054 return(MagickFalse);
1055 pixel=alpha*p->green-beta*q->green;
1056 distance+=pixel*pixel;
1057 if (distance > fuzz)
1058 return(MagickFalse);
1059 pixel=alpha*p->blue-beta*q->blue;
1060 distance+=pixel*pixel;
1061 if (distance > fuzz)
1062 return(MagickFalse);
1067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1071 % I s G r a y I m a g e %
1075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1077 % IsGrayImage() returns MagickTrue if all the pixels in the image have the
1078 % same red, green, and blue intensities.
1080 % The format of the IsGrayImage method is:
1082 % MagickBooleanType IsGrayImage(const Image *image,
1083 % ExceptionInfo *exception)
1085 % A description of each parameter follows:
1087 % o image: the image.
1089 % o exception: return any errors or warnings in this structure.
1092 MagickExport MagickBooleanType IsGrayImage(const Image *image,
1093 ExceptionInfo *exception)
1098 register const PixelPacket
1101 assert(image != (Image *) NULL);
1102 assert(image->signature == MagickSignature);
1103 if (image->debug != MagickFalse)
1104 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1105 if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
1106 (image->type == GrayscaleMatteType))
1108 if (image->colorspace == CMYKColorspace)
1109 return(MagickFalse);
1111 switch (image->storage_class)
1114 case UndefinedClass:
1125 image_view=AcquireCacheView(image);
1126 for (y=0; y < (long) image->rows; y++)
1128 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1129 if (p == (const PixelPacket *) NULL)
1131 for (x=0; x < (long) image->columns; x++)
1133 if (IsGrayPixel(p) == MagickFalse)
1138 if ((type == BilevelType) && (IsMonochromePixel(p) == MagickFalse))
1142 if (type == UndefinedType)
1145 image_view=DestroyCacheView(image_view);
1154 for (i=0; i < (long) image->colors; i++)
1156 if (IsGrayPixel(p) == MagickFalse)
1161 if ((type == BilevelType) && (IsMonochromePixel(p) == MagickFalse))
1168 if (type == UndefinedType)
1169 return(MagickFalse);
1170 ((Image *) image)->type=type;
1171 if ((type == GrayscaleType) && (image->matte != MagickFalse))
1172 ((Image *) image)->type=GrayscaleMatteType;
1177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1181 + I s I m a g e S i m i l a r %
1185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1187 % IsImageSimilar() returns true if the target is similar to a region of the
1190 % The format of the IsImageSimilar method is:
1192 % MagickBooleanType IsImageSimilar(const Image *image,
1193 % const Image *target_image,long *x_offset,long *y_offset,
1194 % ExceptionInfo *exception)
1196 % A description of each parameter follows:
1198 % o image: the image.
1200 % o target_image: the target image.
1202 % o x_offset: On input the starting x position to search for a match;
1203 % on output the x position of the first match found.
1205 % o y_offset: On input the starting y position to search for a match;
1206 % on output the y position of the first match found.
1208 % o exception: return any errors or warnings in this structure.
1211 MagickExport MagickBooleanType IsImageSimilar(const Image *image,
1212 const Image *target_image,long *x_offset,long *y_offset,
1213 ExceptionInfo *exception)
1215 #define SearchImageText " Searching image... "
1228 register const PixelPacket
1232 register const IndexPacket
1244 assert(image != (Image *) NULL);
1245 assert(image->signature == MagickSignature);
1246 if (image->debug != MagickFalse)
1247 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1248 assert(target_image != (Image *) NULL);
1249 assert(target_image->signature == MagickSignature);
1250 assert(x_offset != (long *) NULL);
1251 assert(y_offset != (long *) NULL);
1252 assert(exception != (ExceptionInfo *) NULL);
1254 GetMagickPixelPacket(image,&pixel);
1255 GetMagickPixelPacket(image,&target);
1256 image_view=AcquireCacheView(image);
1257 target_view=AcquireCacheView(target_image);
1258 for (y=(*y_offset); y < (long) image->rows; y++)
1260 for (x=y == 0 ? *x_offset : 0; x < (long) image->columns; x++)
1262 for (j=0; j < (long) target_image->rows; j++)
1264 for (i=0; i < (long) target_image->columns; i++)
1266 p=GetCacheViewVirtualPixels(image_view,x+i,y+j,1,1,exception);
1267 indexes=GetCacheViewVirtualIndexQueue(image_view);
1268 SetMagickPixelPacket(image,p,indexes,&pixel);
1269 q=GetCacheViewVirtualPixels(target_view,i,j,1,1,exception);
1270 target_indexes=GetCacheViewVirtualIndexQueue(target_view);
1271 SetMagickPixelPacket(image,q,target_indexes,&target);
1272 if (IsMagickColorSimilar(&pixel,&target) == MagickFalse)
1275 if (i < (long) target_image->columns)
1278 if (j == (long) target_image->rows)
1281 if (x < (long) image->columns)
1283 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1284 (QuantumTick(y,image->rows) != MagickFalse))
1286 status=image->progress_monitor(SearchImageText,y,image->rows,
1287 image->client_data);
1288 if (status == MagickFalse)
1292 target_view=DestroyCacheView(target_view);
1293 image_view=DestroyCacheView(image_view);
1296 return(y < (long) image->rows ? MagickTrue : MagickFalse);
1300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1304 + I s M a g i c k C o l o r S i m i l a r %
1308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1310 % IsMagickColorSimilar() returns true if the distance between two colors is
1311 % less than the specified distance in a linear three dimensional color space.
1312 % This method is used by ColorFloodFill() and other algorithms which
1313 % compare two colors.
1315 % The format of the IsMagickColorSimilar method is:
1317 % MagickBooleanType IsMagickColorSimilar(const MagickPixelPacket *p,
1318 % const MagickPixelPacket *q)
1320 % A description of each parameter follows:
1327 MagickExport MagickBooleanType IsMagickColorSimilar(const MagickPixelPacket *p,
1328 const MagickPixelPacket *q)
1334 register MagickRealType
1339 if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
1340 return(IsMagickColorEqual(p,q));
1342 fuzz=MagickMax(q->fuzz,MagickSQ1_2)*MagickMax(q->fuzz,MagickSQ1_2);
1345 fuzz=3.0*MagickMax(p->fuzz,MagickSQ1_2)*MagickMax(p->fuzz,MagickSQ1_2);
1347 fuzz=3.0*MagickMax(p->fuzz,MagickSQ1_2)*MagickMax(q->fuzz,MagickSQ1_2);
1349 if (p->matte != MagickFalse)
1350 alpha=(MagickRealType) (QuantumScale*(QuantumRange-p->opacity));
1352 if (q->matte != MagickFalse)
1353 beta=(MagickRealType) (QuantumScale*(QuantumRange-q->opacity));
1354 if (p->colorspace == CMYKColorspace)
1356 alpha*=(MagickRealType) (QuantumScale*(QuantumRange-p->index));
1357 beta*=(MagickRealType) (QuantumScale*(QuantumRange-q->index));
1359 pixel=alpha*p->red-beta*q->red;
1360 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
1361 (p->colorspace == HWBColorspace))
1363 if (fabs(p->red-q->red) > (QuantumRange/2))
1365 if (p->red > (QuantumRange/2))
1366 pixel=alpha*(p->red-QuantumRange)-beta*q->red;
1368 pixel=alpha*p->red-beta*(q->red-QuantumRange);
1372 distance=pixel*pixel;
1373 if (distance > fuzz)
1374 return(MagickFalse);
1375 pixel=alpha*p->green-beta*q->green;
1376 distance+=pixel*pixel;
1377 if (distance > fuzz)
1378 return(MagickFalse);
1379 pixel=alpha*p->blue-beta*q->blue;
1380 distance+=pixel*pixel;
1381 if (distance > fuzz)
1382 return(MagickFalse);
1383 pixel=p->opacity-q->opacity;
1384 distance+=pixel*pixel;
1385 if (distance > fuzz)
1386 return(MagickFalse);
1391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1395 % I s M o n o c h r o m e I m a g e %
1399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1401 % IsMonochromeImage() returns MagickTrue if all the pixels in the image have
1402 % the same red, green, and blue intensities and the intensity is either
1403 % 0 or QuantumRange.
1405 % The format of the IsMonochromeImage method is:
1407 % MagickBooleanType IsMonochromeImage(const Image *image,
1408 % ExceptionInfo *exception)
1410 % A description of each parameter follows:
1412 % o image: the image.
1414 % o exception: return any errors or warnings in this structure.
1417 MagickExport MagickBooleanType IsMonochromeImage(const Image *image,
1418 ExceptionInfo *exception)
1423 register const PixelPacket
1426 assert(image != (Image *) NULL);
1427 assert(image->signature == MagickSignature);
1428 if (image->debug != MagickFalse)
1429 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1430 if (image->type == BilevelType)
1432 if (image->colorspace == CMYKColorspace)
1433 return(MagickFalse);
1435 switch (image->storage_class)
1438 case UndefinedClass:
1449 image_view=AcquireCacheView(image);
1450 for (y=0; y < (long) image->rows; y++)
1452 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1453 if (p == (const PixelPacket *) NULL)
1455 for (x=0; x < (long) image->columns; x++)
1457 if (IsMonochromePixel(p) == MagickFalse)
1464 if (type == UndefinedType)
1467 image_view=DestroyCacheView(image_view);
1468 if (y == (long) image->rows)
1469 ((Image *) image)->type=BilevelType;
1478 for (i=0; i < (long) image->colors; i++)
1480 if (IsMonochromePixel(p) == MagickFalse)
1490 if (type == UndefinedType)
1491 return(MagickFalse);
1492 ((Image *) image)->type=type;
1497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1501 + I s O p a c i t y S i m i l a r %
1505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1507 % IsOpacitySimilar() returns true if the distance between two opacity
1508 % values is less than the specified distance in a linear color space. This
1509 % method is used by MatteFloodFill() and other algorithms which compare
1510 % two opacity values.
1512 % The format of the IsOpacitySimilar method is:
1514 % void IsOpacitySimilar(const Image *image,const PixelPacket *p,
1515 % const PixelPacket *q)
1517 % A description of each parameter follows:
1519 % o image: the image.
1526 MagickExport MagickBooleanType IsOpacitySimilar(const Image *image,
1527 const PixelPacket *p,const PixelPacket *q)
1533 register MagickRealType
1536 if (image->matte == MagickFalse)
1538 if (p->opacity == q->opacity)
1540 fuzz=MagickMax(image->fuzz,MagickSQ1_2)*MagickMax(image->fuzz,MagickSQ1_2);
1541 pixel=(MagickRealType) p->opacity-(MagickRealType) q->opacity;
1542 distance=pixel*pixel;
1543 if (distance > fuzz)
1544 return(MagickFalse);
1549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1553 % I s O p a q u e I m a g e %
1557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1559 % IsOpaqueImage() returns MagickTrue if none of the pixels in the image have
1560 % an opacity value other than opaque (0).
1562 % The format of the IsOpaqueImage method is:
1564 % MagickBooleanType IsOpaqueImage(const Image *image,
1565 % ExceptionInfo *exception)
1567 % A description of each parameter follows:
1569 % o image: the image.
1571 % o exception: return any errors or warnings in this structure.
1574 MagickExport MagickBooleanType IsOpaqueImage(const Image *image,
1575 ExceptionInfo *exception)
1580 register const PixelPacket
1590 Determine if image is opaque.
1592 assert(image != (Image *) NULL);
1593 assert(image->signature == MagickSignature);
1594 if (image->debug != MagickFalse)
1595 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1596 if (image->matte == MagickFalse)
1598 image_view=AcquireCacheView(image);
1599 for (y=0; y < (long) image->rows; y++)
1601 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1602 if (p == (const PixelPacket *) NULL)
1604 for (x=0; x < (long) image->columns; x++)
1606 if (p->opacity != OpaqueOpacity)
1610 if (x < (long) image->columns)
1613 image_view=DestroyCacheView(image_view);
1614 return(y < (long) image->rows ? MagickFalse : MagickTrue);
1618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1622 % L i s t C o l o r I n f o %
1626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1628 % ListColorInfo() lists color names to the specified file. Color names
1629 % are a convenience. Rather than defining a color by its red, green, and
1630 % blue intensities just use a color name such as white, blue, or yellow.
1632 % The format of the ListColorInfo method is:
1634 % MagickBooleanType ListColorInfo(FILE *file,ExceptionInfo *exception)
1636 % A description of each parameter follows.
1638 % o file: List color names to this file handle.
1640 % o exception: return any errors or warnings in this structure.
1643 MagickExport MagickBooleanType ListColorInfo(FILE *file,
1644 ExceptionInfo *exception)
1647 tuple[MaxTextExtent];
1662 List name and attributes of each color in the list.
1664 if (file == (const FILE *) NULL)
1666 color_info=GetColorInfoList("*",&number_colors,exception);
1667 if (color_info == (const ColorInfo **) NULL)
1668 return(MagickFalse);
1669 path=(const char *) NULL;
1670 for (i=0; i < (long) number_colors; i++)
1672 if (color_info[i]->stealth != MagickFalse)
1674 if ((path == (const char *) NULL) ||
1675 (LocaleCompare(path,color_info[i]->path) != 0))
1677 if (color_info[i]->path != (char *) NULL)
1678 (void) fprintf(file,"\nPath: %s\n\n",color_info[i]->path);
1679 (void) fprintf(file,"Name Color "
1681 (void) fprintf(file,"-------------------------------------------------"
1682 "------------------------------\n");
1684 path=color_info[i]->path;
1685 (void) fprintf(file,"%-21.21s ",color_info[i]->name);
1686 GetColorTuple(&color_info[i]->color,MagickFalse,tuple);
1687 (void) fprintf(file,"%-45.45s ",tuple);
1688 if ((color_info[i]->compliance & SVGCompliance) != 0)
1689 (void) fprintf(file,"SVG ");
1690 if ((color_info[i]->compliance & X11Compliance) != 0)
1691 (void) fprintf(file,"X11 ");
1692 if ((color_info[i]->compliance & XPMCompliance) != 0)
1693 (void) fprintf(file,"XPM ");
1694 (void) fprintf(file,"\n");
1696 color_info=(const ColorInfo **) RelinquishMagickMemory((void *) color_info);
1697 (void) fflush(file);
1702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1706 + L o a d C o l o r L i s t %
1710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1712 % LoadColorList() loads the color configuration file which provides a mapping
1713 % between color attributes and a color name.
1715 % The format of the LoadColorList method is:
1717 % MagickBooleanType LoadColorList(const char *xml,const char *filename,
1718 % const unsigned long depth,ExceptionInfo *exception)
1720 % A description of each parameter follows:
1722 % o xml: The color list in XML format.
1724 % o filename: The color list filename.
1726 % o depth: depth of <include /> statements.
1728 % o exception: return any errors or warnings in this structure.
1731 static MagickBooleanType LoadColorList(const char *xml,const char *filename,
1732 const unsigned long depth,ExceptionInfo *exception)
1735 keyword[MaxTextExtent],
1748 Load the color map file.
1750 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1751 "Loading color file \"%s\" ...",filename);
1752 if (xml == (char *) NULL)
1753 return(MagickFalse);
1754 if (color_list == (LinkedListInfo *) NULL)
1756 color_list=NewLinkedList(0);
1757 if (color_list == (LinkedListInfo *) NULL)
1759 ThrowFileException(exception,ResourceLimitError,
1760 "MemoryAllocationFailed",filename);
1761 return(MagickFalse);
1765 color_info=(ColorInfo *) NULL;
1766 token=AcquireString(xml);
1767 for (q=(char *) xml; *q != '\0'; )
1772 GetMagickToken(q,&q,token);
1775 (void) CopyMagickString(keyword,token,MaxTextExtent);
1776 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1781 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1782 GetMagickToken(q,&q,token);
1785 if (LocaleNCompare(keyword,"<!--",4) == 0)
1790 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1791 GetMagickToken(q,&q,token);
1794 if (LocaleCompare(keyword,"<include") == 0)
1799 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1801 (void) CopyMagickString(keyword,token,MaxTextExtent);
1802 GetMagickToken(q,&q,token);
1805 GetMagickToken(q,&q,token);
1806 if (LocaleCompare(keyword,"file") == 0)
1809 (void) ThrowMagickException(exception,GetMagickModule(),
1810 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1814 path[MaxTextExtent],
1817 GetPathComponent(filename,HeadPath,path);
1819 (void) ConcatenateMagickString(path,DirectorySeparator,
1821 if (*token == *DirectorySeparator)
1822 (void) CopyMagickString(path,token,MaxTextExtent);
1824 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1825 xml=FileToString(path,~0,exception);
1826 if (xml != (char *) NULL)
1828 status=LoadColorList(xml,path,depth+1,exception);
1829 xml=(char *) RelinquishMagickMemory(xml);
1836 if (LocaleCompare(keyword,"<color") == 0)
1841 color_info=(ColorInfo *) AcquireMagickMemory(sizeof(*color_info));
1842 if (color_info == (ColorInfo *) NULL)
1843 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1844 (void) ResetMagickMemory(color_info,0,sizeof(*color_info));
1845 color_info->path=ConstantString(filename);
1846 color_info->signature=MagickSignature;
1849 if (color_info == (ColorInfo *) NULL)
1851 if (LocaleCompare(keyword,"/>") == 0)
1853 status=AppendValueToLinkedList(color_list,color_info);
1854 if (status == MagickFalse)
1855 (void) ThrowMagickException(exception,GetMagickModule(),
1856 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1858 color_info=(ColorInfo *) NULL;
1860 GetMagickToken(q,(const char **) NULL,token);
1863 GetMagickToken(q,&q,token);
1864 GetMagickToken(q,&q,token);
1870 if (LocaleCompare((char *) keyword,"color") == 0)
1872 (void) QueryMagickColor(token,&color_info->color,exception);
1875 if (LocaleCompare((char *) keyword,"compliance") == 0)
1880 compliance=color_info->compliance;
1881 if (GlobExpression(token,"*SVG*",MagickTrue) != MagickFalse)
1882 compliance|=SVGCompliance;
1883 if (GlobExpression(token,"*X11*",MagickTrue) != MagickFalse)
1884 compliance|=X11Compliance;
1885 if (GlobExpression(token,"*XPM*",MagickTrue) != MagickFalse)
1886 compliance|=XPMCompliance;
1887 color_info->compliance=(ComplianceType) compliance;
1895 if (LocaleCompare((char *) keyword,"name") == 0)
1897 color_info->name=ConstantString(token);
1905 if (LocaleCompare((char *) keyword,"stealth") == 0)
1907 color_info->stealth=IsMagickTrue(token);
1916 token=(char *) RelinquishMagickMemory(token);
1921 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1925 % L o a d C o l o r L i s t s %
1929 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1931 % LoadColorList() loads one or more color configuration file which provides a
1932 % mapping between color attributes and a color name.
1934 % The format of the LoadColorLists method is:
1936 % MagickBooleanType LoadColorLists(const char *filename,
1937 % ExceptionInfo *exception)
1939 % A description of each parameter follows:
1941 % o filename: the font file name.
1943 % o exception: return any errors or warnings in this structure.
1946 static MagickBooleanType LoadColorLists(const char *filename,
1947 ExceptionInfo *exception)
1949 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
1950 return(LoadColorList(ColorMap,"built-in",0,exception));
1962 options=GetConfigureOptions(filename,exception);
1963 option=(const StringInfo *) GetNextValueInLinkedList(options);
1964 while (option != (const StringInfo *) NULL)
1966 status|=LoadColorList((const char *) GetStringInfoDatum(option),
1967 GetStringInfoPath(option),0,exception);
1968 option=(const StringInfo *) GetNextValueInLinkedList(options);
1970 options=DestroyConfigureOptions(options);
1971 if ((color_list == (LinkedListInfo *) NULL) ||
1972 (IsLinkedListEmpty(color_list) != MagickFalse))
1973 status|=LoadColorList(ColorMap,"built-in",0,exception);
1974 return(status != 0 ? MagickTrue : MagickFalse);
1979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1983 % Q u e r y C o l o r D a t a b a s e %
1987 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1989 % QueryColorDatabase() returns the red, green, blue, and opacity intensities
1990 % for a given color name.
1992 % The format of the QueryColorDatabase method is:
1994 % MagickBooleanType QueryColorDatabase(const char *name,PixelPacket *color,
1995 % ExceptionInfo *exception)
1997 % A description of each parameter follows:
1999 % o name: the color name (e.g. white, blue, yellow).
2001 % o color: the red, green, blue, and opacity intensities values of the
2002 % named color in this structure.
2004 % o exception: return any errors or warnings in this structure.
2008 static inline double MagickMin(const double x,const double y)
2015 MagickExport MagickBooleanType QueryColorDatabase(const char *name,
2016 PixelPacket *color,ExceptionInfo *exception)
2024 status=QueryMagickColor(name,&pixel,exception);
2025 color->opacity=RoundToQuantum(pixel.opacity);
2026 if (pixel.colorspace == CMYKColorspace)
2028 color->red=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
2029 QuantumRange,(MagickRealType) (QuantumScale*pixel.red*(QuantumRange-
2030 pixel.index)+pixel.index))));
2031 color->green=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
2032 QuantumRange,(MagickRealType) (QuantumScale*pixel.green*(QuantumRange-
2033 pixel.index)+pixel.index))));
2034 color->blue=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
2035 QuantumRange,(MagickRealType) (QuantumScale*pixel.blue*(QuantumRange-
2036 pixel.index)+pixel.index))));
2039 color->red=RoundToQuantum(pixel.red);
2040 color->green=RoundToQuantum(pixel.green);
2041 color->blue=RoundToQuantum(pixel.blue);
2046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2050 % Q u e r y C o l o r n a m e %
2054 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2056 % QueryColorname() returns a named color for the given color intensity. If
2057 % an exact match is not found, a rgb() color is returned instead.
2059 % The format of the QueryColorname method is:
2061 % MagickBooleanType QueryColorname(const Image *image,
2062 % const PixelPacket *color,const ComplianceType compliance,char *name,
2063 % ExceptionInfo *exception)
2065 % A description of each parameter follows.
2067 % o image: the image.
2069 % o color: the color intensities.
2071 % o compliance: Adhere to this color standard: SVG, X11, or XPM.
2073 % o name: Return the color name or hex value.
2075 % o exception: return any errors or warnings in this structure.
2078 MagickExport MagickBooleanType QueryColorname(const Image *image,
2079 const PixelPacket *color,const ComplianceType compliance,char *name,
2080 ExceptionInfo *exception)
2085 GetMagickPixelPacket(image,&pixel);
2086 SetMagickPixelPacket(image,color,(IndexPacket *) NULL,&pixel);
2087 return(QueryMagickColorname(image,&pixel,compliance,name,exception));
2091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2095 % Q u e r y M a g i c k C o l o r %
2099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2101 % QueryMagickColor() returns the red, green, blue, and opacity intensities
2102 % for a given color name.
2104 % The format of the QueryMagickColor method is:
2106 % MagickBooleanType QueryMagickColor(const char *name,
2107 % MagickPixelPacket *color,ExceptionInfo *exception)
2109 % A description of each parameter follows:
2111 % o name: the color name (e.g. white, blue, yellow).
2113 % o color: the red, green, blue, and opacity intensities values of the
2114 % named color in this structure.
2116 % o exception: return any errors or warnings in this structure.
2119 MagickExport MagickBooleanType QueryMagickColor(const char *name,
2120 MagickPixelPacket *color,ExceptionInfo *exception)
2134 register const ColorInfo
2141 Initialize color return value.
2143 assert(name != (const char *) NULL);
2144 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
2145 assert(color != (MagickPixelPacket *) NULL);
2146 GetMagickPixelPacket((Image *) NULL,color);
2147 if ((name == (char *) NULL) || (*name == '\0'))
2148 name=BackgroundColor;
2149 while (isspace((int) ((unsigned char) *name)) != 0)
2169 (void) ResetMagickMemory(&pixel,0,sizeof(pixel));
2171 for (n=0; isxdigit((int) ((unsigned char) name[n])) != MagickFalse; n++) ;
2176 pixel.red=pixel.green;
2177 pixel.green=pixel.blue;
2179 for (i=(long) (n/3-1); i >= 0; i--)
2183 if ((c >= '0') && (c <= '9'))
2184 pixel.blue|=(int) (c-'0');
2186 if ((c >= 'A') && (c <= 'F'))
2187 pixel.blue|=(int) c-((int) 'A'-10);
2189 if ((c >= 'a') && (c <= 'f'))
2190 pixel.blue|=(int) c-((int) 'a'-10);
2192 return(MagickFalse);
2194 } while (isxdigit((int) ((unsigned char) *name)) != MagickFalse);
2201 (void) ThrowMagickException(exception,GetMagickModule(),
2202 OptionWarning,"UnrecognizedColor","`%s'",name);
2203 return(MagickFalse);
2207 pixel.red=pixel.green;
2208 pixel.green=pixel.blue;
2209 pixel.blue=pixel.opacity;
2211 for (i=(long) (n/4-1); i >= 0; i--)
2215 if ((c >= '0') && (c <= '9'))
2216 pixel.opacity|=(int) (c-'0');
2218 if ((c >= 'A') && (c <= 'F'))
2219 pixel.opacity|=(int) c-((int) 'A'-10);
2221 if ((c >= 'a') && (c <= 'f'))
2222 pixel.opacity|=(int) c-((int) 'a'-10);
2224 return(MagickFalse);
2226 } while (isxdigit((int) ((unsigned char) *name)) != MagickFalse);
2229 color->colorspace=RGBColorspace;
2230 color->matte=MagickFalse;
2231 range=GetQuantumRange(depth);
2232 color->red=(MagickRealType) ScaleAnyToQuantum(pixel.red,range);
2233 color->green=(MagickRealType) ScaleAnyToQuantum(pixel.green,range);
2234 color->blue=(MagickRealType) ScaleAnyToQuantum(pixel.blue,range);
2235 color->opacity=(MagickRealType) OpaqueOpacity;
2238 color->matte=MagickTrue;
2239 color->opacity=(MagickRealType) (QuantumRange-ScaleAnyToQuantum(
2240 pixel.opacity,range));
2245 if (strchr(name,'(') != (char *) NULL)
2248 colorspace[MaxTextExtent];
2251 Parse color of the form rgb(100,255,0).
2253 (void) CopyMagickString(colorspace,name,MaxTextExtent);
2254 for (i=0; colorspace[i] != '\0'; i++)
2255 if (colorspace[i] == '(')
2257 colorspace[i--]='\0';
2258 LocaleLower(colorspace);
2259 color->matte=MagickFalse;
2260 if ((i > 0) && (colorspace[i] == 'a'))
2263 color->matte=MagickTrue;
2265 type=ParseMagickOption(MagickColorspaceOptions,MagickFalse,colorspace);
2268 (void) ThrowMagickException(exception,GetMagickModule(),
2269 OptionWarning,"UnrecognizedColor","`%s'",name);
2270 return(MagickFalse);
2272 color->colorspace=(ColorspaceType) type;
2273 SetGeometryInfo(&geometry_info);
2274 flags=ParseGeometry(name+i+1,&geometry_info);
2275 scale=(MagickRealType) ScaleCharToQuantum(1);
2276 if ((flags & PercentValue) != 0)
2277 scale=(MagickRealType) (QuantumRange/100.0);
2278 if ((flags & RhoValue) != 0)
2279 color->red=(MagickRealType) RoundToQuantum(scale*geometry_info.rho);
2280 if ((flags & SigmaValue) != 0)
2281 color->green=(MagickRealType) RoundToQuantum(scale*geometry_info.sigma);
2282 if ((flags & XiValue) != 0)
2283 color->blue=(MagickRealType) RoundToQuantum(scale*geometry_info.xi);
2284 color->opacity=(MagickRealType) OpaqueOpacity;
2285 if ((flags & PsiValue) != 0)
2287 if (color->colorspace == CMYKColorspace)
2288 color->index=(MagickRealType) RoundToQuantum(scale*
2291 if (color->matte != MagickFalse)
2292 color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
2293 (QuantumRange-QuantumRange*geometry_info.psi));
2295 if (((flags & ChiValue) != 0) && (color->matte != MagickFalse))
2296 color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
2297 (QuantumRange-QuantumRange*geometry_info.chi));
2298 if (LocaleCompare(colorspace,"gray") == 0)
2300 color->green=color->red;
2301 color->blue=color->red;
2302 if (((flags & SigmaValue) != 0) && (color->matte != MagickFalse))
2303 color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
2304 (QuantumRange-QuantumRange*geometry_info.sigma));
2306 if ((LocaleCompare(colorspace,"HSB") == 0) ||
2307 (LocaleCompare(colorspace,"HSL") == 0) ||
2308 (LocaleCompare(colorspace,"HWB") == 0))
2314 if ((flags & PercentValue) != 0)
2316 geometry_info.rho*=360.0*scale;
2318 if ((flags & PercentValue) != 0)
2320 geometry_info.sigma*=scale;
2321 geometry_info.xi*=scale;
2322 if (LocaleCompare(colorspace,"HSB") == 0)
2323 ConvertHSBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
2324 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
2325 &pixel.green,&pixel.blue);
2327 if (LocaleCompare(colorspace,"HSL") == 0)
2328 ConvertHSLToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
2329 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
2330 &pixel.green,&pixel.blue);
2332 ConvertHWBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
2333 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
2334 &pixel.green,&pixel.blue);
2335 color->colorspace=RGBColorspace;
2336 color->red=(MagickRealType) pixel.red;
2337 color->green=(MagickRealType) pixel.green;
2338 color->blue=(MagickRealType) pixel.blue;
2345 p=GetColorInfo(name,exception);
2346 if (p == (const ColorInfo *) NULL)
2347 return(MagickFalse);
2348 color->colorspace=RGBColorspace;
2349 color->matte=p->color.opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
2350 color->red=(MagickRealType) p->color.red;
2351 color->green=(MagickRealType) p->color.green;
2352 color->blue=(MagickRealType) p->color.blue;
2353 color->opacity=(MagickRealType) p->color.opacity;
2359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2363 % Q u e r y M a g i c k C o l o r n a m e %
2367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2369 % QueryMagickColorname() returns a named color for the given color intensity.
2370 % If an exact match is not found, a hex value is returned instead. For
2371 % example an intensity of rgb:(0,0,0) returns black whereas rgb:(223,223,223)
2374 % The format of the QueryMagickColorname method is:
2376 % MagickBooleanType QueryMagickColorname(const Image *image,
2377 % const PixelPacket *color,const ComplianceType compliance,char *name,
2378 % ExceptionInfo *exception)
2380 % A description of each parameter follows.
2382 % o image: the image.
2384 % o color: the color intensities.
2386 % o Compliance: Adhere to this color standard: SVG, X11, or XPM.
2388 % o name: Return the color name or hex value.
2390 % o exception: return any errors or warnings in this structure.
2393 MagickExport MagickBooleanType QueryMagickColorname(const Image *image,
2394 const MagickPixelPacket *color,const ComplianceType compliance,
2395 char *name,ExceptionInfo *exception)
2403 register const ColorInfo
2408 if (compliance == XPMCompliance)
2410 pixel.matte=MagickFalse;
2411 pixel.depth=(unsigned long) MagickMin(1.0*image->depth,16.0);
2412 GetColorTuple(&pixel,MagickTrue,name);
2415 GetColorTuple(&pixel,compliance != SVGCompliance ? MagickTrue : MagickFalse,
2417 (void) GetColorInfo("*",exception);
2418 ResetLinkedListIterator(color_list);
2419 opacity=image->matte != MagickFalse ? color->opacity : OpaqueOpacity;
2420 p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
2421 while (p != (const ColorInfo *) NULL)
2423 if (((p->compliance & compliance) != 0) && ((p->color.red == color->red)) &&
2424 (p->color.green == color->green) && (p->color.blue == color->blue) &&
2425 (p->color.opacity == opacity))
2427 (void) CopyMagickString(name,p->name,MaxTextExtent);
2430 p=(const ColorInfo *) GetNextValueInLinkedList(color_list);