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