color.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                       CCCC   OOO   L       OOO   RRRR                       %
00006 %                      C      O   O  L      O   O  R   R                      %
00007 %                      C      O   O  L      O   O  RRRR                       %
00008 %                      C      O   O  L      O   O  R R                        %
00009 %                       CCCC   OOO   LLLLL   OOO   R  R                       %
00010 %                                                                             %
00011 %                                                                             %
00012 %                          MagickCore Color Methods                           %
00013 %                                                                             %
00014 %                              Software Design                                %
00015 %                                John Cristy                                  %
00016 %                                 July 1992                                   %
00017 %                                                                             %
00018 %                                                                             %
00019 %  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
00020 %  dedicated to making software imaging solutions freely available.           %
00021 %                                                                             %
00022 %  You may not use this file except in compliance with the License.  You may  %
00023 %  obtain a copy of the License at                                            %
00024 %                                                                             %
00025 %    http://www.imagemagick.org/script/license.php                            %
00026 %                                                                             %
00027 %  Unless required by applicable law or agreed to in writing, software        %
00028 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00029 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00030 %  See the License for the specific language governing permissions and        %
00031 %  limitations under the License.                                             %
00032 %                                                                             %
00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00034 %
00035 %  We use linked-lists because splay-trees do not currently support duplicate
00036 %  key / value pairs (.e.g X11 green compliance and SVG green compliance).
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
00042 */
00043 #include "magick/studio.h"
00044 #include "magick/blob.h"
00045 #include "magick/cache-view.h"
00046 #include "magick/cache.h"
00047 #include "magick/color.h"
00048 #include "magick/color-private.h"
00049 #include "magick/client.h"
00050 #include "magick/configure.h"
00051 #include "magick/exception.h"
00052 #include "magick/exception-private.h"
00053 #include "magick/gem.h"
00054 #include "magick/geometry.h"
00055 #include "magick/image-private.h"
00056 #include "magick/memory_.h"
00057 #include "magick/monitor.h"
00058 #include "magick/monitor-private.h"
00059 #include "magick/option.h"
00060 #include "magick/pixel-private.h"
00061 #include "magick/quantize.h"
00062 #include "magick/quantum.h"
00063 #include "magick/semaphore.h"
00064 #include "magick/string_.h"
00065 #include "magick/token.h"
00066 #include "magick/utility.h"
00067 #include "magick/xml-tree.h"
00068 
00069 /*
00070   Define declarations.
00071 */
00072 #define ColorFilename  "colors.xml"
00073 
00074 /*
00075   Typedef declarations.
00076 */
00077 typedef struct _ColorMapInfo
00078 {
00079   const char
00080     *name;
00081 
00082   const float
00083     red,
00084     green,
00085     blue,
00086     alpha;
00087 
00088   const long
00089     compliance;
00090 } ColorMapInfo;
00091 
00092 /*
00093   Static declarations.
00094 */
00095 static const ColorMapInfo
00096   ColorMap[] =
00097   {
00098     { "none", 0, 0, 0, 0, SVGCompliance },
00099     { "black", 0, 0, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
00100     { "red", 255, 0, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
00101     { "magenta", 255, 0, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
00102     { "green", 0, 128, 0, 1, SVGCompliance },
00103     { "cyan", 0, 255, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
00104     { "blue", 0, 0, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
00105     { "yellow", 255, 255, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
00106     { "white", 255, 255, 255, 1, SVGCompliance | X11Compliance },
00107     { "AliceBlue", 240, 248, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
00108     { "AntiqueWhite", 250, 235, 215, 1, SVGCompliance | X11Compliance | XPMCompliance },
00109     { "AntiqueWhite1", 255, 239, 219, 1, X11Compliance },
00110     { "AntiqueWhite2", 238, 223, 204, 1, X11Compliance },
00111     { "AntiqueWhite3", 205, 192, 176, 1, X11Compliance },
00112     { "AntiqueWhite4", 139, 131, 120, 1, X11Compliance },
00113     { "aqua", 0, 255, 255, 1, SVGCompliance },
00114     { "aquamarine", 127, 255, 212, 1, SVGCompliance | X11Compliance | XPMCompliance },
00115     { "aquamarine1", 127, 255, 212, 1, X11Compliance },
00116     { "aquamarine2", 118, 238, 198, 1, X11Compliance },
00117     { "aquamarine3", 102, 205, 170, 1, X11Compliance },
00118     { "aquamarine4", 69, 139, 116, 1, X11Compliance },
00119     { "azure", 240, 255, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
00120     { "azure1", 240, 255, 255, 1, X11Compliance },
00121     { "azure2", 224, 238, 238, 1, X11Compliance },
00122     { "azure3", 193, 205, 205, 1, X11Compliance },
00123     { "azure4", 131, 139, 139, 1, X11Compliance },
00124     { "beige", 245, 245, 220, 1, SVGCompliance | X11Compliance | XPMCompliance },
00125     { "bisque", 255, 228, 196, 1, SVGCompliance | X11Compliance | XPMCompliance },
00126     { "bisque1", 255, 228, 196, 1, X11Compliance },
00127     { "bisque2", 238, 213, 183, 1, X11Compliance },
00128     { "bisque3", 205, 183, 158, 1, X11Compliance },
00129     { "bisque4", 139, 125, 107, 1, X11Compliance },
00130     { "BlanchedAlmond", 255, 235, 205, 1, SVGCompliance | X11Compliance | XPMCompliance },
00131     { "blue1", 0, 0, 255, 1, X11Compliance },
00132     { "blue2", 0, 0, 238, 1, X11Compliance },
00133     { "blue3", 0, 0, 205, 1, X11Compliance },
00134     { "blue4", 0, 0, 139, 1, X11Compliance },
00135     { "BlueViolet", 138, 43, 226, 1, SVGCompliance | X11Compliance | XPMCompliance },
00136     { "brown", 165, 42, 42, 1, SVGCompliance | X11Compliance | XPMCompliance },
00137     { "brown1", 255, 64, 64, 1, X11Compliance },
00138     { "brown2", 238, 59, 59, 1, X11Compliance },
00139     { "brown3", 205, 51, 51, 1, X11Compliance },
00140     { "brown4", 139, 35, 35, 1, X11Compliance },
00141     { "burlywood", 222, 184, 135, 1, SVGCompliance | X11Compliance | XPMCompliance },
00142     { "burlywood1", 255, 211, 155, 1, X11Compliance },
00143     { "burlywood2", 238, 197, 145, 1, X11Compliance },
00144     { "burlywood3", 205, 170, 125, 1, X11Compliance },
00145     { "burlywood4", 139, 115, 85, 1, X11Compliance },
00146     { "cadet blue", 95, 158, 160, 1, X11Compliance },
00147     { "CadetBlue", 95, 158, 160, 1, SVGCompliance | X11Compliance | XPMCompliance },
00148     { "CadetBlue1", 152, 245, 255, 1, X11Compliance },
00149     { "CadetBlue2", 142, 229, 238, 1, X11Compliance },
00150     { "CadetBlue3", 122, 197, 205, 1, X11Compliance },
00151     { "CadetBlue4", 83, 134, 139, 1, X11Compliance },
00152     { "chartreuse", 127, 255, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
00153     { "chartreuse1", 127, 255, 0, 1, X11Compliance },
00154     { "chartreuse2", 118, 238, 0, 1, X11Compliance },
00155     { "chartreuse3", 102, 205, 0, 1, X11Compliance },
00156     { "chartreuse4", 69, 139, 0, 1, X11Compliance },
00157     { "chocolate", 210, 105, 30, 1, SVGCompliance | X11Compliance | XPMCompliance },
00158     { "chocolate1", 255, 127, 36, 1, X11Compliance },
00159     { "chocolate2", 238, 118, 33, 1, X11Compliance },
00160     { "chocolate3", 205, 102, 29, 1, X11Compliance },
00161     { "chocolate4", 139, 69, 19, 1, X11Compliance },
00162     { "coral", 255, 127, 80, 1, SVGCompliance | X11Compliance | XPMCompliance },
00163     { "coral1", 255, 114, 86, 1, X11Compliance },
00164     { "coral2", 238, 106, 80, 1, X11Compliance },
00165     { "coral3", 205, 91, 69, 1, X11Compliance },
00166     { "coral4", 139, 62, 47, 1, X11Compliance },
00167     { "CornflowerBlue", 100, 149, 237, 1, SVGCompliance | X11Compliance | XPMCompliance },
00168     { "cornsilk", 255, 248, 220, 1, SVGCompliance | X11Compliance | XPMCompliance },
00169     { "cornsilk1", 255, 248, 220, 1, X11Compliance },
00170     { "cornsilk2", 238, 232, 205, 1, X11Compliance },
00171     { "cornsilk3", 205, 200, 177, 1, X11Compliance },
00172     { "cornsilk4", 139, 136, 120, 1, X11Compliance },
00173     { "crimson", 220, 20, 60, 1, SVGCompliance },
00174     { "cyan1", 0, 255, 255, 1, X11Compliance },
00175     { "cyan2", 0, 238, 238, 1, X11Compliance },
00176     { "cyan3", 0, 205, 205, 1, X11Compliance },
00177     { "cyan4", 0, 139, 139, 1, X11Compliance },
00178     { "dark violet", 148, 0, 211, 1, X11Compliance },
00179     { "DarkBlue", 0, 0, 139, 1, SVGCompliance | X11Compliance },
00180     { "DarkCyan", 0, 139, 139, 1, SVGCompliance | X11Compliance },
00181     { "DarkGoldenrod", 184, 134, 11, 1, SVGCompliance | X11Compliance | XPMCompliance },
00182     { "DarkGoldenrod1", 255, 185, 15, 1, X11Compliance },
00183     { "DarkGoldenrod2", 238, 173, 14, 1, X11Compliance },
00184     { "DarkGoldenrod3", 205, 149, 12, 1, X11Compliance },
00185     { "DarkGoldenrod4", 139, 101, 8, 1, X11Compliance },
00186     { "DarkGray", 169, 169, 169, 1, SVGCompliance | X11Compliance },
00187     { "DarkGreen", 0, 100, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
00188     { "DarkGrey", 169, 169, 169, 1, SVGCompliance | X11Compliance },
00189     { "DarkKhaki", 189, 183, 107, 1, SVGCompliance | X11Compliance | XPMCompliance },
00190     { "DarkMagenta", 139, 0, 139, 1, SVGCompliance | X11Compliance },
00191     { "DarkOliveGreen", 85, 107, 47, 1, SVGCompliance | X11Compliance | XPMCompliance },
00192     { "DarkOliveGreen1", 202, 255, 112, 1, X11Compliance },
00193     { "DarkOliveGreen2", 188, 238, 104, 1, X11Compliance },
00194     { "DarkOliveGreen3", 162, 205, 90, 1, X11Compliance },
00195     { "DarkOliveGreen4", 110, 139, 61, 1, X11Compliance },
00196     { "DarkOrange", 255, 140, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
00197     { "DarkOrange1", 255, 127, 0, 1, X11Compliance },
00198     { "DarkOrange2", 238, 118, 0, 1, X11Compliance },
00199     { "DarkOrange3", 205, 102, 0, 1, X11Compliance },
00200     { "DarkOrange4", 139, 69, 0, 1, X11Compliance },
00201     { "DarkOrchid", 153, 50, 204, 1, SVGCompliance | X11Compliance | XPMCompliance },
00202     { "DarkOrchid1", 191, 62, 255, 1, X11Compliance },
00203     { "DarkOrchid2", 178, 58, 238, 1, X11Compliance },
00204     { "DarkOrchid3", 154, 50, 205, 1, X11Compliance },
00205     { "DarkOrchid4", 104, 34, 139, 1, X11Compliance },
00206     { "DarkRed", 139, 0, 0, 1, SVGCompliance | X11Compliance },
00207     { "DarkSalmon", 233, 150, 122, 1, SVGCompliance | X11Compliance | XPMCompliance },
00208     { "DarkSeaGreen", 143, 188, 143, 1, SVGCompliance | X11Compliance | XPMCompliance },
00209     { "DarkSeaGreen1", 193, 255, 193, 1, X11Compliance },
00210     { "DarkSeaGreen2", 180, 238, 180, 1, X11Compliance },
00211     { "DarkSeaGreen3", 155, 205, 155, 1, X11Compliance },
00212     { "DarkSeaGreen4", 105, 139, 105, 1, X11Compliance },
00213     { "DarkSlateBlue", 72, 61, 139, 1, SVGCompliance | X11Compliance | XPMCompliance },
00214     { "DarkSlateGray", 47, 79, 79, 1, SVGCompliance | X11Compliance | XPMCompliance },
00215     { "DarkSlateGray1", 151, 255, 255, 1, X11Compliance },
00216     { "DarkSlateGray2", 141, 238, 238, 1, X11Compliance },
00217     { "DarkSlateGray3", 121, 205, 205, 1, X11Compliance },
00218     { "DarkSlateGray4", 82, 139, 139, 1, X11Compliance },
00219     { "DarkSlateGrey", 47, 79, 79, 1, SVGCompliance | X11Compliance },
00220     { "DarkTurquoise", 0, 206, 209, 1, SVGCompliance | X11Compliance | XPMCompliance },
00221     { "DarkViolet", 148, 0, 211, 1, SVGCompliance | X11Compliance | XPMCompliance },
00222     { "DeepPink", 255, 20, 147, 1, SVGCompliance | X11Compliance | XPMCompliance },
00223     { "DeepPink1", 255, 20, 147, 1, X11Compliance },
00224     { "DeepPink2", 238, 18, 137, 1, X11Compliance },
00225     { "DeepPink3", 205, 16, 118, 1, X11Compliance },
00226     { "DeepPink4", 139, 10, 80, 1, X11Compliance },
00227     { "DeepSkyBlue", 0, 191, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
00228     { "DeepSkyBlue1", 0, 191, 255, 1, X11Compliance },
00229     { "DeepSkyBlue2", 0, 178, 238, 1, X11Compliance },
00230     { "DeepSkyBlue3", 0, 154, 205, 1, X11Compliance },
00231     { "DeepSkyBlue4", 0, 104, 139, 1, X11Compliance },
00232     { "DimGray", 105, 105, 105, 1, SVGCompliance | X11Compliance | XPMCompliance },
00233     { "DimGrey", 105, 105, 105, 1, SVGCompliance | X11Compliance },
00234     { "DodgerBlue", 30, 144, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
00235     { "DodgerBlue1", 30, 144, 255, 1, X11Compliance },
00236     { "DodgerBlue2", 28, 134, 238, 1, X11Compliance },
00237     { "DodgerBlue3", 24, 116, 205, 1, X11Compliance },
00238     { "DodgerBlue4", 16, 78, 139, 1, X11Compliance },
00239     { "firebrick", 178, 34, 34, 1, SVGCompliance | X11Compliance | XPMCompliance },
00240     { "firebrick1", 255, 48, 48, 1, X11Compliance },
00241     { "firebrick2", 238, 44, 44, 1, X11Compliance },
00242     { "firebrick3", 205, 38, 38, 1, X11Compliance },
00243     { "firebrick4", 139, 26, 26, 1, X11Compliance },
00244     { "FloralWhite", 255, 250, 240, 1, SVGCompliance | X11Compliance | XPMCompliance },
00245     { "ForestGreen", 34, 139, 34, 1, SVGCompliance | X11Compliance | XPMCompliance },
00246     { "fractal", 128, 128, 128, 1, SVGCompliance },
00247     { "freeze", 0, 0, 0, 0, SVGCompliance },
00248     { "fuchsia", 255, 0, 255, 1, SVGCompliance },
00249     { "gainsboro", 220, 220, 220, 1, SVGCompliance | X11Compliance | XPMCompliance },
00250     { "GhostWhite", 248, 248, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
00251     { "gold", 255, 215, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
00252     { "gold1", 255, 215, 0, 1, X11Compliance },
00253     { "gold2", 238, 201, 0, 1, X11Compliance },
00254     { "gold3", 205, 173, 0, 1, X11Compliance },
00255     { "gold4", 139, 117, 0, 1, X11Compliance },
00256     { "goldenrod", 218, 165, 32, 1, SVGCompliance | X11Compliance | XPMCompliance },
00257     { "goldenrod1", 255, 193, 37, 1, X11Compliance },
00258     { "goldenrod2", 238, 180, 34, 1, X11Compliance },
00259     { "goldenrod3", 205, 155, 29, 1, X11Compliance },
00260     { "goldenrod4", 139, 105, 20, 1, X11Compliance },
00261     { "gray", 126, 126, 126, 1, SVGCompliance },
00262     { "gray", 190, 190, 190, 1, X11Compliance | XPMCompliance },
00263     { "gray0", 0, 0, 0, 1, X11Compliance | XPMCompliance },
00264     { "gray1", 3, 3, 3, 1, X11Compliance | XPMCompliance },
00265     { "gray10", 26, 26, 26, 1, X11Compliance | XPMCompliance },
00266     { "gray100", 255, 255, 255, 1, X11Compliance | XPMCompliance },
00267     { "gray100", 255, 255, 255, 1, X11Compliance | XPMCompliance },
00268     { "gray11", 28, 28, 28, 1, X11Compliance | XPMCompliance },
00269     { "gray12", 31, 31, 31, 1, X11Compliance | XPMCompliance },
00270     { "gray13", 33, 33, 33, 1, X11Compliance | XPMCompliance },
00271     { "gray14", 36, 36, 36, 1, X11Compliance | XPMCompliance },
00272     { "gray15", 38, 38, 38, 1, X11Compliance | XPMCompliance },
00273     { "gray16", 41, 41, 41, 1, X11Compliance | XPMCompliance },
00274     { "gray17", 43, 43, 43, 1, X11Compliance | XPMCompliance },
00275     { "gray18", 46, 46, 46, 1, X11Compliance | XPMCompliance },
00276     { "gray19", 48, 48, 48, 1, X11Compliance | XPMCompliance },
00277     { "gray2", 5, 5, 5, 1, X11Compliance | XPMCompliance },
00278     { "gray20", 51, 51, 51, 1, X11Compliance | XPMCompliance },
00279     { "gray21", 54, 54, 54, 1, X11Compliance | XPMCompliance },
00280     { "gray22", 56, 56, 56, 1, X11Compliance | XPMCompliance },
00281     { "gray23", 59, 59, 59, 1, X11Compliance | XPMCompliance },
00282     { "gray24", 61, 61, 61, 1, X11Compliance | XPMCompliance },
00283     { "gray25", 64, 64, 64, 1, X11Compliance | XPMCompliance },
00284     { "gray26", 66, 66, 66, 1, X11Compliance | XPMCompliance },
00285     { "gray27", 69, 69, 69, 1, X11Compliance | XPMCompliance },
00286     { "gray28", 71, 71, 71, 1, X11Compliance | XPMCompliance },
00287     { "gray29", 74, 74, 74, 1, X11Compliance | XPMCompliance },
00288     { "gray3", 8, 8, 8, 1, X11Compliance | XPMCompliance },
00289     { "gray30", 77, 77, 77, 1, X11Compliance | XPMCompliance },
00290     { "gray31", 79, 79, 79, 1, X11Compliance | XPMCompliance },
00291     { "gray32", 82, 82, 82, 1, X11Compliance | XPMCompliance },
00292     { "gray33", 84, 84, 84, 1, X11Compliance | XPMCompliance },
00293     { "gray34", 87, 87, 87, 1, X11Compliance | XPMCompliance },
00294     { "gray35", 89, 89, 89, 1, X11Compliance | XPMCompliance },
00295     { "gray36", 92, 92, 92, 1, X11Compliance | XPMCompliance },
00296     { "gray37", 94, 94, 94, 1, X11Compliance | XPMCompliance },
00297     { "gray38", 97, 97, 97, 1, X11Compliance | XPMCompliance },
00298     { "gray39", 99, 99, 99, 1, X11Compliance | XPMCompliance },
00299     { "gray4", 10, 10, 10, 1, X11Compliance | XPMCompliance },
00300     { "gray40", 102, 102, 102, 1, X11Compliance | XPMCompliance },
00301     { "gray41", 105, 105, 105, 1, X11Compliance | XPMCompliance },
00302     { "gray42", 107, 107, 107, 1, X11Compliance | XPMCompliance },
00303     { "gray43", 110, 110, 110, 1, X11Compliance | XPMCompliance },
00304     { "gray44", 112, 112, 112, 1, X11Compliance | XPMCompliance },
00305     { "gray45", 115, 115, 115, 1, X11Compliance | XPMCompliance },
00306     { "gray46", 117, 117, 117, 1, X11Compliance | XPMCompliance },
00307     { "gray47", 120, 120, 120, 1, X11Compliance | XPMCompliance },
00308     { "gray48", 122, 122, 122, 1, X11Compliance | XPMCompliance },
00309     { "gray49", 125, 125, 125, 1, X11Compliance | XPMCompliance },
00310     { "gray5", 13, 13, 13, 1, X11Compliance | XPMCompliance },
00311     { "gray50", 127.5, 127.5, 127.5, 1, X11Compliance | XPMCompliance },
00312     { "gray51", 130, 130, 130, 1, X11Compliance | XPMCompliance },
00313     { "gray52", 133, 133, 133, 1, X11Compliance | XPMCompliance },
00314     { "gray53", 135, 135, 135, 1, X11Compliance | XPMCompliance },
00315     { "gray54", 138, 138, 138, 1, X11Compliance | XPMCompliance },
00316     { "gray55", 140, 140, 140, 1, X11Compliance | XPMCompliance },
00317     { "gray56", 143, 143, 143, 1, X11Compliance | XPMCompliance },
00318     { "gray57", 145, 145, 145, 1, X11Compliance | XPMCompliance },
00319     { "gray58", 148, 148, 148, 1, X11Compliance | XPMCompliance },
00320     { "gray59", 150, 150, 150, 1, X11Compliance | XPMCompliance },
00321     { "gray6", 15, 15, 15, 1, X11Compliance | XPMCompliance },
00322     { "gray60", 153, 153, 153, 1, X11Compliance | XPMCompliance },
00323     { "gray61", 156, 156, 156, 1, X11Compliance | XPMCompliance },
00324     { "gray62", 158, 158, 158, 1, X11Compliance | XPMCompliance },
00325     { "gray63", 161, 161, 161, 1, X11Compliance | XPMCompliance },
00326     { "gray64", 163, 163, 163, 1, X11Compliance | XPMCompliance },
00327     { "gray65", 166, 166, 166, 1, X11Compliance | XPMCompliance },
00328     { "gray66", 168, 168, 168, 1, X11Compliance | XPMCompliance },
00329     { "gray67", 171, 171, 171, 1, X11Compliance | XPMCompliance },
00330     { "gray68", 173, 173, 173, 1, X11Compliance | XPMCompliance },
00331     { "gray69", 176, 176, 176, 1, X11Compliance | XPMCompliance },
00332     { "gray7", 18, 18, 18, 1, X11Compliance | XPMCompliance },
00333     { "gray70", 179, 179, 179, 1, X11Compliance | XPMCompliance },
00334     { "gray71", 181, 181, 181, 1, X11Compliance | XPMCompliance },
00335     { "gray72", 184, 184, 184, 1, X11Compliance | XPMCompliance },
00336     { "gray73", 186, 186, 186, 1, X11Compliance | XPMCompliance },
00337     { "gray74", 189, 189, 189, 1, X11Compliance | XPMCompliance },
00338     { "gray75", 191, 191, 191, 1, X11Compliance | XPMCompliance },
00339     { "gray76", 194, 194, 194, 1, X11Compliance | XPMCompliance },
00340     { "gray77", 196, 196, 196, 1, X11Compliance | XPMCompliance },
00341     { "gray78", 199, 199, 199, 1, X11Compliance | XPMCompliance },
00342     { "gray79", 201, 201, 201, 1, X11Compliance | XPMCompliance },
00343     { "gray8", 20, 20, 20, 1, X11Compliance | XPMCompliance },
00344     { "gray80", 204, 204, 204, 1, X11Compliance | XPMCompliance },
00345     { "gray81", 207, 207, 207, 1, X11Compliance | XPMCompliance },
00346     { "gray82", 209, 209, 209, 1, X11Compliance | XPMCompliance },
00347     { "gray83", 212, 212, 212, 1, X11Compliance | XPMCompliance },
00348     { "gray84", 214, 214, 214, 1, X11Compliance | XPMCompliance },
00349     { "gray85", 217, 217, 217, 1, X11Compliance | XPMCompliance },
00350     { "gray86", 219, 219, 219, 1, X11Compliance | XPMCompliance },
00351     { "gray87", 222, 222, 222, 1, X11Compliance | XPMCompliance },
00352     { "gray88", 224, 224, 224, 1, X11Compliance | XPMCompliance },
00353     { "gray89", 227, 227, 227, 1, X11Compliance | XPMCompliance },
00354     { "gray9", 23, 23, 23, 1, X11Compliance | XPMCompliance },
00355     { "gray90", 229, 229, 229, 1, X11Compliance | XPMCompliance },
00356     { "gray91", 232, 232, 232, 1, X11Compliance | XPMCompliance },
00357     { "gray92", 235, 235, 235, 1, X11Compliance | XPMCompliance },
00358     { "gray93", 237, 237, 237, 1, X11Compliance | XPMCompliance },
00359     { "gray94", 240, 240, 240, 1, X11Compliance | XPMCompliance },
00360     { "gray95", 242, 242, 242, 1, X11Compliance | XPMCompliance },
00361     { "gray96", 245, 245, 245, 1, X11Compliance | XPMCompliance },
00362     { "gray97", 247, 247, 247, 1, X11Compliance | XPMCompliance },
00363     { "gray98", 250, 250, 250, 1, X11Compliance | XPMCompliance },
00364     { "gray99", 252, 252, 252, 1, X11Compliance | XPMCompliance },
00365     { "green", 0, 255, 0, 1, X11Compliance | XPMCompliance },
00366     { "green1", 0, 255, 0, 1, X11Compliance },
00367     { "green2", 0, 238, 0, 1, X11Compliance },
00368     { "green3", 0, 205, 0, 1, X11Compliance },
00369     { "green4", 0, 139, 0, 1, X11Compliance },
00370     { "GreenYellow", 173, 255, 47, 1, X11Compliance | XPMCompliance },
00371     { "grey", 190, 190, 190, 1, SVGCompliance | X11Compliance },
00372     { "grey0", 0, 0, 0, 1, SVGCompliance | X11Compliance },
00373     { "grey1", 3, 3, 3, 1, SVGCompliance | X11Compliance },
00374     { "grey10", 26, 26, 26, 1, SVGCompliance | X11Compliance },
00375     { "grey100", 255, 255, 255, 1, SVGCompliance | X11Compliance },
00376     { "grey11", 28, 28, 28, 1, SVGCompliance | X11Compliance },
00377     { "grey12", 31, 31, 31, 1, SVGCompliance | X11Compliance },
00378     { "grey13", 33, 33, 33, 1, SVGCompliance | X11Compliance },
00379     { "grey14", 36, 36, 36, 1, SVGCompliance | X11Compliance },
00380     { "grey15", 38, 38, 38, 1, SVGCompliance | X11Compliance },
00381     { "grey16", 41, 41, 41, 1, SVGCompliance | X11Compliance },
00382     { "grey17", 43, 43, 43, 1, SVGCompliance | X11Compliance },
00383     { "grey18", 46, 46, 46, 1, SVGCompliance | X11Compliance },
00384     { "grey19", 48, 48, 48, 1, SVGCompliance | X11Compliance },
00385     { "grey2", 5, 5, 5, 1, SVGCompliance | X11Compliance },
00386     { "grey20", 51, 51, 51, 1, SVGCompliance | X11Compliance },
00387     { "grey21", 54, 54, 54, 1, SVGCompliance | X11Compliance },
00388     { "grey22", 56, 56, 56, 1, SVGCompliance | X11Compliance },
00389     { "grey23", 59, 59, 59, 1, SVGCompliance | X11Compliance },
00390     { "grey24", 61, 61, 61, 1, SVGCompliance | X11Compliance },
00391     { "grey25", 64, 64, 64, 1, SVGCompliance | X11Compliance },
00392     { "grey26", 66, 66, 66, 1, SVGCompliance | X11Compliance },
00393     { "grey27", 69, 69, 69, 1, SVGCompliance | X11Compliance },
00394     { "grey28", 71, 71, 71, 1, SVGCompliance | X11Compliance },
00395     { "grey29", 74, 74, 74, 1, SVGCompliance | X11Compliance },
00396     { "grey3", 8, 8, 8, 1, SVGCompliance | X11Compliance },
00397     { "grey30", 77, 77, 77, 1, SVGCompliance | X11Compliance },
00398     { "grey31", 79, 79, 79, 1, SVGCompliance | X11Compliance },
00399     { "grey32", 82, 82, 82, 1, SVGCompliance | X11Compliance },
00400     { "grey33", 84, 84, 84, 1, SVGCompliance | X11Compliance },
00401     { "grey34", 87, 87, 87, 1, SVGCompliance | X11Compliance },
00402     { "grey35", 89, 89, 89, 1, SVGCompliance | X11Compliance },
00403     { "grey36", 92, 92, 92, 1, SVGCompliance | X11Compliance },
00404     { "grey37", 94, 94, 94, 1, SVGCompliance | X11Compliance },
00405     { "grey38", 97, 97, 97, 1, SVGCompliance | X11Compliance },
00406     { "grey39", 99, 99, 99, 1, SVGCompliance | X11Compliance },
00407     { "grey4", 10, 10, 10, 1, SVGCompliance | X11Compliance },
00408     { "grey40", 102, 102, 102, 1, SVGCompliance | X11Compliance },
00409     { "grey41", 105, 105, 105, 1, SVGCompliance | X11Compliance },
00410     { "grey42", 107, 107, 107, 1, SVGCompliance | X11Compliance },
00411     { "grey43", 110, 110, 110, 1, SVGCompliance | X11Compliance },
00412     { "grey44", 112, 112, 112, 1, SVGCompliance | X11Compliance },
00413     { "grey45", 115, 115, 115, 1, SVGCompliance | X11Compliance },
00414     { "grey46", 117, 117, 117, 1, SVGCompliance | X11Compliance },
00415     { "grey47", 120, 120, 120, 1, SVGCompliance | X11Compliance },
00416     { "grey48", 122, 122, 122, 1, SVGCompliance | X11Compliance },
00417     { "grey49", 125, 125, 125, 1, SVGCompliance | X11Compliance },
00418     { "grey5", 13, 13, 13, 1, SVGCompliance | X11Compliance },
00419     { "grey50", 127, 127, 127, 1, SVGCompliance | X11Compliance },
00420     { "grey51", 130, 130, 130, 1, SVGCompliance | X11Compliance },
00421     { "grey52", 133, 133, 133, 1, SVGCompliance | X11Compliance },
00422     { "grey53", 135, 135, 135, 1, SVGCompliance | X11Compliance },
00423     { "grey54", 138, 138, 138, 1, SVGCompliance | X11Compliance },
00424     { "grey55", 140, 140, 140, 1, SVGCompliance | X11Compliance },
00425     { "grey56", 143, 143, 143, 1, SVGCompliance | X11Compliance },
00426     { "grey57", 145, 145, 145, 1, SVGCompliance | X11Compliance },
00427     { "grey58", 148, 148, 148, 1, SVGCompliance | X11Compliance },
00428     { "grey59", 150, 150, 150, 1, SVGCompliance | X11Compliance },
00429     { "grey6", 15, 15, 15, 1, SVGCompliance | X11Compliance },
00430     { "grey60", 153, 153, 153, 1, SVGCompliance | X11Compliance },
00431     { "grey61", 156, 156, 156, 1, SVGCompliance | X11Compliance },
00432     { "grey62", 158, 158, 158, 1, SVGCompliance | X11Compliance },
00433     { "grey63", 161, 161, 161, 1, SVGCompliance | X11Compliance },
00434     { "grey64", 163, 163, 163, 1, SVGCompliance | X11Compliance },
00435     { "grey65", 166, 166, 166, 1, SVGCompliance | X11Compliance },
00436     { "grey66", 168, 168, 168, 1, SVGCompliance | X11Compliance },
00437     { "grey67", 171, 171, 171, 1, SVGCompliance | X11Compliance },
00438     { "grey68", 173, 173, 173, 1, SVGCompliance | X11Compliance },
00439     { "grey69", 176, 176, 176, 1, SVGCompliance | X11Compliance },
00440     { "grey7", 18, 18, 18, 1, SVGCompliance | X11Compliance },
00441     { "grey70", 179, 179, 179, 1, SVGCompliance | X11Compliance },
00442     { "grey71", 181, 181, 181, 1, SVGCompliance | X11Compliance },
00443     { "grey72", 184, 184, 184, 1, SVGCompliance | X11Compliance },
00444     { "grey73", 186, 186, 186, 1, SVGCompliance | X11Compliance },
00445     { "grey74", 189, 189, 189, 1, SVGCompliance | X11Compliance },
00446     { "grey75", 191, 191, 191, 1, SVGCompliance | X11Compliance },
00447     { "grey76", 194, 194, 194, 1, SVGCompliance | X11Compliance },
00448     { "grey77", 196, 196, 196, 1, SVGCompliance | X11Compliance },
00449     { "grey78", 199, 199, 199, 1, SVGCompliance | X11Compliance },
00450     { "grey79", 201, 201, 201, 1, SVGCompliance | X11Compliance },
00451     { "grey8", 20, 20, 20, 1, SVGCompliance | X11Compliance },
00452     { "grey80", 204, 204, 204, 1, SVGCompliance | X11Compliance },
00453     { "grey81", 207, 207, 207, 1, SVGCompliance | X11Compliance },
00454     { "grey82", 209, 209, 209, 1, SVGCompliance | X11Compliance },
00455     { "grey83", 212, 212, 212, 1, SVGCompliance | X11Compliance },
00456     { "grey84", 214, 214, 214, 1, SVGCompliance | X11Compliance },
00457     { "grey85", 217, 217, 217, 1, SVGCompliance | X11Compliance },
00458     { "grey86", 219, 219, 219, 1, SVGCompliance | X11Compliance },
00459     { "grey87", 222, 222, 222, 1, SVGCompliance | X11Compliance },
00460     { "grey88", 224, 224, 224, 1, SVGCompliance | X11Compliance },
00461     { "grey89", 227, 227, 227, 1, SVGCompliance | X11Compliance },
00462     { "grey9", 23, 23, 23, 1, SVGCompliance | X11Compliance },
00463     { "grey90", 229, 229, 229, 1, SVGCompliance | X11Compliance },
00464     { "grey91", 232, 232, 232, 1, SVGCompliance | X11Compliance },
00465     { "grey92", 235, 235, 235, 1, SVGCompliance | X11Compliance },
00466     { "grey93", 237, 237, 237, 1, SVGCompliance | X11Compliance },
00467     { "grey94", 240, 240, 240, 1, SVGCompliance | X11Compliance },
00468     { "grey95", 242, 242, 242, 1, SVGCompliance | X11Compliance },
00469     { "grey96", 245, 245, 245, 1, SVGCompliance | X11Compliance },
00470     { "grey97", 247, 247, 247, 1, SVGCompliance | X11Compliance },
00471     { "grey98", 250, 250, 250, 1, SVGCompliance | X11Compliance },
00472     { "grey99", 252, 252, 252, 1, SVGCompliance | X11Compliance },
00473     { "honeydew", 240, 255, 240, 1, SVGCompliance | X11Compliance | XPMCompliance },
00474     { "honeydew1", 240, 255, 240, 1, X11Compliance },
00475     { "honeydew2", 224, 238, 224, 1, X11Compliance },
00476     { "honeydew3", 193, 205, 193, 1, X11Compliance },
00477     { "honeydew4", 131, 139, 131, 1, X11Compliance },
00478     { "HotPink", 255, 105, 180, 1, SVGCompliance | X11Compliance | XPMCompliance },
00479     { "HotPink1", 255, 110, 180, 1, X11Compliance },
00480     { "HotPink2", 238, 106, 167, 1, X11Compliance },
00481     { "HotPink3", 205, 96, 144, 1, X11Compliance },
00482     { "HotPink4", 139, 58, 98, 1, X11Compliance },
00483     { "IndianRed", 205, 92, 92, 1, SVGCompliance | X11Compliance | XPMCompliance },
00484     { "IndianRed1", 255, 106, 106, 1, X11Compliance },
00485     { "IndianRed2", 238, 99, 99, 1, X11Compliance },
00486     { "IndianRed3", 205, 85, 85, 1, X11Compliance },
00487     { "IndianRed4", 139, 58, 58, 1, X11Compliance },
00488     { "indigo", 75, 0, 130, 1, SVGCompliance },
00489     { "ivory", 255, 255, 240, 1, SVGCompliance | X11Compliance | XPMCompliance },
00490     { "ivory1", 255, 255, 240, 1, X11Compliance },
00491     { "ivory2", 238, 238, 224, 1, X11Compliance },
00492     { "ivory3", 205, 205, 193, 1, X11Compliance },
00493     { "ivory4", 139, 139, 131, 1, X11Compliance },
00494     { "khaki", 240, 230, 140, 1, SVGCompliance | X11Compliance | XPMCompliance },
00495     { "khaki1", 255, 246, 143, 1, X11Compliance },
00496     { "khaki2", 238, 230, 133, 1, X11Compliance },
00497     { "khaki3", 205, 198, 115, 1, X11Compliance },
00498     { "khaki4", 139, 134, 78, 1, X11Compliance },
00499     { "lavender", 230, 230, 250, 1, SVGCompliance | X11Compliance | XPMCompliance },
00500     { "LavenderBlush", 255, 240, 245, 1, SVGCompliance | X11Compliance | XPMCompliance },
00501     { "LavenderBlush1", 255, 240, 245, 1, X11Compliance },
00502     { "LavenderBlush2", 238, 224, 229, 1, X11Compliance },
00503     { "LavenderBlush3", 205, 193, 197, 1, X11Compliance },
00504     { "LavenderBlush4", 139, 131, 134, 1, X11Compliance },
00505     { "LawnGreen", 124, 252, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
00506     { "LemonChiffon", 255, 250, 205, 1, SVGCompliance | X11Compliance | XPMCompliance },
00507     { "LemonChiffon1", 255, 250, 205, 1, X11Compliance },
00508     { "LemonChiffon2", 238, 233, 191, 1, X11Compliance },
00509     { "LemonChiffon3", 205, 201, 165, 1, X11Compliance },
00510     { "LemonChiffon4", 139, 137, 112, 1, X11Compliance },
00511     { "LightBlue", 173, 216, 230, 1, SVGCompliance | X11Compliance | XPMCompliance },
00512     { "LightBlue1", 191, 239, 255, 1, X11Compliance },
00513     { "LightBlue2", 178, 223, 238, 1, X11Compliance },
00514     { "LightBlue3", 154, 192, 205, 1, X11Compliance },
00515     { "LightBlue4", 104, 131, 139, 1, X11Compliance },
00516     { "LightCoral", 240, 128, 128, 1, SVGCompliance | X11Compliance | XPMCompliance },
00517     { "LightCyan", 224, 255, 255, 1, SVGCompliance | X11Compliance | XPMCompliance },
00518     { "LightCyan1", 224, 255, 255, 1, X11Compliance },
00519     { "LightCyan2", 209, 238, 238, 1, X11Compliance },
00520     { "LightCyan3", 180, 205, 205, 1, X11Compliance },
00521     { "LightCyan4", 122, 139, 139, 1, X11Compliance },
00522     { "LightGoldenrod", 238, 221, 130, 1, X11Compliance | XPMCompliance },
00523     { "LightGoldenrod1", 255, 236, 139, 1, X11Compliance },
00524     { "LightGoldenrod2", 238, 220, 130, 1, X11Compliance },
00525     { "LightGoldenrod3", 205, 190, 112, 1, X11Compliance },
00526     { "LightGoldenrod4", 139, 129, 76, 1, X11Compliance },
00527     { "LightGoldenrodYellow", 250, 250, 210, 1, SVGCompliance | X11Compliance | XPMCompliance },
00528     { "LightGray", 211, 211, 211, 1, SVGCompliance | X11Compliance | XPMCompliance },
00529     { "LightGreen", 144, 238, 144, 1, SVGCompliance | X11Compliance },
00530     { "LightGrey", 211, 211, 211, 1, SVGCompliance | X11Compliance },
00531     { "LightPink", 255, 182, 193, 1, SVGCompliance | X11Compliance | XPMCompliance },
00532     { "LightPink1", 255, 174, 185, 1, X11Compliance },
00533     { "LightPink2", 238, 162, 173, 1, X11Compliance },
00534     { "LightPink3", 205, 140, 149, 1, X11Compliance },
00535     { "LightPink4", 139, 95, 101, 1, X11Compliance },
00536     { "LightSalmon", 255, 160, 122, 1, SVGCompliance | X11Compliance | XPMCompliance },
00537     { "LightSalmon1", 255, 160, 122, 1, X11Compliance },
00538     { "LightSalmon2", 238, 149, 114, 1, X11Compliance },
00539     { "LightSalmon3", 205, 129, 98, 1, X11Compliance },
00540     { "LightSalmon4", 139, 87, 66, 1, X11Compliance },
00541     { "LightSeaGreen", 32, 178, 170, 1, SVGCompliance | X11Compliance | XPMCompliance },
00542     { "LightSkyBlue", 135, 206, 250, 1, SVGCompliance | X11Compliance | XPMCompliance },
00543     { "LightSkyBlue1", 176, 226, 255, 1, X11Compliance },
00544     { "LightSkyBlue2", 164, 211, 238, 1, X11Compliance },
00545     { "LightSkyBlue3", 141, 182, 205, 1, X11Compliance },
00546     { "LightSkyBlue4", 96, 123, 139, 1, X11Compliance },
00547     { "LightSlateBlue", 132, 112, 255, 1, X11Compliance | XPMCompliance },
00548     { "LightSlateGray", 119, 136, 153, 1, SVGCompliance | X11Compliance | XPMCompliance },
00549     { "LightSlateGrey", 119, 136, 153, 1, SVGCompliance | X11Compliance },
00550     { "LightSteelBlue", 176, 196, 222, 1, SVGCompliance | X11Compliance | XPMCompliance },
00551     { "LightSteelBlue1", 202, 225, 255, 1, X11Compliance },
00552     { "LightSteelBlue2", 188, 210, 238, 1, X11Compliance },
00553     { "LightSteelBlue3", 162, 181, 205, 1, X11Compliance },
00554     { "LightSteelBlue4", 110, 123, 139, 1, X11Compliance },
00555     { "LightYellow", 255, 255, 224, 1, SVGCompliance | X11Compliance | XPMCompliance },
00556     { "LightYellow1", 255, 255, 224, 1, X11Compliance },
00557     { "LightYellow2", 238, 238, 209, 1, X11Compliance },
00558     { "LightYellow3", 205, 205, 180, 1, X11Compliance },
00559     { "LightYellow4", 139, 139, 122, 1, X11Compliance },
00560     { "lime", 0, 255, 0, 1, SVGCompliance },
00561     { "LimeGreen", 50, 205, 50, 1, SVGCompliance | X11Compliance | XPMCompliance },
00562     { "linen", 250, 240, 230, 1, SVGCompliance | X11Compliance | XPMCompliance },
00563     { "magenta1", 255, 0, 255, 1, X11Compliance },
00564     { "magenta2", 238, 0, 238, 1, X11Compliance },
00565     { "magenta3", 205, 0, 205, 1, X11Compliance },
00566     { "magenta4", 139, 0, 139, 1, X11Compliance },
00567     { "maroon", 128, 0, 0, 1, SVGCompliance },
00568     { "maroon", 176, 48, 96, 1, X11Compliance | XPMCompliance },
00569     { "maroon1", 255, 52, 179, 1, X11Compliance },
00570     { "maroon2", 238, 48, 167, 1, X11Compliance },
00571     { "maroon3", 205, 41, 144, 1, X11Compliance },
00572     { "maroon4", 139, 28, 98, 1, X11Compliance },
00573     { "MediumAquamarine", 102, 205, 170, 1, SVGCompliance | X11Compliance | XPMCompliance },
00574     { "MediumBlue", 0, 0, 205, 1, SVGCompliance | X11Compliance | XPMCompliance },
00575     { "MediumForestGreen", 50, 129, 75, 1, X11Compliance | XPMCompliance },
00576     { "MediumGoldenRod", 209, 193, 102, 1, X11Compliance | XPMCompliance },
00577     { "MediumOrchid", 186, 85, 211, 1, SVGCompliance | X11Compliance | XPMCompliance },
00578     { "MediumOrchid1", 224, 102, 255, 1, X11Compliance },
00579     { "MediumOrchid2", 209, 95, 238, 1, X11Compliance },
00580     { "MediumOrchid3", 180, 82, 205, 1, X11Compliance },
00581     { "MediumOrchid4", 122, 55, 139, 1, X11Compliance },
00582     { "MediumPurple", 147, 112, 219, 1, SVGCompliance | X11Compliance | XPMCompliance },
00583     { "MediumPurple1", 171, 130, 255, 1, X11Compliance },
00584     { "MediumPurple2", 159, 121, 238, 1, X11Compliance },
00585     { "MediumPurple3", 137, 104, 205, 1, X11Compliance },
00586     { "MediumPurple4", 93, 71, 139, 1, X11Compliance },
00587     { "MediumSeaGreen", 60, 179, 113, 1, SVGCompliance | X11Compliance | XPMCompliance },
00588     { "MediumSlateBlue", 123, 104, 238, 1, SVGCompliance | X11Compliance | XPMCompliance },
00589     { "MediumSpringGreen", 0, 250, 154, 1, SVGCompliance | X11Compliance | XPMCompliance },
00590     { "MediumTurquoise", 72, 209, 204, 1, SVGCompliance | X11Compliance | XPMCompliance },
00591     { "MediumVioletRed", 199, 21, 133, 1, SVGCompliance | X11Compliance | XPMCompliance },
00592     { "MidnightBlue", 25, 25, 112, 1, SVGCompliance | X11Compliance | XPMCompliance },
00593     { "MintCream", 245, 255, 250, 1, SVGCompliance | X11Compliance | XPMCompliance },
00594     { "MistyRose", 255, 228, 225, 1, SVGCompliance | X11Compliance | XPMCompliance },
00595     { "MistyRose1", 255, 228, 225, 1, X11Compliance },
00596     { "MistyRose2", 238, 213, 210, 1, X11Compliance },
00597     { "MistyRose3", 205, 183, 181, 1, X11Compliance },
00598     { "MistyRose4", 139, 125, 123, 1, X11Compliance },
00599     { "moccasin", 255, 228, 181, 1, SVGCompliance | X11Compliance | XPMCompliance },
00600     { "NavajoWhite", 255, 222, 173, 1, SVGCompliance | X11Compliance | XPMCompliance },
00601     { "NavajoWhite1", 255, 222, 173, 1, X11Compliance },
00602     { "NavajoWhite2", 238, 207, 161, 1, X11Compliance },
00603     { "NavajoWhite3", 205, 179, 139, 1, X11Compliance },
00604     { "NavajoWhite4", 139, 121, 94, 1, X11Compliance },
00605     { "navy", 0, 0, 128, 1, SVGCompliance | X11Compliance | XPMCompliance },
00606     { "NavyBlue", 0, 0, 128, 1, X11Compliance | XPMCompliance },
00607     { "matte", 0, 0, 0, 0, SVGCompliance },
00608     { "OldLace", 253, 245, 230, 1, SVGCompliance | X11Compliance | XPMCompliance },
00609     { "olive", 128, 128, 0, 1, SVGCompliance },
00610     { "OliveDrab", 107, 142, 35, 1, SVGCompliance | X11Compliance | XPMCompliance },
00611     { "OliveDrab1", 192, 255, 62, 1, X11Compliance },
00612     { "OliveDrab2", 179, 238, 58, 1, X11Compliance },
00613     { "OliveDrab3", 154, 205, 50, 1, X11Compliance },
00614     { "OliveDrab4", 105, 139, 34, 1, X11Compliance },
00615     { "opaque", 0, 0, 0, 1, SVGCompliance },
00616     { "orange", 255, 165, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
00617     { "orange1", 255, 165, 0, 1, X11Compliance },
00618     { "orange2", 238, 154, 0, 1, X11Compliance },
00619     { "orange3", 205, 133, 0, 1, X11Compliance },
00620     { "orange4", 139, 90, 0, 1, X11Compliance },
00621     { "OrangeRed", 255, 69, 0, 1, SVGCompliance | X11Compliance | XPMCompliance },
00622     { "OrangeRed1", 255, 69, 0, 1, X11Compliance },
00623     { "OrangeRed2", 238, 64, 0, 1, X11Compliance },
00624     { "OrangeRed3", 205, 55, 0, 1, X11Compliance },
00625     { "OrangeRed4", 139, 37, 0, 1, X11Compliance },
00626     { "orchid", 218, 112, 214, 1, SVGCompliance | X11Compliance | XPMCompliance },
00627     { "orchid1", 255, 131, 250, 1, X11Compliance },
00628     { "orchid2", 238, 122, 233, 1, X11Compliance },
00629     { "orchid3", 205, 105, 201, 1, X11Compliance },
00630     { "orchid4", 139, 71, 137, 1, X11Compliance },
00631     { "PaleGoldenrod", 238, 232, 170, 1, SVGCompliance | X11Compliance | XPMCompliance },
00632     { "PaleGreen", 152, 251, 152, 1, SVGCompliance | X11Compliance | XPMCompliance },
00633     { "PaleGreen1", 154, 255, 154, 1, X11Compliance },
00634     { "PaleGreen2", 144, 238, 144, 1, X11Compliance },
00635     { "PaleGreen3", 124, 205, 124, 1, X11Compliance },
00636     { "PaleGreen4", 84, 139, 84, 1, X11Compliance },
00637     { "PaleTurquoise", 175, 238, 238, 1, SVGCompliance | X11Compliance | XPMCompliance },
00638     { "PaleTurquoise1", 187, 255, 255, 1, X11Compliance },
00639     { "PaleTurquoise2", 174, 238, 238, 1, X11Compliance },
00640     { "PaleTurquoise3", 150, 205, 205, 1, X11Compliance },
00641     { "PaleTurquoise4", 102, 139, 139, 1, X11Compliance },
00642     { "PaleVioletRed", 219, 112, 147, 1, SVGCompliance | X11Compliance | XPMCompliance },
00643     { "PaleVioletRed1", 255, 130, 171, 1, X11Compliance },
00644     { "PaleVioletRed2", 238, 121, 159, 1, X11Compliance },
00645     { "PaleVioletRed3", 205, 104, 137, 1, X11Compliance },
00646     { "PaleVioletRed4", 139, 71, 93, 1, X11Compliance },
00647     { "PapayaWhip", 255, 239, 213, 1, SVGCompliance | X11Compliance | XPMCompliance },
00648     { "PeachPuff", 255, 218, 185, 1, SVGCompliance | X11Compliance | XPMCompliance },
00649     { "PeachPuff1", 255, 218, 185, 1, X11Compliance },
00650     { "PeachPuff2", 238, 203, 173, 1, X11Compliance },
00651     { "PeachPuff3", 205, 175, 149, 1, X11Compliance },
00652     { "PeachPuff4", 139, 119, 101, 1, X11Compliance },
00653     { "peru", 205, 133, 63, 1, SVGCompliance | X11Compliance | XPMCompliance },
00654     { "pink", 255, 192, 203, 1, SVGCompliance | X11Compliance | XPMCompliance },
00655     { "pink1", 255, 181, 197, 1, X11Compliance },
00656     { "pink2", 238, 169, 184, 1, X11Compliance },
00657     { "pink3", 205, 145, 158, 1, X11Compliance },
00658     { "pink4", 139, 99, 108, 1, X11Compliance },
00659     { "plum", 221, 160, 221, 1, SVGCompliance | X11Compliance | XPMCompliance },
00660     { "plum1", 255, 187, 255, 1, X11Compliance },
00661     { "plum2", 238, 174, 238, 1, X11Compliance },
00662     { "plum3", 205, 150, 205, 1, X11Compliance },
00663     { "plum4", 139, 102, 139, 1, X11Compliance },
00664     { "PowderBlue", 176, 224, 230, 1, SVGCompliance | X11Compliance | XPMCompliance },
00665     { "purple", 128, 0, 128, 1, SVGCompliance },
00666     { "purple", 160, 32, 240, 1, X11Compliance | XPMCompliance },
00667     { "purple1", 155, 48, 255, 1, X11Compliance },
00668     { "purple2", 145, 44, 238, 1, X11Compliance },
00669     { "purple3", 125, 38, 205, 1, X11Compliance },
00670     { "purple4", 85, 26, 139, 1, X11Compliance },
00671     { "red1", 255, 0, 0, 1, X11Compliance },
00672     { "red2", 238, 0, 0, 1, X11Compliance },
00673     { "red3", 205, 0, 0, 1, X11Compliance },
00674     { "red4", 139, 0, 0, 1, X11Compliance },
00675     { "RosyBrown", 188, 143, 143, 1, SVGCompliance | X11Compliance | XPMCompliance },
00676     { "RosyBrown1", 255, 193, 193, 1, X11Compliance },
00677     { "RosyBrown2", 238, 180, 180, 1, X11Compliance },
00678     { "RosyBrown3", 205, 155, 155, 1, X11Compliance },
00679     { "RosyBrown4", 139, 105, 105, 1, X11Compliance },
00680     { "RoyalBlue", 65, 105, 225, 1, SVGCompliance | X11Compliance | XPMCompliance },
00681     { "RoyalBlue1", 72, 118, 255, 1, X11Compliance },
00682     { "RoyalBlue2", 67, 110, 238, 1, X11Compliance },
00683     { "RoyalBlue3", 58, 95, 205, 1, X11Compliance },
00684     { "RoyalBlue4", 39, 64, 139, 1, X11Compliance },
00685     { "SaddleBrown", 139, 69, 19, 1, SVGCompliance | X11Compliance | XPMCompliance },
00686     { "salmon", 250, 128, 114, 1, SVGCompliance | X11Compliance | XPMCompliance },
00687     { "salmon1", 255, 140, 105, 1, X11Compliance },
00688     { "salmon2", 238, 130, 98, 1, X11Compliance },
00689     { "salmon3", 205, 112, 84, 1, X11Compliance },
00690     { "salmon4", 139, 76, 57, 1, X11Compliance },
00691     { "SandyBrown", 244, 164, 96, 1, SVGCompliance | X11Compliance | XPMCompliance },
00692     { "SeaGreen", 46, 139, 87, 1, SVGCompliance | X11Compliance | XPMCompliance },
00693     { "SeaGreen1", 84, 255, 159, 1, X11Compliance },
00694     { "SeaGreen2", 78, 238, 148, 1, X11Compliance },
00695     { "SeaGreen3", 67, 205, 128, 1, X11Compliance },
00696     { "SeaGreen4", 46, 139, 87, 1, X11Compliance },
00697     { "seashell", 255, 245, 238, 1, SVGCompliance | X11Compliance | XPMCompliance },
00698     { "seashell1", 255, 245, 238, 1, X11Compliance },
00699     { "seashell2", 238, 229, 222, 1, X11Compliance },
00700     { "seashell3", 205, 197, 191, 1, X11Compliance },
00701     { "seashell4", 139, 134, 130, 1, X11Compliance },
00702     { "sienna", 160, 82, 45, 1, SVGCompliance | X11Compliance | XPMCompliance },
00703     { "sienna1", 255, 130, 71, 1, X11Compliance },
00704     { "sienna2", 238, 121, 66, 1, X11Compliance },
00705     { "sienna3", 205, 104, 57, 1, X11Compliance },
00706     { "sienna4", 139, 71, 38, 1, X11Compliance },
00707     { "silver", 192, 192, 192, 1, SVGCompliance },
00708     { "SkyBlue", 135, 206, 235, 1, SVGCompliance | X11Compliance | XPMCompliance },
00709     { "SkyBlue1", 135, 206, 255, 1, X11Compliance },
00710     { "SkyBlue2", 126, 192, 238, 1, X11Compliance },
00711     { "SkyBlue3", 108, 166, 205, 1, X11Compliance },
00712     { "SkyBlue4", 74, 112, 139, 1, X11Compliance },
00713     { "SlateBlue", 106, 90, 205, 1, SVGCompliance | X11Compliance | XPMCompliance },
00714     { "SlateBlue1", 131, 111, 255, 1, X11Compliance },
00715     { "SlateBlue2", 122, 103, 238, 1, X11Compliance },
00716     { "SlateBlue3", 105, 89, 205, 1, X11Compliance },
00717     { "SlateBlue4", 71, 60, 139, 1, X11Compliance },
00718     { "SlateGray", 112, 128, 144, 1, SVGCompliance | X11Compliance | XPMCompliance },
00719     { "SlateGray1", 198, 226, 255, 1, X11Compliance },
00720     { "SlateGray2", 185, 211, 238, 1, X11Compliance },
00721     { "SlateGray3", 159, 182, 205, 1, X11Compliance },
00722     { "SlateGray4", 108, 123, 139, 1, X11Compliance },
00723     { "SlateGrey", 112, 128, 144, 1, SVGCompliance | X11Compliance },
00724     { "snow", 255, 250, 250, 1, SVGCompliance | X11Compliance | XPMCompliance },
00725     { "snow1", 255, 250, 250, 1, X11Compliance },
00726     { "snow2", 238, 233, 233, 1, X11Compliance },
00727     { "snow3", 205, 201, 201, 1, X11Compliance },
00728     { "snow4", 139, 137, 137, 1, X11Compliance },
00729     { "SpringGreen", 0, 255, 127, 1, SVGCompliance | X11Compliance | XPMCompliance },
00730     { "SpringGreen1", 0, 255, 127, 1, X11Compliance },
00731     { "SpringGreen2", 0, 238, 118, 1, X11Compliance },
00732     { "SpringGreen3", 0, 205, 102, 1, X11Compliance },
00733     { "SpringGreen4", 0, 139, 69, 1, X11Compliance },
00734     { "SteelBlue", 70, 130, 180, 1, SVGCompliance | X11Compliance | XPMCompliance },
00735     { "SteelBlue1", 99, 184, 255, 1, X11Compliance },
00736     { "SteelBlue2", 92, 172, 238, 1, X11Compliance },
00737     { "SteelBlue3", 79, 148, 205, 1, X11Compliance },
00738     { "SteelBlue4", 54, 100, 139, 1, X11Compliance },
00739     { "tan", 210, 180, 140, 1, SVGCompliance | X11Compliance | XPMCompliance },
00740     { "tan1", 255, 165, 79, 1, X11Compliance },
00741     { "tan2", 238, 154, 73, 1, X11Compliance },
00742     { "tan3", 205, 133, 63, 1, X11Compliance },
00743     { "tan4", 139, 90, 43, 1, X11Compliance },
00744     { "teal", 0, 128, 128, 1, SVGCompliance },
00745     { "thistle", 216, 191, 216, 1, SVGCompliance | X11Compliance | XPMCompliance },
00746     { "thistle1", 255, 225, 255, 1, X11Compliance },
00747     { "thistle2", 238, 210, 238, 1, X11Compliance },
00748     { "thistle3", 205, 181, 205, 1, X11Compliance },
00749     { "thistle4", 139, 123, 139, 1, X11Compliance },
00750     { "tomato", 255, 99, 71, 1, SVGCompliance | X11Compliance | XPMCompliance },
00751     { "tomato1", 255, 99, 71, 1, X11Compliance },
00752     { "tomato2", 238, 92, 66, 1, X11Compliance },
00753     { "tomato3", 205, 79, 57, 1, X11Compliance },
00754     { "tomato4", 139, 54, 38, 1, X11Compliance },
00755     { "transparent", 0, 0, 0, 0, SVGCompliance },
00756     { "turquoise", 64, 224, 208, 1, SVGCompliance | X11Compliance | XPMCompliance },
00757     { "turquoise1", 0, 245, 255, 1, X11Compliance },
00758     { "turquoise2", 0, 229, 238, 1, X11Compliance },
00759     { "turquoise3", 0, 197, 205, 1, X11Compliance },
00760     { "turquoise4", 0, 134, 139, 1, X11Compliance },
00761     { "violet", 238, 130, 238, 1, SVGCompliance | X11Compliance | XPMCompliance },
00762     { "VioletRed", 208, 32, 144, 1, X11Compliance | XPMCompliance },
00763     { "VioletRed1", 255, 62, 150, 1, X11Compliance },
00764     { "VioletRed2", 238, 58, 140, 1, X11Compliance },
00765     { "VioletRed3", 205, 50, 120, 1, X11Compliance },
00766     { "VioletRed4", 139, 34, 82, 1, X11Compliance },
00767     { "wheat", 245, 222, 179, 1, SVGCompliance | X11Compliance | XPMCompliance },
00768     { "wheat1", 255, 231, 186, 1, X11Compliance },
00769     { "wheat2", 238, 216, 174, 1, X11Compliance },
00770     { "wheat3", 205, 186, 150, 1, X11Compliance },
00771     { "wheat4", 139, 126, 102, 1, X11Compliance },
00772     { "WhiteSmoke", 245, 245, 245, 1, SVGCompliance | X11Compliance | XPMCompliance },
00773     { "yellow1", 255, 255, 0, 1, X11Compliance },
00774     { "yellow2", 238, 238, 0, 1, X11Compliance },
00775     { "yellow3", 205, 205, 0, 1, X11Compliance },
00776     { "yellow4", 139, 139, 0, 1, X11Compliance },
00777     { "YellowGreen", 154, 205, 50, 1, SVGCompliance | X11Compliance | XPMCompliance }
00778   };
00779 
00780 /*
00781   Static declarations.
00782 */
00783 static LinkedListInfo
00784   *color_list = (LinkedListInfo *) NULL;
00785 
00786 static SemaphoreInfo
00787   *color_semaphore = (SemaphoreInfo *) NULL;
00788 
00789 static volatile MagickBooleanType
00790   instantiate_color = MagickFalse;
00791 
00792 /*
00793   Forward declarations.
00794 */
00795 static MagickBooleanType
00796   InitializeColorList(ExceptionInfo *),
00797   LoadColorLists(const char *,ExceptionInfo *);
00798 
00799 /*
00800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00801 %                                                                             %
00802 %                                                                             %
00803 %                                                                             %
00804 +   C o l o r C o m p o n e n t G e n e s i s                                 %
00805 %                                                                             %
00806 %                                                                             %
00807 %                                                                             %
00808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00809 %
00810 %  ColorComponentGenesis() instantiates the color component.
00811 %
00812 %  The format of the ColorComponentGenesis method is:
00813 %
00814 %      MagickBooleanType ColorComponentGenesis(void)
00815 %
00816 */
00817 MagickExport MagickBooleanType ColorComponentGenesis(void)
00818 {
00819   AcquireSemaphoreInfo(&color_semaphore);
00820   return(MagickTrue);
00821 }
00822 
00823 /*
00824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00825 %                                                                             %
00826 %                                                                             %
00827 %                                                                             %
00828 +   C o l o r C o m p o n e n t T e r m i n u s                               %
00829 %                                                                             %
00830 %                                                                             %
00831 %                                                                             %
00832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00833 %
00834 %  ColorComponentTerminus() destroys the color component.
00835 %
00836 %  The format of the ColorComponentTerminus method is:
00837 %
00838 %      ColorComponentTerminus(void)
00839 %
00840 */
00841 
00842 static void *DestroyColorElement(void *color_info)
00843 {
00844   register ColorInfo
00845     *p;
00846 
00847   p=(ColorInfo *) color_info;
00848   if (p->exempt  == MagickFalse)
00849     {
00850       if (p->path != (char *) NULL)
00851         p->path=DestroyString(p->path);
00852       if (p->name != (char *) NULL)
00853         p->name=DestroyString(p->name);
00854     }
00855   p=(ColorInfo *) RelinquishMagickMemory(p);
00856   return((void *) NULL);
00857 }
00858 
00859 MagickExport void ColorComponentTerminus(void)
00860 {
00861   if (color_semaphore == (SemaphoreInfo *) NULL)
00862     AcquireSemaphoreInfo(&color_semaphore);
00863   (void) LockSemaphoreInfo(color_semaphore);
00864   if (color_list != (LinkedListInfo *) NULL)
00865     color_list=DestroyLinkedList(color_list,DestroyColorElement);
00866   instantiate_color=MagickFalse;
00867   (void) UnlockSemaphoreInfo(color_semaphore);
00868   DestroySemaphoreInfo(&color_semaphore);
00869 }
00870 
00871 /*
00872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00873 %                                                                             %
00874 %                                                                             %
00875 %                                                                             %
00876 +   G e t C o l o r I n f o                                                   %
00877 %                                                                             %
00878 %                                                                             %
00879 %                                                                             %
00880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00881 %
00882 %  GetColorInfo() searches the color list for the specified name and if found
00883 %  returns attributes for that color.
00884 %
00885 %  The format of the GetColorInfo method is:
00886 %
00887 %      const PixelPacket *GetColorInfo(const char *name,
00888 %        ExceptionInfo *exception)
00889 %
00890 %  A description of each parameter follows:
00891 %
00892 %    o color_info: search the color list for the specified name and if found
00893 %      return attributes for that color.
00894 %
00895 %    o name: the color name.
00896 %
00897 %    o exception: return any errors or warnings in this structure.
00898 %
00899 */
00900 MagickExport const ColorInfo *GetColorInfo(const char *name,
00901   ExceptionInfo *exception)
00902 {
00903   char
00904     colorname[MaxTextExtent];
00905 
00906   register const ColorInfo
00907     *p;
00908 
00909   register char
00910     *q;
00911 
00912   assert(exception != (ExceptionInfo *) NULL);
00913   if ((color_list == (LinkedListInfo *) NULL) ||
00914       (instantiate_color == MagickFalse))
00915     if (InitializeColorList(exception) == MagickFalse)
00916       return((const ColorInfo *) NULL);
00917   if ((color_list == (LinkedListInfo *) NULL) ||
00918       (IsLinkedListEmpty(color_list) != MagickFalse))
00919     return((const ColorInfo *) NULL);
00920   if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
00921     return((const ColorInfo *) GetValueFromLinkedList(color_list,0));
00922   /*
00923     Strip names of whitespace.
00924   */
00925   (void) CopyMagickString(colorname,name,MaxTextExtent);
00926   for (q=colorname; *q != '\0'; q++)
00927   {
00928     if (isspace((int) ((unsigned char) *q)) == 0)
00929       continue;
00930     (void) CopyMagickString(q,q+1,MaxTextExtent);
00931     q--;
00932   }
00933   /*
00934     Search for color tag.
00935   */
00936   (void) LockSemaphoreInfo(color_semaphore);
00937   ResetLinkedListIterator(color_list);
00938   p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
00939   while (p != (const ColorInfo *) NULL)
00940   {
00941     if (LocaleCompare(colorname,p->name) == 0)
00942       break;
00943     p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
00944   }
00945   if (p == (ColorInfo *) NULL)
00946     (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
00947       "UnrecognizedColor","`%s'",name);
00948   else
00949     (void) InsertValueInLinkedList(color_list,0,
00950       RemoveElementByValueFromLinkedList(color_list,p));
00951   (void) UnlockSemaphoreInfo(color_semaphore);
00952   return(p);
00953 }
00954 
00955 /*
00956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00957 %                                                                             %
00958 %                                                                             %
00959 %                                                                             %
00960 +   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                         %
00961 %                                                                             %
00962 %                                                                             %
00963 %                                                                             %
00964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00965 %
00966 %  ConcatenateColorComponent() returns the pixel as a canonical string.
00967 %
00968 %  The format of the ConcatenateColorComponent() method is:
00969 %
00970 %      void ConcatenateColorComponent(const MagickPixelPacket *pixel,
00971 %        const ChannelType channel,const ComplianceType compliance,char *tuple)
00972 %
00973 %  A description of each parameter follows.
00974 %
00975 %    o pixel:  The pixel.
00976 %
00977 %    channel:  The channel.
00978 %
00979 %    o compliance: Adhere to this color standard: SVG, X11, or XPM.
00980 %
00981 %    tuple:  The color tuple.
00982 %
00983 */
00984 MagickExport void ConcatenateColorComponent(const MagickPixelPacket *pixel,
00985   const ChannelType channel,const ComplianceType compliance,char *tuple)
00986 {
00987   char
00988     component[MaxTextExtent];
00989 
00990   MagickRealType
00991     color;
00992 
00993   color=0.0;
00994   switch (channel)
00995   {
00996     case RedChannel:
00997     {
00998       color=pixel->red;
00999       break;
01000     }
01001     case GreenChannel:
01002     {
01003       color=pixel->green;
01004       break;
01005     }
01006     case BlueChannel:
01007     {
01008       color=pixel->blue;
01009       break;
01010     }
01011     case AlphaChannel:
01012     {
01013       color=QuantumRange-pixel->opacity;
01014       break;
01015     }
01016     case IndexChannel:
01017     {
01018       color=pixel->index;
01019       break;
01020     }
01021     default:
01022       break;
01023   }
01024   if (compliance != SVGCompliance)
01025     {
01026       if (pixel->depth > 16)
01027         {
01028           (void) FormatMagickString(component,MaxTextExtent,"%10lu",
01029             (unsigned long) ScaleQuantumToLong(RoundToQuantum(color)));
01030           (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01031           return;
01032         }
01033       if (pixel->depth > 8)
01034         {
01035           (void) FormatMagickString(component,MaxTextExtent,"%5d",
01036             ScaleQuantumToShort(RoundToQuantum(color)));
01037           (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01038           return;
01039         }
01040       (void) FormatMagickString(component,MaxTextExtent,"%3d",
01041         ScaleQuantumToChar(RoundToQuantum(color)));
01042       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01043       return;
01044     }
01045   if (channel == OpacityChannel)
01046     {
01047       (void) FormatMagickString(component,MaxTextExtent,"%g",
01048         (double) (QuantumScale*color));
01049       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01050       return;
01051     }
01052   if ((pixel->colorspace == HSLColorspace) ||
01053       (pixel->colorspace == HSBColorspace))
01054     {
01055       (void) FormatMagickString(component,MaxTextExtent,"%g%%",
01056         (double) (100.0*QuantumScale*color));
01057       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01058       return;
01059     }
01060   if (pixel->depth > 8)
01061     {
01062       (void) FormatMagickString(component,MaxTextExtent,"%g%%",
01063         (double) (100.0*QuantumScale*color));
01064       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01065       return;
01066     }
01067   (void) FormatMagickString(component,MaxTextExtent,"%d",
01068     ScaleQuantumToChar(RoundToQuantum(color)));
01069   (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01070 }
01071 
01072 /*
01073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01074 %                                                                             %
01075 %                                                                             %
01076 %                                                                             %
01077 %   G e t C o l o r I n f o L i s t                                           %
01078 %                                                                             %
01079 %                                                                             %
01080 %                                                                             %
01081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01082 %
01083 %  GetColorInfoList() returns any colors that match the specified pattern.
01084 %
01085 %  The format of the GetColorInfoList function is:
01086 %
01087 %      const ColorInfo **GetColorInfoList(const char *pattern,
01088 %        unsigned long *number_colors,ExceptionInfo *exception)
01089 %
01090 %  A description of each parameter follows:
01091 %
01092 %    o pattern: Specifies a pointer to a text string containing a pattern.
01093 %
01094 %    o number_colors:  This integer returns the number of colors in the list.
01095 %
01096 %    o exception: return any errors or warnings in this structure.
01097 %
01098 */
01099 
01100 #if defined(__cplusplus) || defined(c_plusplus)
01101 extern "C" {
01102 #endif
01103 
01104 static int ColorInfoCompare(const void *x,const void *y)
01105 {
01106   const ColorInfo
01107     **p,
01108     **q;
01109 
01110   p=(const ColorInfo **) x,
01111   q=(const ColorInfo **) y;
01112   if (LocaleCompare((*p)->path,(*q)->path) == 0)
01113     return(LocaleCompare((*p)->name,(*q)->name));
01114   return(LocaleCompare((*p)->path,(*q)->path));
01115 }
01116 
01117 #if defined(__cplusplus) || defined(c_plusplus)
01118 }
01119 #endif
01120 
01121 MagickExport const ColorInfo **GetColorInfoList(const char *pattern,
01122   unsigned long *number_colors,ExceptionInfo *exception)
01123 {
01124   const ColorInfo
01125     **colors;
01126 
01127   register const ColorInfo
01128     *p;
01129 
01130   register long
01131     i;
01132 
01133   /*
01134     Allocate color list.
01135   */
01136   assert(pattern != (char *) NULL);
01137   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
01138   assert(number_colors != (unsigned long *) NULL);
01139   *number_colors=0;
01140   p=GetColorInfo("*",exception);
01141   if (p == (const ColorInfo *) NULL)
01142     return((const ColorInfo **) NULL);
01143   colors=(const ColorInfo **) AcquireQuantumMemory((size_t)
01144     GetNumberOfElementsInLinkedList(color_list)+1UL,sizeof(*colors));
01145   if (colors == (const ColorInfo **) NULL)
01146     return((const ColorInfo **) NULL);
01147   /*
01148     Generate color list.
01149   */
01150   (void) LockSemaphoreInfo(color_semaphore);
01151   ResetLinkedListIterator(color_list);
01152   p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
01153   for (i=0; p != (const ColorInfo *) NULL; )
01154   {
01155     if ((p->stealth == MagickFalse) &&
01156         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
01157       colors[i++]=p;
01158     p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
01159   }
01160   (void) UnlockSemaphoreInfo(color_semaphore);
01161   qsort((void *) colors,(size_t) i,sizeof(*colors),ColorInfoCompare);
01162   colors[i]=(ColorInfo *) NULL;
01163   *number_colors=(unsigned long) i;
01164   return(colors);
01165 }
01166 
01167 /*
01168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01169 %                                                                             %
01170 %                                                                             %
01171 %                                                                             %
01172 %   G e t C o l o r L i s t                                                   %
01173 %                                                                             %
01174 %                                                                             %
01175 %                                                                             %
01176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01177 %
01178 %  GetColorList() returns any colors that match the specified pattern.
01179 %
01180 %  The format of the GetColorList function is:
01181 %
01182 %      char **GetColorList(const char *pattern,unsigned long *number_colors,
01183 %        ExceptionInfo *exception)
01184 %
01185 %  A description of each parameter follows:
01186 %
01187 %    o pattern: Specifies a pointer to a text string containing a pattern.
01188 %
01189 %    o number_colors:  This integer returns the number of colors in the list.
01190 %
01191 %    o exception: return any errors or warnings in this structure.
01192 %
01193 */
01194 
01195 #if defined(__cplusplus) || defined(c_plusplus)
01196 extern "C" {
01197 #endif
01198 
01199 static int ColorCompare(const void *x,const void *y)
01200 {
01201   register const char
01202     **p,
01203     **q;
01204 
01205   p=(const char **) x;
01206   q=(const char **) y;
01207   return(LocaleCompare(*p,*q));
01208 }
01209 
01210 #if defined(__cplusplus) || defined(c_plusplus)
01211 }
01212 #endif
01213 
01214 MagickExport char **GetColorList(const char *pattern,
01215   unsigned long *number_colors,ExceptionInfo *exception)
01216 {
01217   char
01218     **colors;
01219 
01220   register const ColorInfo
01221     *p;
01222 
01223   register long
01224     i;
01225 
01226   /*
01227     Allocate color list.
01228   */
01229   assert(pattern != (char *) NULL);
01230   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
01231   assert(number_colors != (unsigned long *) NULL);
01232   *number_colors=0;
01233   p=GetColorInfo("*",exception);
01234   if (p == (const ColorInfo *) NULL)
01235     return((char **) NULL);
01236   colors=(char **) AcquireQuantumMemory((size_t)
01237     GetNumberOfElementsInLinkedList(color_list)+1UL,sizeof(*colors));
01238   if (colors == (char **) NULL)
01239     return((char **) NULL);
01240   /*
01241     Generate color list.
01242   */
01243   (void) LockSemaphoreInfo(color_semaphore);
01244   ResetLinkedListIterator(color_list);
01245   p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
01246   for (i=0; p != (const ColorInfo *) NULL; )
01247   {
01248     if ((p->stealth == MagickFalse) &&
01249         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
01250       colors[i++]=ConstantString(p->name);
01251     p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
01252   }
01253   (void) UnlockSemaphoreInfo(color_semaphore);
01254   qsort((void *) colors,(size_t) i,sizeof(*colors),ColorCompare);
01255   colors[i]=(char *) NULL;
01256   *number_colors=(unsigned long) i;
01257   return(colors);
01258 }
01259 
01260 /*
01261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01262 %                                                                             %
01263 %                                                                             %
01264 %                                                                             %
01265 +   G e t C o l o r T u p l e                                                 %
01266 %                                                                             %
01267 %                                                                             %
01268 %                                                                             %
01269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01270 %
01271 %  GetColorTuple() returns a color as a color tuple string (e.g. rgba(255,0,0))
01272 %  or hex string (e.g. #FF0000).
01273 %
01274 %  The format of the GetColorTuple method is:
01275 %
01276 %      GetColorTuple(const MagickPixelPacket *pixel,const MagickBooleanType hex,
01277 %        char *tuple)
01278 %
01279 %  A description of each parameter follows.
01280 %
01281 %    o pixel: the pixel.
01282 %
01283 %    o hex: A value other than zero returns the tuple in a hexidecimal format.
01284 %
01285 %    o tuple: Return the color tuple as this string.
01286 %
01287 */
01288 
01289 static void ConcatentateHexColorComponent(const MagickPixelPacket *pixel,
01290   const ChannelType channel,char *tuple)
01291 {
01292   char
01293     component[MaxTextExtent];
01294 
01295   MagickRealType
01296     color;
01297 
01298   color=0.0;
01299   switch (channel)
01300   {
01301     case RedChannel:
01302     {
01303       color=pixel->red;
01304       break;
01305     }
01306     case GreenChannel:
01307     {
01308       color=pixel->green;
01309       break;
01310     }
01311     case BlueChannel:
01312     {
01313       color=pixel->blue;
01314       break;
01315     }
01316     case OpacityChannel:
01317     {
01318       color=(MagickRealType) QuantumRange-pixel->opacity;
01319       break;
01320     }
01321     case IndexChannel:
01322     {
01323       color=pixel->index;
01324       break;
01325     }
01326     default:
01327       break;
01328   }
01329   if (pixel->depth > 32)
01330     {
01331       (void) FormatMagickString(component,MaxTextExtent,"%08lX",
01332         ScaleQuantumToLong(RoundToQuantum(color)));
01333       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01334       return;
01335     }
01336   if (pixel->depth > 16)
01337     {
01338       (void) FormatMagickString(component,MaxTextExtent,"%08X",
01339         (unsigned int) ScaleQuantumToLong(RoundToQuantum(color)));
01340       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01341       return;
01342     }
01343   if (pixel->depth > 8)
01344     {
01345       (void) FormatMagickString(component,MaxTextExtent,"%04X",
01346         ScaleQuantumToShort(RoundToQuantum(color)));
01347       (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01348       return;
01349     }
01350   (void) FormatMagickString(component,MaxTextExtent,"%02X",
01351     ScaleQuantumToChar(RoundToQuantum(color)));
01352   (void) ConcatenateMagickString(tuple,component,MaxTextExtent);
01353   return;
01354 }
01355 
01356 MagickExport void GetColorTuple(const MagickPixelPacket *pixel,
01357   const MagickBooleanType hex,char *tuple)
01358 {
01359   MagickPixelPacket
01360     color;
01361 
01362   assert(pixel != (const MagickPixelPacket *) NULL);
01363   assert(tuple != (char *) NULL);
01364   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",tuple);
01365   *tuple='\0';
01366   if (hex != MagickFalse)
01367     {
01368       /*
01369         Convert pixel to hex color.
01370       */
01371       (void) ConcatenateMagickString(tuple,"#",MaxTextExtent);
01372       ConcatentateHexColorComponent(pixel,RedChannel,tuple);
01373       ConcatentateHexColorComponent(pixel,GreenChannel,tuple);
01374       ConcatentateHexColorComponent(pixel,BlueChannel,tuple);
01375       if (pixel->colorspace == CMYKColorspace)
01376         ConcatentateHexColorComponent(pixel,IndexChannel,tuple);
01377       if ((pixel->matte != MagickFalse) && (pixel->opacity != OpaqueOpacity))
01378         ConcatentateHexColorComponent(pixel,OpacityChannel,tuple);
01379       return;
01380     }
01381   /*
01382     Convert pixel to rgb() or cmyk() color.
01383   */
01384   color=(*pixel);
01385   if (color.depth > 8)
01386     {
01387 #define SVGCompliant(component) ((MagickRealType) \
01388    ScaleCharToQuantum(ScaleQuantumToChar(RoundToQuantum(component))));
01389 
01390       MagickStatusType
01391         status;
01392 
01393       /*
01394         SVG requires color depths > 8 expressed as percentages.
01395       */
01396       status=color.red == SVGCompliant(color.red);
01397       status&=color.green == SVGCompliant(color.green);
01398       status&=color.blue == SVGCompliant(color.blue);
01399       if (color.colorspace != CMYKColorspace)
01400         status&=color.index == SVGCompliant(color.index);
01401       if (color.matte != MagickFalse)
01402         status&=color.opacity == SVGCompliant(color.opacity);
01403       if (status != MagickFalse)
01404         color.depth=8;
01405     }
01406   (void) ConcatenateMagickString(tuple,MagickOptionToMnemonic(
01407     MagickColorspaceOptions,(long) color.colorspace),MaxTextExtent);
01408   if (color.matte != MagickFalse)
01409     (void) ConcatenateMagickString(tuple,"a",MaxTextExtent);
01410   (void) ConcatenateMagickString(tuple,"(",MaxTextExtent);
01411   ConcatenateColorComponent(&color,RedChannel,SVGCompliance,tuple);
01412   (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
01413   ConcatenateColorComponent(&color,GreenChannel,SVGCompliance,tuple);
01414   (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
01415   ConcatenateColorComponent(&color,BlueChannel,SVGCompliance,tuple);
01416   if (color.colorspace == CMYKColorspace)
01417     {
01418       (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
01419       ConcatenateColorComponent(&color,IndexChannel,SVGCompliance,tuple);
01420     }
01421   if (color.matte != MagickFalse)
01422     {
01423       (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
01424       ConcatenateColorComponent(&color,AlphaChannel,SVGCompliance,tuple);
01425     }
01426   (void) ConcatenateMagickString(tuple,")",MaxTextExtent);
01427   LocaleLower(tuple);
01428   return;
01429 }
01430 
01431 /*
01432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01433 %                                                                             %
01434 %                                                                             %
01435 %                                                                             %
01436 +   I n i t i a l i z e C o l o r L i s t                                     %
01437 %                                                                             %
01438 %                                                                             %
01439 %                                                                             %
01440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01441 %
01442 %  InitializeColorList() initializes the color list.
01443 %
01444 %  The format of the InitializeColorList method is:
01445 %
01446 %      MagickBooleanType InitializeColorList(ExceptionInfo *exception)
01447 %
01448 %  A description of each parameter follows.
01449 %
01450 %    o exception: return any errors or warnings in this structure.
01451 %
01452 */
01453 static MagickBooleanType InitializeColorList(ExceptionInfo *exception)
01454 {
01455   if ((color_list == (LinkedListInfo *) NULL) &&
01456       (instantiate_color == MagickFalse))
01457     {
01458       if (color_semaphore == (SemaphoreInfo *) NULL)
01459         AcquireSemaphoreInfo(&color_semaphore);
01460       (void) LockSemaphoreInfo(color_semaphore);
01461       if ((color_list == (LinkedListInfo *) NULL) &&
01462           (instantiate_color == MagickFalse))
01463         {
01464           (void) LoadColorLists(ColorFilename,exception);
01465           instantiate_color=MagickTrue;
01466         }
01467       (void) UnlockSemaphoreInfo(color_semaphore);
01468     }
01469   return(color_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
01470 }
01471 
01472 /*
01473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01474 %                                                                             %
01475 %                                                                             %
01476 %                                                                             %
01477 +   I s C o l o r S i m i l a r                                               %
01478 %                                                                             %
01479 %                                                                             %
01480 %                                                                             %
01481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01482 %
01483 %  IsColorSimilar() returns MagickTrue if the distance between two colors is
01484 %  less than the specified distance in a linear three dimensional color space.
01485 %  This method is used by ColorFloodFill() and other algorithms which
01486 %  compare two colors.
01487 %
01488 %  The format of the IsColorSimilar method is:
01489 %
01490 %      void IsColorSimilar(const Image *image,const PixelPacket *p,
01491 %        const PixelPacket *q)
01492 %
01493 %  A description of each parameter follows:
01494 %
01495 %    o image: the image.
01496 %
01497 %    o p: Pixel p.
01498 %
01499 %    o q: Pixel q.
01500 %
01501 */
01502 
01503 static inline double MagickMax(const double x,const double y)
01504 {
01505   if (x > y)
01506     return(x);
01507   return(y);
01508 }
01509 
01510 MagickExport MagickBooleanType IsColorSimilar(const Image *image,
01511   const PixelPacket *p,const PixelPacket *q)
01512 {
01513   MagickRealType
01514     fuzz,
01515     pixel;
01516 
01517   register MagickRealType
01518     alpha,
01519     beta,
01520     distance;
01521 
01522   if ((image->fuzz == 0.0) && (image->matte == MagickFalse))
01523     return(IsColorEqual(p,q));
01524   fuzz=3.0*MagickMax(image->fuzz,MagickSQ1_2)*MagickMax(image->fuzz,
01525     MagickSQ1_2);
01526   alpha=1.0;
01527   beta=1.0;
01528   if (image->matte != MagickFalse)
01529     {
01530       alpha=(MagickRealType) (QuantumScale*(QuantumRange-p->opacity));
01531       beta=(MagickRealType) (QuantumScale*(QuantumRange-q->opacity));
01532     }
01533   pixel=alpha*p->red-beta*q->red;
01534   distance=pixel*pixel;
01535   if (distance > fuzz)
01536     return(MagickFalse);
01537   pixel=alpha*p->green-beta*q->green;
01538   distance+=pixel*pixel;
01539   if (distance > fuzz)
01540     return(MagickFalse);
01541   pixel=alpha*p->blue-beta*q->blue;
01542   distance+=pixel*pixel;
01543   if (distance > fuzz)
01544     return(MagickFalse);
01545   return(MagickTrue);
01546 }
01547 
01548 /*
01549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01550 %                                                                             %
01551 %                                                                             %
01552 %                                                                             %
01553 +   I s I m a g e S i m i l a r                                               %
01554 %                                                                             %
01555 %                                                                             %
01556 %                                                                             %
01557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01558 %
01559 %  IsImageSimilar() returns true if the target is similar to a region of the
01560 %  image.
01561 %
01562 %  The format of the IsImageSimilar method is:
01563 %
01564 %      MagickBooleanType IsImageSimilar(const Image *image,
01565 %        const Image *target_image,long *x_offset,long *y_offset,
01566 %        ExceptionInfo *exception)
01567 %
01568 %  A description of each parameter follows:
01569 %
01570 %    o image: the image.
01571 %
01572 %    o target_image: the target image.
01573 %
01574 %    o x_offset: On input the starting x position to search for a match;
01575 %      on output the x position of the first match found.
01576 %
01577 %    o y_offset: On input the starting y position to search for a match;
01578 %      on output the y position of the first match found.
01579 %
01580 %    o exception: return any errors or warnings in this structure.
01581 %
01582 */
01583 MagickExport MagickBooleanType IsImageSimilar(const Image *image,
01584   const Image *target_image,long *x_offset,long *y_offset,
01585   ExceptionInfo *exception)
01586 {
01587 #define SearchImageText  "  Searching image...  "
01588 
01589   long
01590     j,
01591     y;
01592 
01593   MagickBooleanType
01594     status;
01595 
01596   MagickPixelPacket
01597     target,
01598     pixel;
01599 
01600   register const PixelPacket
01601     *p,
01602     *q;
01603 
01604   register const IndexPacket
01605     *indexes,
01606     *target_indexes;
01607 
01608   register long
01609     i,
01610     x;
01611 
01612   CacheView
01613     *image_view,
01614     *target_view;
01615 
01616   assert(image != (Image *) NULL);
01617   assert(image->signature == MagickSignature);
01618   if (image->debug != MagickFalse)
01619     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01620   assert(target_image != (Image *) NULL);
01621   assert(target_image->signature == MagickSignature);
01622   assert(x_offset != (long *) NULL);
01623   assert(y_offset != (long *) NULL);
01624   assert(exception != (ExceptionInfo *) NULL);
01625   x=0;
01626   GetMagickPixelPacket(image,&pixel);
01627   GetMagickPixelPacket(image,&target);
01628   image_view=AcquireCacheView(image);
01629   target_view=AcquireCacheView(target_image);
01630   for (y=(*y_offset); y < (long) image->rows; y++)
01631   {
01632     for (x=y == 0 ? *x_offset : 0; x < (long) image->columns; x++)
01633     {
01634       for (j=0; j < (long) target_image->rows; j++)
01635       {
01636         for (i=0; i < (long) target_image->columns; i++)
01637         {
01638           p=GetCacheViewVirtualPixels(image_view,x+i,y+j,1,1,exception);
01639           indexes=GetCacheViewVirtualIndexQueue(image_view);
01640           SetMagickPixelPacket(image,p,indexes,&pixel);
01641           q=GetCacheViewVirtualPixels(target_view,i,j,1,1,exception);
01642           target_indexes=GetCacheViewVirtualIndexQueue(target_view);
01643           SetMagickPixelPacket(image,q,target_indexes,&target);
01644           if (IsMagickColorSimilar(&pixel,&target) == MagickFalse)
01645             break;
01646         }
01647         if (i < (long) target_image->columns)
01648           break;
01649       }
01650       if (j == (long) target_image->rows)
01651         break;
01652     }
01653     if (x < (long) image->columns)
01654       break;
01655     if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
01656         (QuantumTick(y,image->rows) != MagickFalse))
01657       {
01658         status=image->progress_monitor(SearchImageText,y,image->rows,
01659           image->client_data);
01660         if (status == MagickFalse)
01661           break;
01662       }
01663   }
01664   target_view=DestroyCacheView(target_view);
01665   image_view=DestroyCacheView(image_view);
01666   *x_offset=x;
01667   *y_offset=y;
01668   return(y < (long) image->rows ? MagickTrue : MagickFalse);
01669 }
01670 
01671 /*
01672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01673 %                                                                             %
01674 %                                                                             %
01675 %                                                                             %
01676 +   I s M a g i c k C o l o r S i m i l a r                                   %
01677 %                                                                             %
01678 %                                                                             %
01679 %                                                                             %
01680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01681 %
01682 %  IsMagickColorSimilar() returns true if the distance between two colors is
01683 %  less than the specified distance in a linear three dimensional color space.
01684 %  This method is used by ColorFloodFill() and other algorithms which
01685 %  compare two colors.
01686 %
01687 %  The format of the IsMagickColorSimilar method is:
01688 %
01689 %      MagickBooleanType IsMagickColorSimilar(const MagickPixelPacket *p,
01690 %        const MagickPixelPacket *q)
01691 %
01692 %  A description of each parameter follows:
01693 %
01694 %    o p: Pixel p.
01695 %
01696 %    o q: Pixel q.
01697 %
01698 */
01699 MagickExport MagickBooleanType IsMagickColorSimilar(const MagickPixelPacket *p,
01700   const MagickPixelPacket *q)
01701 {
01702   MagickRealType
01703     fuzz,
01704     pixel;
01705 
01706   register MagickRealType
01707     alpha,
01708     beta,
01709     distance;
01710 
01711   if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
01712     return(IsMagickColorEqual(p,q));
01713   if (p->fuzz == 0.0)
01714     fuzz=MagickMax(q->fuzz,MagickSQ1_2)*MagickMax(q->fuzz,MagickSQ1_2);
01715   else
01716     if (q->fuzz == 0.0)
01717       fuzz=3.0*MagickMax(p->fuzz,MagickSQ1_2)*MagickMax(p->fuzz,MagickSQ1_2);
01718     else
01719       fuzz=3.0*MagickMax(p->fuzz,MagickSQ1_2)*MagickMax(q->fuzz,MagickSQ1_2);
01720   alpha=1.0;
01721   if (p->matte != MagickFalse)
01722     alpha=(MagickRealType) (QuantumScale*(QuantumRange-p->opacity));
01723   beta=1.0;
01724   if (q->matte != MagickFalse)
01725     beta=(MagickRealType) (QuantumScale*(QuantumRange-q->opacity));
01726   if (p->colorspace == CMYKColorspace)
01727     {
01728       alpha*=(MagickRealType) (QuantumScale*(QuantumRange-p->index));
01729       beta*=(MagickRealType) (QuantumScale*(QuantumRange-q->index));
01730     }
01731   pixel=alpha*p->red-beta*q->red;
01732   if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
01733       (p->colorspace == HWBColorspace))
01734     {
01735       if (fabs(p->red-q->red) > (QuantumRange/2))
01736         {
01737           if (p->red > (QuantumRange/2))
01738             pixel=alpha*(p->red-QuantumRange)-beta*q->red;
01739           else
01740             pixel=alpha*p->red-beta*(q->red-QuantumRange);
01741         }
01742         pixel*=2;
01743      }
01744   distance=pixel*pixel;
01745   if (distance > fuzz)
01746     return(MagickFalse);
01747   pixel=alpha*p->green-beta*q->green;
01748   distance+=pixel*pixel;
01749   if (distance > fuzz)
01750     return(MagickFalse);
01751   pixel=alpha*p->blue-beta*q->blue;
01752   distance+=pixel*pixel;
01753   if (distance > fuzz)
01754     return(MagickFalse);
01755   pixel=p->opacity-q->opacity;
01756   distance+=pixel*pixel;
01757   if (distance > fuzz)
01758     return(MagickFalse);
01759   return(MagickTrue);
01760 }
01761 
01762 /*
01763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01764 %                                                                             %
01765 %                                                                             %
01766 %                                                                             %
01767 +   I s O p a c i t y S i m i l a r                                           %
01768 %                                                                             %
01769 %                                                                             %
01770 %                                                                             %
01771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01772 %
01773 %  IsOpacitySimilar() returns true if the distance between two opacity
01774 %  values is less than the specified distance in a linear color space.  This
01775 %  method is used by MatteFloodFill() and other algorithms which compare
01776 %  two opacity values.
01777 %
01778 %  The format of the IsOpacitySimilar method is:
01779 %
01780 %      void IsOpacitySimilar(const Image *image,const PixelPacket *p,
01781 %        const PixelPacket *q)
01782 %
01783 %  A description of each parameter follows:
01784 %
01785 %    o image: the image.
01786 %
01787 %    o p: Pixel p.
01788 %
01789 %    o q: Pixel q.
01790 %
01791 */
01792 MagickExport MagickBooleanType IsOpacitySimilar(const Image *image,
01793   const PixelPacket *p,const PixelPacket *q)
01794 {
01795   MagickRealType
01796     fuzz,
01797     pixel;
01798 
01799   register MagickRealType
01800     distance;
01801 
01802   if (image->matte == MagickFalse)
01803     return(MagickTrue);
01804   if (p->opacity == q->opacity)
01805     return(MagickTrue);
01806   fuzz=MagickMax(image->fuzz,MagickSQ1_2)*MagickMax(image->fuzz,MagickSQ1_2);
01807   pixel=(MagickRealType) p->opacity-(MagickRealType) q->opacity;
01808   distance=pixel*pixel;
01809   if (distance > fuzz)
01810     return(MagickFalse);
01811   return(MagickTrue);
01812 }
01813 
01814 /*
01815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01816 %                                                                             %
01817 %                                                                             %
01818 %                                                                             %
01819 %  L i s t C o l o r I n f o                                                  %
01820 %                                                                             %
01821 %                                                                             %
01822 %                                                                             %
01823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01824 %
01825 %  ListColorInfo() lists color names to the specified file.  Color names
01826 %  are a convenience.  Rather than defining a color by its red, green, and
01827 %  blue intensities just use a color name such as white, blue, or yellow.
01828 %
01829 %  The format of the ListColorInfo method is:
01830 %
01831 %      MagickBooleanType ListColorInfo(FILE *file,ExceptionInfo *exception)
01832 %
01833 %  A description of each parameter follows.
01834 %
01835 %    o file:  List color names to this file handle.
01836 %
01837 %    o exception: return any errors or warnings in this structure.
01838 %
01839 */
01840 MagickExport MagickBooleanType ListColorInfo(FILE *file,
01841   ExceptionInfo *exception)
01842 {
01843   char
01844     tuple[MaxTextExtent];
01845 
01846   const char
01847     *path;
01848 
01849   const ColorInfo
01850     **color_info;
01851 
01852   register long
01853     i;
01854 
01855   unsigned long
01856     number_colors;
01857 
01858   /*
01859     List name and attributes of each color in the list.
01860   */
01861   if (file == (const FILE *) NULL)
01862     file=stdout;
01863   color_info=GetColorInfoList("*",&number_colors,exception);
01864   if (color_info == (const ColorInfo **) NULL)
01865     return(MagickFalse);
01866   path=(const char *) NULL;
01867   for (i=0; i < (long) number_colors; i++)
01868   {
01869     if (color_info[i]->stealth != MagickFalse)
01870       continue;
01871     if ((path == (const char *) NULL) ||
01872         (LocaleCompare(path,color_info[i]->path) != 0))
01873       {
01874         if (color_info[i]->path != (char *) NULL)
01875           (void) fprintf(file,"\nPath: %s\n\n",color_info[i]->path);
01876         (void) fprintf(file,"Name                  Color                  "
01877           "                       Compliance\n");
01878         (void) fprintf(file,"-------------------------------------------------"
01879           "------------------------------\n");
01880       }
01881     path=color_info[i]->path;
01882     (void) fprintf(file,"%-21.21s ",color_info[i]->name);
01883     GetColorTuple(&color_info[i]->color,MagickFalse,tuple);
01884     (void) fprintf(file,"%-45.45s ",tuple);
01885     if ((color_info[i]->compliance & SVGCompliance) != 0)
01886       (void) fprintf(file,"SVG ");
01887     if ((color_info[i]->compliance & X11Compliance) != 0)
01888       (void) fprintf(file,"X11 ");
01889     if ((color_info[i]->compliance & XPMCompliance) != 0)
01890       (void) fprintf(file,"XPM ");
01891     (void) fprintf(file,"\n");
01892   }
01893   color_info=(const ColorInfo **) RelinquishMagickMemory((void *) color_info);
01894   (void) fflush(file);
01895   return(MagickTrue);
01896 }
01897 
01898 /*
01899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01900 %                                                                             %
01901 %                                                                             %
01902 %                                                                             %
01903 +   L o a d C o l o r L i s t                                                 %
01904 %                                                                             %
01905 %                                                                             %
01906 %                                                                             %
01907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01908 %
01909 %  LoadColorList() loads the color configuration file which provides a mapping
01910 %  between color attributes and a color name.
01911 %
01912 %  The format of the LoadColorList method is:
01913 %
01914 %      MagickBooleanType LoadColorList(const char *xml,const char *filename,
01915 %        const unsigned long depth,ExceptionInfo *exception)
01916 %
01917 %  A description of each parameter follows:
01918 %
01919 %    o xml:  The color list in XML format.
01920 %
01921 %    o filename:  The color list filename.
01922 %
01923 %    o depth: depth of <include /> statements.
01924 %
01925 %    o exception: return any errors or warnings in this structure.
01926 %
01927 */
01928 static MagickBooleanType LoadColorList(const char *xml,const char *filename,
01929   const unsigned long depth,ExceptionInfo *exception)
01930 {
01931   char
01932     keyword[MaxTextExtent],
01933     *token;
01934 
01935   ColorInfo
01936     *color_info;
01937 
01938   const char
01939     *q;
01940 
01941   MagickBooleanType
01942     status;
01943 
01944   /*
01945     Load the color map file.
01946   */
01947   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
01948     "Loading color file \"%s\" ...",filename);
01949   if (xml == (char *) NULL)
01950     return(MagickFalse);
01951   if (color_list == (LinkedListInfo *) NULL)
01952     {
01953       color_list=NewLinkedList(0);
01954       if (color_list == (LinkedListInfo *) NULL)
01955         {
01956           ThrowFileException(exception,ResourceLimitError,
01957             "MemoryAllocationFailed",filename);
01958           return(MagickFalse);
01959         }
01960     }
01961   status=MagickTrue;
01962   color_info=(ColorInfo *) NULL;
01963   token=AcquireString(xml);
01964   for (q=(char *) xml; *q != '\0'; )
01965   {
01966     /*
01967       Interpret XML.
01968     */
01969     GetMagickToken(q,&q,token);
01970     if (*token == '\0')
01971       break;
01972     (void) CopyMagickString(keyword,token,MaxTextExtent);
01973     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
01974       {
01975         /*
01976           Doctype element.
01977         */
01978         while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
01979           GetMagickToken(q,&q,token);
01980         continue;
01981       }
01982     if (LocaleNCompare(keyword,"<!--",4) == 0)
01983       {
01984         /*
01985           Comment element.
01986         */
01987         while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
01988           GetMagickToken(q,&q,token);
01989         continue;
01990       }
01991     if (LocaleCompare(keyword,"<include") == 0)
01992       {
01993         /*
01994           Include element.
01995         */
01996         while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
01997         {
01998           (void) CopyMagickString(keyword,token,MaxTextExtent);
01999           GetMagickToken(q,&q,token);
02000           if (*token != '=')
02001             continue;
02002           GetMagickToken(q,&q,token);
02003           if (LocaleCompare(keyword,"file") == 0)
02004             {
02005               if (depth > 200)
02006                 (void) ThrowMagickException(exception,GetMagickModule(),
02007                   ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
02008               else
02009                 {
02010                   char
02011                     path[MaxTextExtent],
02012                     *xml;
02013 
02014                   GetPathComponent(filename,HeadPath,path);
02015                   if (*path != '\0')
02016                     (void) ConcatenateMagickString(path,DirectorySeparator,
02017                       MaxTextExtent);
02018                   if (*token == *DirectorySeparator)
02019                     (void) CopyMagickString(path,token,MaxTextExtent);
02020                   else
02021                     (void) ConcatenateMagickString(path,token,MaxTextExtent);
02022                   xml=FileToString(path,~0,exception);
02023                   if (xml != (char *) NULL)
02024                     {
02025                       status=LoadColorList(xml,path,depth+1,exception);
02026                       xml=(char *) RelinquishMagickMemory(xml);
02027                     }
02028                 }
02029             }
02030         }
02031         continue;
02032       }
02033     if (LocaleCompare(keyword,"<color") == 0)
02034       {
02035         /*
02036           Color element.
02037         */
02038         color_info=(ColorInfo *) AcquireMagickMemory(sizeof(*color_info));
02039         if (color_info == (ColorInfo *) NULL)
02040           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
02041         (void) ResetMagickMemory(color_info,0,sizeof(*color_info));
02042         color_info->path=ConstantString(filename);
02043         color_info->exempt=MagickFalse;
02044         color_info->signature=MagickSignature;
02045         continue;
02046       }
02047     if (color_info == (ColorInfo *) NULL)
02048       continue;
02049     if (LocaleCompare(keyword,"/>") == 0)
02050       {
02051         status=AppendValueToLinkedList(color_list,color_info);
02052         if (status == MagickFalse)
02053           (void) ThrowMagickException(exception,GetMagickModule(),
02054             ResourceLimitError,"MemoryAllocationFailed","`%s'",
02055             color_info->name);
02056         color_info=(ColorInfo *) NULL;
02057       }
02058     GetMagickToken(q,(const char **) NULL,token);
02059     if (*token != '=')
02060       continue;
02061     GetMagickToken(q,&q,token);
02062     GetMagickToken(q,&q,token);
02063     switch (*keyword)
02064     {
02065       case 'C':
02066       case 'c':
02067       {
02068         if (LocaleCompare((char *) keyword,"color") == 0)
02069           {
02070             (void) QueryMagickColor(token,&color_info->color,exception);
02071             break;
02072           }
02073         if (LocaleCompare((char *) keyword,"compliance") == 0)
02074           {
02075             long
02076               compliance;
02077 
02078             compliance=color_info->compliance;
02079             if (GlobExpression(token,"*SVG*",MagickTrue) != MagickFalse)
02080               compliance|=SVGCompliance;
02081             if (GlobExpression(token,"*X11*",MagickTrue) != MagickFalse)
02082               compliance|=X11Compliance;
02083             if (GlobExpression(token,"*XPM*",MagickTrue) != MagickFalse)
02084               compliance|=XPMCompliance;
02085             color_info->compliance=(ComplianceType) compliance;
02086             break;
02087           }
02088         break;
02089       }
02090       case 'N':
02091       case 'n':
02092       {
02093         if (LocaleCompare((char *) keyword,"name") == 0)
02094           {
02095             color_info->name=ConstantString(token);
02096             break;
02097           }
02098         break;
02099       }
02100       case 'S':
02101       case 's':
02102       {
02103         if (LocaleCompare((char *) keyword,"stealth") == 0)
02104           {
02105             color_info->stealth=IsMagickTrue(token);
02106             break;
02107           }
02108         break;
02109       }
02110       default:
02111         break;
02112     }
02113   }
02114   token=(char *) RelinquishMagickMemory(token);
02115   return(status);
02116 }
02117 
02118 /*
02119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02120 %                                                                             %
02121 %                                                                             %
02122 %                                                                             %
02123 %  L o a d C o l o r L i s t s                                                %
02124 %                                                                             %
02125 %                                                                             %
02126 %                                                                             %
02127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02128 %
02129 %  LoadColorList() loads one or more color configuration file which provides a
02130 %  mapping between color attributes and a color name.
02131 %
02132 %  The format of the LoadColorLists method is:
02133 %
02134 %      MagickBooleanType LoadColorLists(const char *filename,
02135 %        ExceptionInfo *exception)
02136 %
02137 %  A description of each parameter follows:
02138 %
02139 %    o filename: the font file name.
02140 %
02141 %    o exception: return any errors or warnings in this structure.
02142 %
02143 */
02144 static MagickBooleanType LoadColorLists(const char *filename,
02145   ExceptionInfo *exception)
02146 {
02147   const StringInfo
02148     *option;
02149 
02150   LinkedListInfo
02151     *options;
02152 
02153   MagickRealType
02154     scale;
02155 
02156   MagickStatusType
02157     status;
02158 
02159   register long
02160     i;
02161 
02162   /*
02163     Load built-in color map.
02164   */
02165   status=MagickFalse;
02166   if (color_list == (LinkedListInfo *) NULL)
02167     {
02168       color_list=NewLinkedList(0);
02169       if (color_list == (LinkedListInfo *) NULL)
02170         {
02171           ThrowFileException(exception,ResourceLimitError,
02172             "MemoryAllocationFailed",filename);
02173           return(MagickFalse);
02174         }
02175     }
02176   scale=(MagickRealType) ScaleCharToQuantum(1);
02177   for (i=0; i < (long) (sizeof(ColorMap)/sizeof(*ColorMap)); i++)
02178   {
02179     ColorInfo
02180       *color_info;
02181 
02182     register const ColorMapInfo
02183       *p;
02184 
02185     p=ColorMap+i;
02186     color_info=(ColorInfo *) AcquireMagickMemory(sizeof(*color_info));
02187     if (color_info == (ColorInfo *) NULL)
02188       {
02189         (void) ThrowMagickException(exception,GetMagickModule(),
02190           ResourceLimitError,"MemoryAllocationFailed","`%s'",color_info->name);
02191         continue;
02192       }
02193     (void) ResetMagickMemory(color_info,0,sizeof(*color_info));
02194     color_info->path=(char *) "[built-in]";
02195     color_info->name=(char *) p->name;
02196     GetMagickPixelPacket((Image *) NULL,&color_info->color);
02197     color_info->color.red=scale*p->red;
02198     color_info->color.green=scale*p->green;
02199     color_info->color.blue=scale*p->blue;
02200     color_info->color.opacity=(MagickRealType) (QuantumRange-QuantumRange*
02201       p->alpha);
02202     color_info->compliance=(ComplianceType) p->compliance;
02203     color_info->exempt=MagickTrue;
02204     color_info->signature=MagickSignature;
02205     status=AppendValueToLinkedList(color_list,color_info);
02206     if (status == MagickFalse)
02207       (void) ThrowMagickException(exception,GetMagickModule(),
02208         ResourceLimitError,"MemoryAllocationFailed","`%s'",color_info->name);
02209   }
02210   /*
02211     Load external color map.
02212   */
02213   options=GetConfigureOptions(filename,exception);
02214   option=(const StringInfo *) GetNextValueInLinkedList(options);
02215   while (option != (const StringInfo *) NULL)
02216   {
02217     status|=LoadColorList((const char *) GetStringInfoDatum(option),
02218       GetStringInfoPath(option),0,exception);
02219     option=(const StringInfo *) GetNextValueInLinkedList(options);
02220   }
02221   options=DestroyConfigureOptions(options);
02222   return(status != 0 ? MagickTrue : MagickFalse);
02223 }
02224 
02225 /*
02226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02227 %                                                                             %
02228 %                                                                             %
02229 %                                                                             %
02230 %   Q u e r y C o l o r D a t a b a s e                                       %
02231 %                                                                             %
02232 %                                                                             %
02233 %                                                                             %
02234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02235 %
02236 %  QueryColorDatabase() returns the red, green, blue, and opacity intensities
02237 %  for a given color name.
02238 %
02239 %  The format of the QueryColorDatabase method is:
02240 %
02241 %      MagickBooleanType QueryColorDatabase(const char *name,PixelPacket *color,
02242 %        ExceptionInfo *exception)
02243 %
02244 %  A description of each parameter follows:
02245 %
02246 %    o name: the color name (e.g. white, blue, yellow).
02247 %
02248 %    o color: the red, green, blue, and opacity intensities values of the
02249 %      named color in this structure.
02250 %
02251 %    o exception: return any errors or warnings in this structure.
02252 %
02253 */
02254 
02255 static inline double MagickMin(const double x,const double y)
02256 {
02257   if (x < y)
02258     return(x);
02259   return(y);
02260 }
02261 
02262 MagickExport MagickBooleanType QueryColorDatabase(const char *name,
02263   PixelPacket *color,ExceptionInfo *exception)
02264 {
02265   MagickBooleanType
02266     status;
02267 
02268   MagickPixelPacket
02269     pixel;
02270 
02271   status=QueryMagickColor(name,&pixel,exception);
02272   color->opacity=RoundToQuantum(pixel.opacity);
02273   if (pixel.colorspace == CMYKColorspace)
02274     {
02275       color->red=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
02276         QuantumRange,(MagickRealType) (QuantumScale*pixel.red*(QuantumRange-
02277         pixel.index)+pixel.index))));
02278       color->green=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
02279         QuantumRange,(MagickRealType) (QuantumScale*pixel.green*(QuantumRange-
02280         pixel.index)+pixel.index))));
02281       color->blue=RoundToQuantum((MagickRealType) (QuantumRange-MagickMin(
02282         QuantumRange,(MagickRealType) (QuantumScale*pixel.blue*(QuantumRange-
02283         pixel.index)+pixel.index))));
02284       return(status);
02285     }
02286   color->red=RoundToQuantum(pixel.red);
02287   color->green=RoundToQuantum(pixel.green);
02288   color->blue=RoundToQuantum(pixel.blue);
02289   return(status);
02290 }
02291 
02292 /*
02293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02294 %                                                                             %
02295 %                                                                             %
02296 %                                                                             %
02297 %  Q u e r y C o l o r n a m e                                                %
02298 %                                                                             %
02299 %                                                                             %
02300 %                                                                             %
02301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02302 %
02303 %  QueryColorname() returns a named color for the given color intensity.  If
02304 %  an exact match is not found, a rgb() color is returned instead.
02305 %
02306 %  The format of the QueryColorname method is:
02307 %
02308 %      MagickBooleanType QueryColorname(const Image *image,
02309 %        const PixelPacket *color,const ComplianceType compliance,char *name,
02310 %        ExceptionInfo *exception)
02311 %
02312 %  A description of each parameter follows.
02313 %
02314 %    o image: the image.
02315 %
02316 %    o color: the color intensities.
02317 %
02318 %    o compliance: Adhere to this color standard: SVG, X11, or XPM.
02319 %
02320 %    o name: Return the color name or hex value.
02321 %
02322 %    o exception: return any errors or warnings in this structure.
02323 %
02324 */
02325 MagickExport MagickBooleanType QueryColorname(const Image *image,
02326   const PixelPacket *color,const ComplianceType compliance,char *name,
02327   ExceptionInfo *exception)
02328 {
02329   MagickPixelPacket
02330     pixel;
02331 
02332   GetMagickPixelPacket(image,&pixel);
02333   SetMagickPixelPacket(image,color,(IndexPacket *) NULL,&pixel);
02334   return(QueryMagickColorname(image,&pixel,compliance,name,exception));
02335 }
02336 
02337 /*
02338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02339 %                                                                             %
02340 %                                                                             %
02341 %                                                                             %
02342 %   Q u e r y M a g i c k C o l o r                                           %
02343 %                                                                             %
02344 %                                                                             %
02345 %                                                                             %
02346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02347 %
02348 %  QueryMagickColor() returns the red, green, blue, and opacity intensities
02349 %  for a given color name.
02350 %
02351 %  The format of the QueryMagickColor method is:
02352 %
02353 %      MagickBooleanType QueryMagickColor(const char *name,
02354 %        MagickPixelPacket *color,ExceptionInfo *exception)
02355 %
02356 %  A description of each parameter follows:
02357 %
02358 %    o name: the color name (e.g. white, blue, yellow).
02359 %
02360 %    o color: the red, green, blue, and opacity intensities values of the
02361 %      named color in this structure.
02362 %
02363 %    o exception: return any errors or warnings in this structure.
02364 %
02365 */
02366 MagickExport MagickBooleanType QueryMagickColor(const char *name,
02367   MagickPixelPacket *color,ExceptionInfo *exception)
02368 {
02369   GeometryInfo
02370     geometry_info;
02371 
02372   long
02373     type;
02374 
02375   MagickRealType
02376     scale;
02377 
02378   MagickStatusType
02379     flags;
02380 
02381   register const ColorInfo
02382     *p;
02383 
02384   register long
02385     i;
02386 
02387   /*
02388     Initialize color return value.
02389   */
02390   assert(name != (const char *) NULL);
02391   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
02392   assert(color != (MagickPixelPacket *) NULL);
02393   GetMagickPixelPacket((Image *) NULL,color);
02394   if ((name == (char *) NULL) || (*name == '\0'))
02395     name=BackgroundColor;
02396   while (isspace((int) ((unsigned char) *name)) != 0)
02397     name++;
02398   if (*name == '#')
02399     {
02400       char
02401         c;
02402 
02403       LongPixelPacket
02404         pixel;
02405 
02406       QuantumAny
02407         range;
02408 
02409       unsigned long
02410         depth,
02411         n;
02412 
02413       /*
02414         Parse hex color.
02415       */
02416       (void) ResetMagickMemory(&pixel,0,sizeof(pixel));
02417       name++;
02418       for (n=0; isxdigit((int) ((unsigned char) name[n])) != MagickFalse; n++) ;
02419       if ((n % 3) == 0)
02420         {
02421           do
02422           {
02423             pixel.red=pixel.green;
02424             pixel.green=pixel.blue;
02425             pixel.blue=0;
02426             for (i=(long) (n/3-1); i >= 0; i--)
02427             {
02428               c=(*name++);
02429               pixel.blue<<=4;
02430               if ((c >= '0') && (c <= '9'))
02431                 pixel.blue|=(int) (c-'0');
02432               else
02433                 if ((c >= 'A') && (c <= 'F'))
02434                   pixel.blue|=(int) c-((int) 'A'-10);
02435                 else
02436                   if ((c >= 'a') && (c <= 'f'))
02437                     pixel.blue|=(int) c-((int) 'a'-10);
02438                   else
02439                     return(MagickFalse);
02440             }
02441           } while (isxdigit((int) ((unsigned char) *name)) != MagickFalse);
02442           depth=4*(n/3);
02443         }
02444       else
02445         {
02446           if ((n % 4) != 0)
02447             {
02448               (void) ThrowMagickException(exception,GetMagickModule(),
02449                 OptionWarning,"UnrecognizedColor","`%s'",name);
02450               return(MagickFalse);
02451             }
02452           do
02453           {
02454             pixel.red=pixel.green;
02455             pixel.green=pixel.blue;
02456             pixel.blue=pixel.opacity;
02457             pixel.opacity=0;
02458             for (i=(long) (n/4-1); i >= 0; i--)
02459             {
02460               c=(*name++);
02461               pixel.opacity<<=4;
02462               if ((c >= '0') && (c <= '9'))
02463                 pixel.opacity|=(int) (c-'0');
02464               else
02465                 if ((c >= 'A') && (c <= 'F'))
02466                   pixel.opacity|=(int) c-((int) 'A'-10);
02467                 else
02468                   if ((c >= 'a') && (c <= 'f'))
02469                     pixel.opacity|=(int) c-((int) 'a'-10);
02470                   else
02471                     return(MagickFalse);
02472             }
02473           } while (isxdigit((int) ((unsigned char) *name)) != MagickFalse);
02474           depth=4*(n/4);
02475         }
02476       color->colorspace=RGBColorspace;
02477       color->matte=MagickFalse;
02478       range=GetQuantumRange(depth);
02479       color->red=(MagickRealType) ScaleAnyToQuantum(pixel.red,range);
02480       color->green=(MagickRealType) ScaleAnyToQuantum(pixel.green,range);
02481       color->blue=(MagickRealType) ScaleAnyToQuantum(pixel.blue,range);
02482       color->opacity=(MagickRealType) OpaqueOpacity;
02483       if ((n % 3) != 0)
02484         {
02485           color->matte=MagickTrue;
02486           color->opacity=(MagickRealType) (QuantumRange-ScaleAnyToQuantum(
02487             pixel.opacity,range));
02488         }
02489       color->index=0.0;
02490       return(MagickTrue);
02491     }
02492   if (strchr(name,'(') != (char *) NULL)
02493     {
02494       char
02495         colorspace[MaxTextExtent];
02496 
02497       /*
02498         Parse color of the form rgb(100,255,0).
02499       */
02500       (void) CopyMagickString(colorspace,name,MaxTextExtent);
02501       for (i=0; colorspace[i] != '\0'; i++)
02502         if (colorspace[i] == '(')
02503           break;
02504       colorspace[i--]='\0';
02505       LocaleLower(colorspace);
02506       color->matte=MagickFalse;
02507       if ((i > 0) && (colorspace[i] == 'a'))
02508         {
02509           colorspace[i]='\0';
02510           color->matte=MagickTrue;
02511         }
02512       type=ParseMagickOption(MagickColorspaceOptions,MagickFalse,colorspace);
02513       if (type < 0)
02514         {
02515           (void) ThrowMagickException(exception,GetMagickModule(),
02516             OptionWarning,"UnrecognizedColor","`%s'",name);
02517           return(MagickFalse);
02518         }
02519       color->colorspace=(ColorspaceType) type;
02520       SetGeometryInfo(&geometry_info);
02521       flags=ParseGeometry(name+i+1,&geometry_info);
02522       scale=(MagickRealType) ScaleCharToQuantum(1);
02523       if ((flags & PercentValue) != 0)
02524         scale=(MagickRealType) (QuantumRange/100.0);
02525       if ((flags & RhoValue) != 0)
02526         color->red=(MagickRealType) RoundToQuantum(scale*geometry_info.rho);
02527       if ((flags & SigmaValue) != 0)
02528         color->green=(MagickRealType) RoundToQuantum(scale*geometry_info.sigma);
02529       if ((flags & XiValue) != 0)
02530         color->blue=(MagickRealType) RoundToQuantum(scale*geometry_info.xi);
02531       color->opacity=(MagickRealType) OpaqueOpacity;
02532       if ((flags & PsiValue) != 0)
02533         {
02534           if (color->colorspace == CMYKColorspace)
02535             color->index=(MagickRealType) RoundToQuantum(scale*
02536               geometry_info.psi);
02537           else
02538             if (color->matte != MagickFalse)
02539               color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
02540                 (QuantumRange-QuantumRange*geometry_info.psi));
02541         }
02542       if (((flags & ChiValue) != 0) && (color->matte != MagickFalse))
02543         color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
02544           (QuantumRange-QuantumRange*geometry_info.chi));
02545       if (LocaleCompare(colorspace,"gray") == 0)
02546         {
02547           color->green=color->red;
02548           color->blue=color->red;
02549           if (((flags & SigmaValue) != 0) && (color->matte != MagickFalse))
02550             color->opacity=(MagickRealType) RoundToQuantum((MagickRealType)
02551               (QuantumRange-QuantumRange*geometry_info.sigma));
02552         }
02553       if ((LocaleCompare(colorspace,"HSB") == 0) ||
02554           (LocaleCompare(colorspace,"HSL") == 0) ||
02555           (LocaleCompare(colorspace,"HWB") == 0))
02556         {
02557           PixelPacket
02558             pixel;
02559 
02560           scale=1.0/360.0;
02561           if ((flags & PercentValue) != 0)
02562             scale=1.0/100.0;
02563           geometry_info.rho*=360.0*scale;
02564           scale=1.0/255.0;
02565           if ((flags & PercentValue) != 0)
02566             scale=1.0/100.0;
02567           geometry_info.sigma*=scale;
02568           geometry_info.xi*=scale;
02569           if (LocaleCompare(colorspace,"HSB") == 0)
02570             ConvertHSBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
02571               360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
02572               &pixel.green,&pixel.blue);
02573           else
02574             if (LocaleCompare(colorspace,"HSL") == 0)
02575               ConvertHSLToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
02576                 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
02577                 &pixel.green,&pixel.blue);
02578             else
02579               ConvertHWBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/
02580                 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red,
02581                 &pixel.green,&pixel.blue);
02582           color->colorspace=RGBColorspace;
02583           color->red=(MagickRealType) pixel.red;
02584           color->green=(MagickRealType) pixel.green;
02585           color->blue=(MagickRealType) pixel.blue;
02586         }
02587       return(MagickTrue);
02588     }
02589   /*
02590     Parse named color.
02591   */
02592   p=GetColorInfo(name,exception);
02593   if (p == (const ColorInfo *) NULL)
02594     return(MagickFalse);
02595   color->colorspace=RGBColorspace;
02596   color->matte=p->color.opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
02597   color->red=(MagickRealType) p->color.red;
02598   color->green=(MagickRealType) p->color.green;
02599   color->blue=(MagickRealType) p->color.blue;
02600   color->opacity=(MagickRealType) p->color.opacity;
02601   color->index=0.0;
02602   return(MagickTrue);
02603 }
02604 
02605 /*
02606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02607 %                                                                             %
02608 %                                                                             %
02609 %                                                                             %
02610 %  Q u e r y M a g i c k C o l o r n a m e                                    %
02611 %                                                                             %
02612 %                                                                             %
02613 %                                                                             %
02614 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02615 %
02616 %  QueryMagickColorname() returns a named color for the given color intensity.
02617 %  If an exact match is not found, a hex value is returned instead.  For
02618 %  example an intensity of rgb:(0,0,0) returns black whereas rgb:(223,223,223)
02619 %  returns #dfdfdf.
02620 %
02621 %  The format of the QueryMagickColorname method is:
02622 %
02623 %      MagickBooleanType QueryMagickColorname(const Image *image,
02624 %        const PixelPacket *color,const ComplianceType compliance,char *name,
02625 %        ExceptionInfo *exception)
02626 %
02627 %  A description of each parameter follows.
02628 %
02629 %    o image: the image.
02630 %
02631 %    o color: the color intensities.
02632 %
02633 %    o Compliance: Adhere to this color standard: SVG, X11, or XPM.
02634 %
02635 %    o name: Return the color name or hex value.
02636 %
02637 %    o exception: return any errors or warnings in this structure.
02638 %
02639 */
02640 MagickExport MagickBooleanType QueryMagickColorname(const Image *image,
02641   const MagickPixelPacket *color,const ComplianceType compliance,
02642   char *name,ExceptionInfo *exception)
02643 {
02644   MagickPixelPacket
02645     pixel;
02646 
02647   MagickRealType
02648     opacity;
02649 
02650   register const ColorInfo
02651     *p;
02652 
02653   *name='\0';
02654   pixel=(*color);
02655   if (compliance == XPMCompliance)
02656     {
02657       pixel.matte=MagickFalse;
02658       pixel.depth=(unsigned long) MagickMin(1.0*image->depth,16.0);
02659       GetColorTuple(&pixel,MagickTrue,name);
02660       return(MagickTrue);
02661     }
02662   GetColorTuple(&pixel,compliance != SVGCompliance ? MagickTrue : MagickFalse,
02663     name);
02664   (void) GetColorInfo("*",exception);
02665   ResetLinkedListIterator(color_list);
02666   opacity=image->matte != MagickFalse ? color->opacity : OpaqueOpacity;
02667   p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
02668   while (p != (const ColorInfo *) NULL)
02669   {
02670     if (((p->compliance & compliance) != 0) && ((p->color.red == color->red)) &&
02671          (p->color.green == color->green) && (p->color.blue == color->blue) &&
02672          (p->color.opacity == opacity))
02673       {
02674         (void) CopyMagickString(name,p->name,MaxTextExtent);
02675         break;
02676       }
02677     p=(const ColorInfo *) GetNextValueInLinkedList(color_list);
02678   }
02679   return(MagickTrue);
02680 }

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1