IMG_xpm.c
author Ozkan Sezer <sezeroz@gmail.com>
Sat, 13 Oct 2018 15:02:56 +0300
changeset 596 4b70bfe18fb7
parent 575 36e9e2255178
child 638 e3e9d7430674
permissions -rw-r--r--
fix build against libpng-1.5.x versions.
     1 /*
     2   SDL_image:  An example image loading library for use with SDL
     3   Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 
    22 /*
    23  * XPM (X PixMap) image loader:
    24  *
    25  * Supports the XPMv3 format, EXCEPT:
    26  * - hotspot coordinates are ignored
    27  * - only colour ('c') colour symbols are used
    28  * - rgb.txt is not used (for portability), so only RGB colours
    29  *   are recognized (#rrggbb etc) - only a few basic colour names are
    30  *   handled
    31  *
    32  * The result is an 8bpp indexed surface if possible, otherwise 32bpp.
    33  * The colourkey is correctly set if transparency is used.
    34  *
    35  * Besides the standard API, also provides
    36  *
    37  *     SDL_Surface *IMG_ReadXPMFromArray(char **xpm)
    38  *
    39  * that reads the image data from an XPM file included in the C source.
    40  *
    41  * TODO: include rgb.txt here. The full table (from solaris 2.6) only
    42  * requires about 13K in binary form.
    43  */
    44 
    45 #include "SDL_image.h"
    46 
    47 #ifdef LOAD_XPM
    48 
    49 /* See if an image is contained in a data source */
    50 int IMG_isXPM(SDL_RWops *src)
    51 {
    52     Sint64 start;
    53     int is_XPM;
    54     char magic[9];
    55 
    56     if ( !src )
    57         return 0;
    58     start = SDL_RWtell(src);
    59     is_XPM = 0;
    60     if ( SDL_RWread(src, magic, sizeof(magic), 1) ) {
    61         if ( SDL_memcmp(magic, "/* XPM */", sizeof(magic)) == 0 ) {
    62             is_XPM = 1;
    63         }
    64     }
    65     SDL_RWseek(src, start, RW_SEEK_SET);
    66     return(is_XPM);
    67 }
    68 
    69 /* Hash table to look up colors from pixel strings */
    70 #define STARTING_HASH_SIZE 256
    71 
    72 struct hash_entry {
    73     char *key;
    74     Uint32 color;
    75     struct hash_entry *next;
    76 };
    77 
    78 struct color_hash {
    79     struct hash_entry **table;
    80     struct hash_entry *entries; /* array of all entries */
    81     struct hash_entry *next_free;
    82     int size;
    83     int maxnum;
    84 };
    85 
    86 static int hash_key(const char *key, int cpp, int size)
    87 {
    88     int hash;
    89 
    90     hash = 0;
    91     while ( cpp-- > 0 ) {
    92         hash = hash * 33 + *key++;
    93     }
    94     return hash & (size - 1);
    95 }
    96 
    97 static struct color_hash *create_colorhash(int maxnum)
    98 {
    99     int bytes, s;
   100     struct color_hash *hash;
   101 
   102     /* we know how many entries we need, so we can allocate
   103        everything here */
   104     hash = (struct color_hash *)SDL_malloc(sizeof *hash);
   105     if (!hash)
   106         return NULL;
   107 
   108     /* use power-of-2 sized hash table for decoding speed */
   109     for (s = STARTING_HASH_SIZE; s < maxnum; s <<= 1)
   110         ;
   111     hash->size = s;
   112     hash->maxnum = maxnum;
   113     bytes = hash->size * sizeof(struct hash_entry **);
   114     hash->entries = NULL;   /* in case malloc fails */
   115     hash->table = (struct hash_entry **)SDL_malloc(bytes);
   116     if (!hash->table) {
   117         SDL_free(hash);
   118         return NULL;
   119     }
   120     SDL_memset(hash->table, 0, bytes);
   121     hash->entries = (struct hash_entry *)SDL_malloc(maxnum * sizeof(struct hash_entry));
   122     if (!hash->entries) {
   123         SDL_free(hash->table);
   124         SDL_free(hash);
   125         return NULL;
   126     }
   127     hash->next_free = hash->entries;
   128     return hash;
   129 }
   130 
   131 static int add_colorhash(struct color_hash *hash,
   132                          char *key, int cpp, Uint32 color)
   133 {
   134     int index = hash_key(key, cpp, hash->size);
   135     struct hash_entry *e = hash->next_free++;
   136     e->color = color;
   137     e->key = key;
   138     e->next = hash->table[index];
   139     hash->table[index] = e;
   140     return 1;
   141 }
   142 
   143 /* fast lookup that works if cpp == 1 */
   144 #define QUICK_COLORHASH(hash, key) ((hash)->table[*(Uint8 *)(key)]->color)
   145 
   146 static Uint32 get_colorhash(struct color_hash *hash, const char *key, int cpp)
   147 {
   148     struct hash_entry *entry = hash->table[hash_key(key, cpp, hash->size)];
   149     while (entry) {
   150         if (SDL_memcmp(key, entry->key, cpp) == 0)
   151             return entry->color;
   152         entry = entry->next;
   153     }
   154     return 0;       /* garbage in - garbage out */
   155 }
   156 
   157 static void free_colorhash(struct color_hash *hash)
   158 {
   159     if (hash) {
   160         if (hash->table)
   161             SDL_free(hash->table);
   162         if (hash->entries)
   163             SDL_free(hash->entries);
   164         SDL_free(hash);
   165     }
   166 }
   167 
   168 /*
   169  * convert colour spec to RGB (in 0xrrggbb format).
   170  * return 1 if successful.
   171  */
   172 static int color_to_rgb(char *spec, int speclen, Uint32 *rgb)
   173 {
   174     /* poor man's rgb.txt */
   175     static struct { char *name; Uint32 rgb; } known[] = {
   176         { "none",                 0xFFFFFFFF },
   177         { "black",                0x000000 },
   178         { "white",                0xFFFFFF },
   179         { "red",                  0xFF0000 },
   180         { "green",                0x00FF00 },
   181         { "blue",                 0x0000FF },
   182 /* This table increases the size of the library by 40K, so it's disabled by default */
   183 #ifdef EXTENDED_XPM_COLORS
   184         { "aliceblue",            0xf0f8ff },
   185         { "antiquewhite",         0xfaebd7 },
   186         { "antiquewhite1",        0xffefdb },
   187         { "antiquewhite2",        0xeedfcc },
   188         { "antiquewhite3",        0xcdc0b0 },
   189         { "antiquewhite4",        0x8b8378 },
   190         { "aqua",                 0x00ffff },
   191         { "aquamarine",           0x7fffd4 },
   192         { "aquamarine1",          0x7fffd4 },
   193         { "aquamarine2",          0x76eec6 },
   194         { "aquamarine3",          0x66cdaa },
   195         { "aquamarine4",          0x458b74 },
   196         { "azure",                0xf0ffff },
   197         { "azure1",               0xf0ffff },
   198         { "azure2",               0xe0eeee },
   199         { "azure3",               0xc1cdcd },
   200         { "azure4",               0x838b8b },
   201         { "beige",                0xf5f5dc },
   202         { "bisque",               0xffe4c4 },
   203         { "bisque1",              0xffe4c4 },
   204         { "bisque2",              0xeed5b7 },
   205         { "bisque3",              0xcdb79e },
   206         { "bisque4",              0x8b7d6b },
   207         { "black",                0x000000 },
   208         { "blanchedalmond",       0xffebcd },
   209         { "blue",                 0x0000ff },
   210         { "blue1",                0x0000ff },
   211         { "blue2",                0x0000ee },
   212         { "blue3",                0x0000cd },
   213         { "blue4",                0x00008B },
   214         { "blueviolet",           0x8a2be2 },
   215         { "brown",                0xA52A2A },
   216         { "brown1",               0xFF4040 },
   217         { "brown2",               0xEE3B3B },
   218         { "brown3",               0xCD3333 },
   219         { "brown4",               0x8B2323 },
   220         { "burlywood",            0xDEB887 },
   221         { "burlywood1",           0xFFD39B },
   222         { "burlywood2",           0xEEC591 },
   223         { "burlywood3",           0xCDAA7D },
   224         { "burlywood4",           0x8B7355 },
   225         { "cadetblue",            0x5F9EA0 },
   226         { "cadetblue",            0x5f9ea0 },
   227         { "cadetblue1",           0x98f5ff },
   228         { "cadetblue2",           0x8ee5ee },
   229         { "cadetblue3",           0x7ac5cd },
   230         { "cadetblue4",           0x53868b },
   231         { "chartreuse",           0x7FFF00 },
   232         { "chartreuse1",          0x7FFF00 },
   233         { "chartreuse2",          0x76EE00 },
   234         { "chartreuse3",          0x66CD00 },
   235         { "chartreuse4",          0x458B00 },
   236         { "chocolate",            0xD2691E },
   237         { "chocolate1",           0xFF7F24 },
   238         { "chocolate2",           0xEE7621 },
   239         { "chocolate3",           0xCD661D },
   240         { "chocolate4",           0x8B4513 },
   241         { "coral",                0xFF7F50 },
   242         { "coral1",               0xFF7256 },
   243         { "coral2",               0xEE6A50 },
   244         { "coral3",               0xCD5B45 },
   245         { "coral4",               0x8B3E2F },
   246         { "cornflowerblue",       0x6495ed },
   247         { "cornsilk",             0xFFF8DC },
   248         { "cornsilk1",            0xFFF8DC },
   249         { "cornsilk2",            0xEEE8CD },
   250         { "cornsilk3",            0xCDC8B1 },
   251         { "cornsilk4",            0x8B8878 },
   252         { "crimson",              0xDC143C },
   253         { "cyan",                 0x00FFFF },
   254         { "cyan1",                0x00FFFF },
   255         { "cyan2",                0x00EEEE },
   256         { "cyan3",                0x00CDCD },
   257         { "cyan4",                0x008B8B },
   258         { "darkblue",             0x00008b },
   259         { "darkcyan",             0x008b8b },
   260         { "darkgoldenrod",        0xb8860b },
   261         { "darkgoldenrod1",       0xffb90f },
   262         { "darkgoldenrod2",       0xeead0e },
   263         { "darkgoldenrod3",       0xcd950c },
   264         { "darkgoldenrod4",       0x8b6508 },
   265         { "darkgray",             0xa9a9a9 },
   266         { "darkgreen",            0x006400 },
   267         { "darkgrey",             0xa9a9a9 },
   268         { "darkkhaki",            0xbdb76b },
   269         { "darkmagenta",          0x8b008b },
   270         { "darkolivegreen",       0x556b2f },
   271         { "darkolivegreen1",      0xcaff70 },
   272         { "darkolivegreen2",      0xbcee68 },
   273         { "darkolivegreen3",      0xa2cd5a },
   274         { "darkolivegreen4",      0x6e8b3d },
   275         { "darkorange",           0xff8c00 },
   276         { "darkorange1",          0xff7f00 },
   277         { "darkorange2",          0xee7600 },
   278         { "darkorange3",          0xcd6600 },
   279         { "darkorange4",          0x8b4500 },
   280         { "darkorchid",           0x9932cc },
   281         { "darkorchid1",          0xbf3eff },
   282         { "darkorchid2",          0xb23aee },
   283         { "darkorchid3",          0x9a32cd },
   284         { "darkorchid4",          0x68228b },
   285         { "darkred",              0x8b0000 },
   286         { "darksalmon",           0xe9967a },
   287         { "darkseagreen",         0x8fbc8f },
   288         { "darkseagreen1",        0xc1ffc1 },
   289         { "darkseagreen2",        0xb4eeb4 },
   290         { "darkseagreen3",        0x9bcd9b },
   291         { "darkseagreen4",        0x698b69 },
   292         { "darkslateblue",        0x483d8b },
   293         { "darkslategray",        0x2f4f4f },
   294         { "darkslategray1",       0x97ffff },
   295         { "darkslategray2",       0x8deeee },
   296         { "darkslategray3",       0x79cdcd },
   297         { "darkslategray4",       0x528b8b },
   298         { "darkslategrey",        0x2f4f4f },
   299         { "darkturquoise",        0x00ced1 },
   300         { "darkviolet",           0x9400D3 },
   301         { "darkviolet",           0x9400d3 },
   302         { "deeppink",             0xff1493 },
   303         { "deeppink1",            0xff1493 },
   304         { "deeppink2",            0xee1289 },
   305         { "deeppink3",            0xcd1076 },
   306         { "deeppink4",            0x8b0a50 },
   307         { "deepskyblue",          0x00bfff },
   308         { "deepskyblue1",         0x00bfff },
   309         { "deepskyblue2",         0x00b2ee },
   310         { "deepskyblue3",         0x009acd },
   311         { "deepskyblue4",         0x00688b },
   312         { "dimgray",              0x696969 },
   313         { "dimgrey",              0x696969 },
   314         { "dodgerblue",           0x1e90ff },
   315         { "dodgerblue1",          0x1e90ff },
   316         { "dodgerblue2",          0x1c86ee },
   317         { "dodgerblue3",          0x1874cd },
   318         { "dodgerblue4",          0x104e8b },
   319         { "firebrick",            0xB22222 },
   320         { "firebrick1",           0xFF3030 },
   321         { "firebrick2",           0xEE2C2C },
   322         { "firebrick3",           0xCD2626 },
   323         { "firebrick4",           0x8B1A1A },
   324         { "floralwhite",          0xfffaf0 },
   325         { "forestgreen",          0x228b22 },
   326         { "fractal",              0x808080 },
   327         { "fuchsia",              0xFF00FF },
   328         { "gainsboro",            0xDCDCDC },
   329         { "ghostwhite",           0xf8f8ff },
   330         { "gold",                 0xFFD700 },
   331         { "gold1",                0xFFD700 },
   332         { "gold2",                0xEEC900 },
   333         { "gold3",                0xCDAD00 },
   334         { "gold4",                0x8B7500 },
   335         { "goldenrod",            0xDAA520 },
   336         { "goldenrod1",           0xFFC125 },
   337         { "goldenrod2",           0xEEB422 },
   338         { "goldenrod3",           0xCD9B1D },
   339         { "goldenrod4",           0x8B6914 },
   340         { "gray",                 0x7E7E7E },
   341         { "gray",                 0xBEBEBE },
   342         { "gray0",                0x000000 },
   343         { "gray1",                0x030303 },
   344         { "gray10",               0x1A1A1A },
   345         { "gray100",              0xFFFFFF },
   346         { "gray11",               0x1C1C1C },
   347         { "gray12",               0x1F1F1F },
   348         { "gray13",               0x212121 },
   349         { "gray14",               0x242424 },
   350         { "gray15",               0x262626 },
   351         { "gray16",               0x292929 },
   352         { "gray17",               0x2B2B2B },
   353         { "gray18",               0x2E2E2E },
   354         { "gray19",               0x303030 },
   355         { "gray2",                0x050505 },
   356         { "gray20",               0x333333 },
   357         { "gray21",               0x363636 },
   358         { "gray22",               0x383838 },
   359         { "gray23",               0x3B3B3B },
   360         { "gray24",               0x3D3D3D },
   361         { "gray25",               0x404040 },
   362         { "gray26",               0x424242 },
   363         { "gray27",               0x454545 },
   364         { "gray28",               0x474747 },
   365         { "gray29",               0x4A4A4A },
   366         { "gray3",                0x080808 },
   367         { "gray30",               0x4D4D4D },
   368         { "gray31",               0x4F4F4F },
   369         { "gray32",               0x525252 },
   370         { "gray33",               0x545454 },
   371         { "gray34",               0x575757 },
   372         { "gray35",               0x595959 },
   373         { "gray36",               0x5C5C5C },
   374         { "gray37",               0x5E5E5E },
   375         { "gray38",               0x616161 },
   376         { "gray39",               0x636363 },
   377         { "gray4",                0x0A0A0A },
   378         { "gray40",               0x666666 },
   379         { "gray41",               0x696969 },
   380         { "gray42",               0x6B6B6B },
   381         { "gray43",               0x6E6E6E },
   382         { "gray44",               0x707070 },
   383         { "gray45",               0x737373 },
   384         { "gray46",               0x757575 },
   385         { "gray47",               0x787878 },
   386         { "gray48",               0x7A7A7A },
   387         { "gray49",               0x7D7D7D },
   388         { "gray5",                0x0D0D0D },
   389         { "gray50",               0x7F7F7F },
   390         { "gray51",               0x828282 },
   391         { "gray52",               0x858585 },
   392         { "gray53",               0x878787 },
   393         { "gray54",               0x8A8A8A },
   394         { "gray55",               0x8C8C8C },
   395         { "gray56",               0x8F8F8F },
   396         { "gray57",               0x919191 },
   397         { "gray58",               0x949494 },
   398         { "gray59",               0x969696 },
   399         { "gray6",                0x0F0F0F },
   400         { "gray60",               0x999999 },
   401         { "gray61",               0x9C9C9C },
   402         { "gray62",               0x9E9E9E },
   403         { "gray63",               0xA1A1A1 },
   404         { "gray64",               0xA3A3A3 },
   405         { "gray65",               0xA6A6A6 },
   406         { "gray66",               0xA8A8A8 },
   407         { "gray67",               0xABABAB },
   408         { "gray68",               0xADADAD },
   409         { "gray69",               0xB0B0B0 },
   410         { "gray7",                0x121212 },
   411         { "gray70",               0xB3B3B3 },
   412         { "gray71",               0xB5B5B5 },
   413         { "gray72",               0xB8B8B8 },
   414         { "gray73",               0xBABABA },
   415         { "gray74",               0xBDBDBD },
   416         { "gray75",               0xBFBFBF },
   417         { "gray76",               0xC2C2C2 },
   418         { "gray77",               0xC4C4C4 },
   419         { "gray78",               0xC7C7C7 },
   420         { "gray79",               0xC9C9C9 },
   421         { "gray8",                0x141414 },
   422         { "gray80",               0xCCCCCC },
   423         { "gray81",               0xCFCFCF },
   424         { "gray82",               0xD1D1D1 },
   425         { "gray83",               0xD4D4D4 },
   426         { "gray84",               0xD6D6D6 },
   427         { "gray85",               0xD9D9D9 },
   428         { "gray86",               0xDBDBDB },
   429         { "gray87",               0xDEDEDE },
   430         { "gray88",               0xE0E0E0 },
   431         { "gray89",               0xE3E3E3 },
   432         { "gray9",                0x171717 },
   433         { "gray90",               0xE5E5E5 },
   434         { "gray91",               0xE8E8E8 },
   435         { "gray92",               0xEBEBEB },
   436         { "gray93",               0xEDEDED },
   437         { "gray94",               0xF0F0F0 },
   438         { "gray95",               0xF2F2F2 },
   439         { "gray96",               0xF5F5F5 },
   440         { "gray97",               0xF7F7F7 },
   441         { "gray98",               0xFAFAFA },
   442         { "gray99",               0xFCFCFC },
   443         { "green",                0x008000 },
   444         { "green",                0x00FF00 },
   445         { "green1",               0x00FF00 },
   446         { "green2",               0x00EE00 },
   447         { "green3",               0x00CD00 },
   448         { "green4",               0x008B00 },
   449         { "greenyellow",          0xadff2f },
   450         { "grey",                 0xBEBEBE },
   451         { "grey0",                0x000000 },
   452         { "grey1",                0x030303 },
   453         { "grey10",               0x1A1A1A },
   454         { "grey100",              0xFFFFFF },
   455         { "grey11",               0x1C1C1C },
   456         { "grey12",               0x1F1F1F },
   457         { "grey13",               0x212121 },
   458         { "grey14",               0x242424 },
   459         { "grey15",               0x262626 },
   460         { "grey16",               0x292929 },
   461         { "grey17",               0x2B2B2B },
   462         { "grey18",               0x2E2E2E },
   463         { "grey19",               0x303030 },
   464         { "grey2",                0x050505 },
   465         { "grey20",               0x333333 },
   466         { "grey21",               0x363636 },
   467         { "grey22",               0x383838 },
   468         { "grey23",               0x3B3B3B },
   469         { "grey24",               0x3D3D3D },
   470         { "grey25",               0x404040 },
   471         { "grey26",               0x424242 },
   472         { "grey27",               0x454545 },
   473         { "grey28",               0x474747 },
   474         { "grey29",               0x4A4A4A },
   475         { "grey3",                0x080808 },
   476         { "grey30",               0x4D4D4D },
   477         { "grey31",               0x4F4F4F },
   478         { "grey32",               0x525252 },
   479         { "grey33",               0x545454 },
   480         { "grey34",               0x575757 },
   481         { "grey35",               0x595959 },
   482         { "grey36",               0x5C5C5C },
   483         { "grey37",               0x5E5E5E },
   484         { "grey38",               0x616161 },
   485         { "grey39",               0x636363 },
   486         { "grey4",                0x0A0A0A },
   487         { "grey40",               0x666666 },
   488         { "grey41",               0x696969 },
   489         { "grey42",               0x6B6B6B },
   490         { "grey43",               0x6E6E6E },
   491         { "grey44",               0x707070 },
   492         { "grey45",               0x737373 },
   493         { "grey46",               0x757575 },
   494         { "grey47",               0x787878 },
   495         { "grey48",               0x7A7A7A },
   496         { "grey49",               0x7D7D7D },
   497         { "grey5",                0x0D0D0D },
   498         { "grey50",               0x7F7F7F },
   499         { "grey51",               0x828282 },
   500         { "grey52",               0x858585 },
   501         { "grey53",               0x878787 },
   502         { "grey54",               0x8A8A8A },
   503         { "grey55",               0x8C8C8C },
   504         { "grey56",               0x8F8F8F },
   505         { "grey57",               0x919191 },
   506         { "grey58",               0x949494 },
   507         { "grey59",               0x969696 },
   508         { "grey6",                0x0F0F0F },
   509         { "grey60",               0x999999 },
   510         { "grey61",               0x9C9C9C },
   511         { "grey62",               0x9E9E9E },
   512         { "grey63",               0xA1A1A1 },
   513         { "grey64",               0xA3A3A3 },
   514         { "grey65",               0xA6A6A6 },
   515         { "grey66",               0xA8A8A8 },
   516         { "grey67",               0xABABAB },
   517         { "grey68",               0xADADAD },
   518         { "grey69",               0xB0B0B0 },
   519         { "grey7",                0x121212 },
   520         { "grey70",               0xB3B3B3 },
   521         { "grey71",               0xB5B5B5 },
   522         { "grey72",               0xB8B8B8 },
   523         { "grey73",               0xBABABA },
   524         { "grey74",               0xBDBDBD },
   525         { "grey75",               0xBFBFBF },
   526         { "grey76",               0xC2C2C2 },
   527         { "grey77",               0xC4C4C4 },
   528         { "grey78",               0xC7C7C7 },
   529         { "grey79",               0xC9C9C9 },
   530         { "grey8",                0x141414 },
   531         { "grey80",               0xCCCCCC },
   532         { "grey81",               0xCFCFCF },
   533         { "grey82",               0xD1D1D1 },
   534         { "grey83",               0xD4D4D4 },
   535         { "grey84",               0xD6D6D6 },
   536         { "grey85",               0xD9D9D9 },
   537         { "grey86",               0xDBDBDB },
   538         { "grey87",               0xDEDEDE },
   539         { "grey88",               0xE0E0E0 },
   540         { "grey89",               0xE3E3E3 },
   541         { "grey9",                0x171717 },
   542         { "grey90",               0xE5E5E5 },
   543         { "grey91",               0xE8E8E8 },
   544         { "grey92",               0xEBEBEB },
   545         { "grey93",               0xEDEDED },
   546         { "grey94",               0xF0F0F0 },
   547         { "grey95",               0xF2F2F2 },
   548         { "grey96",               0xF5F5F5 },
   549         { "grey97",               0xF7F7F7 },
   550         { "grey98",               0xFAFAFA },
   551         { "grey99",               0xFCFCFC },
   552         { "honeydew",             0xF0FFF0 },
   553         { "honeydew1",            0xF0FFF0 },
   554         { "honeydew2",            0xE0EEE0 },
   555         { "honeydew3",            0xC1CDC1 },
   556         { "honeydew4",            0x838B83 },
   557         { "hotpink",              0xff69b4 },
   558         { "hotpink1",             0xff6eb4 },
   559         { "hotpink2",             0xee6aa7 },
   560         { "hotpink3",             0xcd6090 },
   561         { "hotpink4",             0x8b3a62 },
   562         { "indianred",            0xcd5c5c },
   563         { "indianred1",           0xff6a6a },
   564         { "indianred2",           0xee6363 },
   565         { "indianred3",           0xcd5555 },
   566         { "indianred4",           0x8b3a3a },
   567         { "indigo",               0x4B0082 },
   568         { "ivory",                0xFFFFF0 },
   569         { "ivory1",               0xFFFFF0 },
   570         { "ivory2",               0xEEEEE0 },
   571         { "ivory3",               0xCDCDC1 },
   572         { "ivory4",               0x8B8B83 },
   573         { "khaki",                0xF0E68C },
   574         { "khaki1",               0xFFF68F },
   575         { "khaki2",               0xEEE685 },
   576         { "khaki3",               0xCDC673 },
   577         { "khaki4",               0x8B864E },
   578         { "lavender",             0xE6E6FA },
   579         { "lavenderblush",        0xfff0f5 },
   580         { "lavenderblush1",       0xfff0f5 },
   581         { "lavenderblush2",       0xeee0e5 },
   582         { "lavenderblush3",       0xcdc1c5 },
   583         { "lavenderblush4",       0x8b8386 },
   584         { "lawngreen",            0x7cfc00 },
   585         { "lemonchiffon",         0xfffacd },
   586         { "lemonchiffon1",        0xfffacd },
   587         { "lemonchiffon2",        0xeee9bf },
   588         { "lemonchiffon3",        0xcdc9a5 },
   589         { "lemonchiffon4",        0x8b8970 },
   590         { "lightblue",            0xadd8e6 },
   591         { "lightblue1",           0xbfefff },
   592         { "lightblue2",           0xb2dfee },
   593         { "lightblue3",           0x9ac0cd },
   594         { "lightblue4",           0x68838b },
   595         { "lightcoral",           0xf08080 },
   596         { "lightcyan",            0xe0ffff },
   597         { "lightcyan1",           0xe0ffff },
   598         { "lightcyan2",           0xd1eeee },
   599         { "lightcyan3",           0xb4cdcd },
   600         { "lightcyan4",           0x7a8b8b },
   601         { "lightgoldenrod",       0xeedd82 },
   602         { "lightgoldenrod1",      0xffec8b },
   603         { "lightgoldenrod2",      0xeedc82 },
   604         { "lightgoldenrod3",      0xcdbe70 },
   605         { "lightgoldenrod4",      0x8b814c },
   606         { "lightgoldenrodyellow", 0xfafad2 },
   607         { "lightgray",            0xd3d3d3 },
   608         { "lightgreen",           0x90ee90 },
   609         { "lightgrey",            0xd3d3d3 },
   610         { "lightpink",            0xffb6c1 },
   611         { "lightpink1",           0xffaeb9 },
   612         { "lightpink2",           0xeea2ad },
   613         { "lightpink3",           0xcd8c95 },
   614         { "lightpink4",           0x8b5f65 },
   615         { "lightsalmon",          0xffa07a },
   616         { "lightsalmon1",         0xffa07a },
   617         { "lightsalmon2",         0xee9572 },
   618         { "lightsalmon3",         0xcd8162 },
   619         { "lightsalmon4",         0x8b5742 },
   620         { "lightseagreen",        0x20b2aa },
   621         { "lightskyblue",         0x87cefa },
   622         { "lightskyblue1",        0xb0e2ff },
   623         { "lightskyblue2",        0xa4d3ee },
   624         { "lightskyblue3",        0x8db6cd },
   625         { "lightskyblue4",        0x607b8b },
   626         { "lightslateblue",       0x8470ff },
   627         { "lightslategray",       0x778899 },
   628         { "lightslategrey",       0x778899 },
   629         { "lightsteelblue",       0xb0c4de },
   630         { "lightsteelblue1",      0xcae1ff },
   631         { "lightsteelblue2",      0xbcd2ee },
   632         { "lightsteelblue3",      0xa2b5cd },
   633         { "lightsteelblue4",      0x6e7b8b },
   634         { "lightyellow",          0xffffe0 },
   635         { "lightyellow1",         0xffffe0 },
   636         { "lightyellow2",         0xeeeed1 },
   637         { "lightyellow3",         0xcdcdb4 },
   638         { "lightyellow4",         0x8b8b7a },
   639         { "lime",                 0x00FF00 },
   640         { "limegreen",            0x32cd32 },
   641         { "linen",                0xFAF0E6 },
   642         { "magenta",              0xFF00FF },
   643         { "magenta1",             0xFF00FF },
   644         { "magenta2",             0xEE00EE },
   645         { "magenta3",             0xCD00CD },
   646         { "magenta4",             0x8B008B },
   647         { "maroon",               0x800000 },
   648         { "maroon",               0xB03060 },
   649         { "maroon1",              0xFF34B3 },
   650         { "maroon2",              0xEE30A7 },
   651         { "maroon3",              0xCD2990 },
   652         { "maroon4",              0x8B1C62 },
   653         { "mediumaquamarine",     0x66cdaa },
   654         { "mediumblue",           0x0000cd },
   655         { "mediumforestgreen",    0x32814b },
   656         { "mediumgoldenrod",      0xd1c166 },
   657         { "mediumorchid",         0xba55d3 },
   658         { "mediumorchid1",        0xe066ff },
   659         { "mediumorchid2",        0xd15fee },
   660         { "mediumorchid3",        0xb452cd },
   661         { "mediumorchid4",        0x7a378b },
   662         { "mediumpurple",         0x9370db },
   663         { "mediumpurple1",        0xab82ff },
   664         { "mediumpurple2",        0x9f79ee },
   665         { "mediumpurple3",        0x8968cd },
   666         { "mediumpurple4",        0x5d478b },
   667         { "mediumseagreen",       0x3cb371 },
   668         { "mediumslateblue",      0x7b68ee },
   669         { "mediumspringgreen",    0x00fa9a },
   670         { "mediumturquoise",      0x48d1cc },
   671         { "mediumvioletred",      0xc71585 },
   672         { "midnightblue",         0x191970 },
   673         { "mintcream",            0xf5fffa },
   674         { "mistyrose",            0xffe4e1 },
   675         { "mistyrose1",           0xffe4e1 },
   676         { "mistyrose2",           0xeed5d2 },
   677         { "mistyrose3",           0xcdb7b5 },
   678         { "mistyrose4",           0x8b7d7b },
   679         { "moccasin",             0xFFE4B5 },
   680         { "navajowhite",          0xffdead },
   681         { "navajowhite1",         0xffdead },
   682         { "navajowhite2",         0xeecfa1 },
   683         { "navajowhite3",         0xcdb38b },
   684         { "navajowhite4",         0x8b795e },
   685         { "navy",                 0x000080 },
   686         { "navyblue",             0x000080 },
   687         { "none",                 0x0000FF },
   688         { "oldlace",              0xfdf5e6 },
   689         { "olive",                0x808000 },
   690         { "olivedrab",            0x6b8e23 },
   691         { "olivedrab1",           0xc0ff3e },
   692         { "olivedrab2",           0xb3ee3a },
   693         { "olivedrab3",           0x9acd32 },
   694         { "olivedrab4",           0x698b22 },
   695         { "opaque",               0x000000 },
   696         { "orange",               0xFFA500 },
   697         { "orange1",              0xFFA500 },
   698         { "orange2",              0xEE9A00 },
   699         { "orange3",              0xCD8500 },
   700         { "orange4",              0x8B5A00 },
   701         { "orangered",            0xff4500 },
   702         { "orangered1",           0xff4500 },
   703         { "orangered2",           0xee4000 },
   704         { "orangered3",           0xcd3700 },
   705         { "orangered4",           0x8b2500 },
   706         { "orchid",               0xDA70D6 },
   707         { "orchid1",              0xFF83FA },
   708         { "orchid2",              0xEE7AE9 },
   709         { "orchid3",              0xCD69C9 },
   710         { "orchid4",              0x8B4789 },
   711         { "palegoldenrod",        0xeee8aa },
   712         { "palegreen",            0x98fb98 },
   713         { "palegreen1",           0x9aff9a },
   714         { "palegreen2",           0x90ee90 },
   715         { "palegreen3",           0x7ccd7c },
   716         { "palegreen4",           0x548b54 },
   717         { "paleturquoise",        0xafeeee },
   718         { "paleturquoise1",       0xbbffff },
   719         { "paleturquoise2",       0xaeeeee },
   720         { "paleturquoise3",       0x96cdcd },
   721         { "paleturquoise4",       0x668b8b },
   722         { "palevioletred",        0xdb7093 },
   723         { "palevioletred1",       0xff82ab },
   724         { "palevioletred2",       0xee799f },
   725         { "palevioletred3",       0xcd6889 },
   726         { "palevioletred4",       0x8b475d },
   727         { "papayawhip",           0xffefd5 },
   728         { "peachpuff",            0xffdab9 },
   729         { "peachpuff1",           0xffdab9 },
   730         { "peachpuff2",           0xeecbad },
   731         { "peachpuff3",           0xcdaf95 },
   732         { "peachpuff4",           0x8b7765 },
   733         { "peru",                 0xCD853F },
   734         { "pink",                 0xFFC0CB },
   735         { "pink1",                0xFFB5C5 },
   736         { "pink2",                0xEEA9B8 },
   737         { "pink3",                0xCD919E },
   738         { "pink4",                0x8B636C },
   739         { "plum",                 0xDDA0DD },
   740         { "plum1",                0xFFBBFF },
   741         { "plum2",                0xEEAEEE },
   742         { "plum3",                0xCD96CD },
   743         { "plum4",                0x8B668B },
   744         { "powderblue",           0xb0e0e6 },
   745         { "purple",               0x800080 },
   746         { "purple",               0xA020F0 },
   747         { "purple1",              0x9B30FF },
   748         { "purple2",              0x912CEE },
   749         { "purple3",              0x7D26CD },
   750         { "purple4",              0x551A8B },
   751         { "red",                  0xFF0000 },
   752         { "red1",                 0xFF0000 },
   753         { "red2",                 0xEE0000 },
   754         { "red3",                 0xCD0000 },
   755         { "red4",                 0x8B0000 },
   756         { "rosybrown",            0xbc8f8f },
   757         { "rosybrown1",           0xffc1c1 },
   758         { "rosybrown2",           0xeeb4b4 },
   759         { "rosybrown3",           0xcd9b9b },
   760         { "rosybrown4",           0x8b6969 },
   761         { "royalblue",            0x4169e1 },
   762         { "royalblue1",           0x4876ff },
   763         { "royalblue2",           0x436eee },
   764         { "royalblue3",           0x3a5fcd },
   765         { "royalblue4",           0x27408b },
   766         { "saddlebrown",          0x8b4513 },
   767         { "salmon",               0xFA8072 },
   768         { "salmon1",              0xFF8C69 },
   769         { "salmon2",              0xEE8262 },
   770         { "salmon3",              0xCD7054 },
   771         { "salmon4",              0x8B4C39 },
   772         { "sandybrown",           0xf4a460 },
   773         { "seagreen",             0x2e8b57 },
   774         { "seagreen1",            0x54ff9f },
   775         { "seagreen2",            0x4eee94 },
   776         { "seagreen3",            0x43cd80 },
   777         { "seagreen4",            0x2e8b57 },
   778         { "seashell",             0xFFF5EE },
   779         { "seashell1",            0xFFF5EE },
   780         { "seashell2",            0xEEE5DE },
   781         { "seashell3",            0xCDC5BF },
   782         { "seashell4",            0x8B8682 },
   783         { "sienna",               0xA0522D },
   784         { "sienna1",              0xFF8247 },
   785         { "sienna2",              0xEE7942 },
   786         { "sienna3",              0xCD6839 },
   787         { "sienna4",              0x8B4726 },
   788         { "silver",               0xC0C0C0 },
   789         { "skyblue",              0x87ceeb },
   790         { "skyblue1",             0x87ceff },
   791         { "skyblue2",             0x7ec0ee },
   792         { "skyblue3",             0x6ca6cd },
   793         { "skyblue4",             0x4a708b },
   794         { "slateblue",            0x6a5acd },
   795         { "slateblue1",           0x836fff },
   796         { "slateblue2",           0x7a67ee },
   797         { "slateblue3",           0x6959cd },
   798         { "slateblue4",           0x473c8b },
   799         { "slategray",            0x708090 },
   800         { "slategray1",           0xc6e2ff },
   801         { "slategray2",           0xb9d3ee },
   802         { "slategray3",           0x9fb6cd },
   803         { "slategray4",           0x6c7b8b },
   804         { "slategrey",            0x708090 },
   805         { "snow",                 0xFFFAFA },
   806         { "snow1",                0xFFFAFA },
   807         { "snow2",                0xEEE9E9 },
   808         { "snow3",                0xCDC9C9 },
   809         { "snow4",                0x8B8989 },
   810         { "springgreen",          0x00ff7f },
   811         { "springgreen1",         0x00ff7f },
   812         { "springgreen2",         0x00ee76 },
   813         { "springgreen3",         0x00cd66 },
   814         { "springgreen4",         0x008b45 },
   815         { "steelblue",            0x4682b4 },
   816         { "steelblue1",           0x63b8ff },
   817         { "steelblue2",           0x5cacee },
   818         { "steelblue3",           0x4f94cd },
   819         { "steelblue4",           0x36648b },
   820         { "tan",                  0xD2B48C },
   821         { "tan1",                 0xFFA54F },
   822         { "tan2",                 0xEE9A49 },
   823         { "tan3",                 0xCD853F },
   824         { "tan4",                 0x8B5A2B },
   825         { "teal",                 0x008080 },
   826         { "thistle",              0xD8BFD8 },
   827         { "thistle1",             0xFFE1FF },
   828         { "thistle2",             0xEED2EE },
   829         { "thistle3",             0xCDB5CD },
   830         { "thistle4",             0x8B7B8B },
   831         { "tomato",               0xFF6347 },
   832         { "tomato1",              0xFF6347 },
   833         { "tomato2",              0xEE5C42 },
   834         { "tomato3",              0xCD4F39 },
   835         { "tomato4",              0x8B3626 },
   836         { "transparent",          0x0000FF },
   837         { "turquoise",            0x40E0D0 },
   838         { "turquoise1",           0x00F5FF },
   839         { "turquoise2",           0x00E5EE },
   840         { "turquoise3",           0x00C5CD },
   841         { "turquoise4",           0x00868B },
   842         { "violet",               0xEE82EE },
   843         { "violetred",            0xd02090 },
   844         { "violetred1",           0xff3e96 },
   845         { "violetred2",           0xee3a8c },
   846         { "violetred3",           0xcd3278 },
   847         { "violetred4",           0x8b2252 },
   848         { "wheat",                0xF5DEB3 },
   849         { "wheat1",               0xFFE7BA },
   850         { "wheat2",               0xEED8AE },
   851         { "wheat3",               0xCDBA96 },
   852         { "wheat4",               0x8B7E66 },
   853         { "white",                0xFFFFFF },
   854         { "whitesmoke",           0xf5f5f5 },
   855         { "yellow",               0xFFFF00 },
   856         { "yellow1",              0xFFFF00 },
   857         { "yellow2",              0xEEEE00 },
   858         { "yellow3",              0xCDCD00 },
   859         { "yellow4",              0x8B8B00 },
   860         { "yellowgreen",          0x9acd32 },
   861 #endif /* EXTENDED_XPM_COLORS */
   862         {"none",                  0xFFFFFF}
   863     };
   864 
   865     if (spec[0] == '#') {
   866         char buf[7];
   867         switch(speclen) {
   868         case 4:
   869             buf[0] = buf[1] = spec[1];
   870             buf[2] = buf[3] = spec[2];
   871             buf[4] = buf[5] = spec[3];
   872             break;
   873         case 7:
   874             SDL_memcpy(buf, spec + 1, 6);
   875             break;
   876         case 13:
   877             buf[0] = spec[1];
   878             buf[1] = spec[2];
   879             buf[2] = spec[5];
   880             buf[3] = spec[6];
   881             buf[4] = spec[9];
   882             buf[5] = spec[10];
   883             break;
   884         }
   885         buf[6] = '\0';
   886         *rgb = (Uint32)SDL_strtol(buf, NULL, 16);
   887         return 1;
   888     } else {
   889         int i;
   890         for (i = 0; i < SDL_arraysize(known); i++) {
   891             if (SDL_strncasecmp(known[i].name, spec, speclen) == 0) {
   892                 *rgb = known[i].rgb;
   893                 return 1;
   894             }
   895         }
   896         return 0;
   897     }
   898 }
   899 
   900 #ifndef MAX
   901 #define MAX(a, b) ((a) > (b) ? (a) : (b))
   902 #endif
   903 
   904 static char *linebuf;
   905 static int buflen;
   906 static char *error;
   907 
   908 /*
   909  * Read next line from the source.
   910  * If len > 0, it's assumed to be at least len chars (for efficiency).
   911  * Return NULL and set error upon EOF or parse error.
   912  */
   913 static char *get_next_line(char ***lines, SDL_RWops *src, int len)
   914 {
   915     char *linebufnew;
   916 
   917     if (lines) {
   918         return *(*lines)++;
   919     } else {
   920         char c;
   921         int n;
   922         do {
   923             if (SDL_RWread(src, &c, 1, 1) <= 0) {
   924                 error = "Premature end of data";
   925                 return NULL;
   926             }
   927         } while (c != '"');
   928         if (len) {
   929             len += 4;   /* "\",\n\0" */
   930             if (len > buflen){
   931                 buflen = len;
   932                 linebufnew = (char *)SDL_realloc(linebuf, buflen);
   933                 if (!linebufnew) {
   934                     SDL_free(linebuf);
   935                     error = "Out of memory";
   936                     return NULL;
   937                 }
   938                 linebuf = linebufnew;
   939             }
   940             if (SDL_RWread(src, linebuf, len - 1, 1) <= 0) {
   941                 error = "Premature end of data";
   942                 return NULL;
   943             }
   944             n = len - 2;
   945         } else {
   946             n = 0;
   947             do {
   948                 if (n >= buflen - 1) {
   949                     if (buflen == 0)
   950                         buflen = 16;
   951                     buflen *= 2;
   952                     linebufnew = (char *)SDL_realloc(linebuf, buflen);
   953                     if (!linebufnew) {
   954                         SDL_free(linebuf);
   955                         error = "Out of memory";
   956                         return NULL;
   957                     }
   958                     linebuf = linebufnew;
   959                 }
   960                 if (SDL_RWread(src, linebuf + n, 1, 1) <= 0) {
   961                     error = "Premature end of data";
   962                     return NULL;
   963                 }
   964             } while (linebuf[n++] != '"');
   965             n--;
   966         }
   967         linebuf[n] = '\0';
   968         return linebuf;
   969     }
   970 }
   971 
   972 #define SKIPSPACE(p)                \
   973 do {                        \
   974     while (SDL_isspace((unsigned char)*(p))) \
   975           ++(p);                \
   976 } while (0)
   977 
   978 #define SKIPNONSPACE(p)                 \
   979 do {                            \
   980     while (!SDL_isspace((unsigned char)*(p)) && *p)  \
   981           ++(p);                    \
   982 } while (0)
   983 
   984 /* read XPM from either array or RWops */
   985 static SDL_Surface *load_xpm(char **xpm, SDL_RWops *src)
   986 {
   987     Sint64 start = 0;
   988     SDL_Surface *image = NULL;
   989     int index;
   990     int x, y;
   991     int w, h, ncolors, cpp;
   992     int indexed;
   993     Uint8 *dst;
   994     struct color_hash *colors = NULL;
   995     SDL_Color *im_colors = NULL;
   996     char *keystrings = NULL, *nextkey;
   997     char *line;
   998     char ***xpmlines = NULL;
   999     int pixels_len;
  1000 
  1001     error = NULL;
  1002     linebuf = NULL;
  1003     buflen = 0;
  1004 
  1005     if (src)
  1006         start = SDL_RWtell(src);
  1007 
  1008     if (xpm)
  1009         xpmlines = &xpm;
  1010 
  1011     line = get_next_line(xpmlines, src, 0);
  1012     if (!line)
  1013         goto done;
  1014     /*
  1015      * The header string of an XPMv3 image has the format
  1016      *
  1017      * <width> <height> <ncolors> <cpp> [ <hotspot_x> <hotspot_y> ]
  1018      *
  1019      * where the hotspot coords are intended for mouse cursors.
  1020      * Right now we don't use the hotspots but it should be handled
  1021      * one day.
  1022      */
  1023     if (SDL_sscanf(line, "%d %d %d %d", &w, &h, &ncolors, &cpp) != 4
  1024        || w <= 0 || h <= 0 || ncolors <= 0 || cpp <= 0) {
  1025         error = "Invalid format description";
  1026         goto done;
  1027     }
  1028 
  1029     keystrings = (char *)SDL_malloc(ncolors * cpp);
  1030     if (!keystrings) {
  1031         error = "Out of memory";
  1032         goto done;
  1033     }
  1034     nextkey = keystrings;
  1035 
  1036     /* Create the new surface */
  1037     if (ncolors <= 256) {
  1038         indexed = 1;
  1039         image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8,
  1040                          0, 0, 0, 0);
  1041         im_colors = image->format->palette->colors;
  1042         image->format->palette->ncolors = ncolors;
  1043     } else {
  1044         indexed = 0;
  1045         image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
  1046                          0xff0000, 0x00ff00, 0x0000ff, 0);
  1047     }
  1048     if (!image) {
  1049         /* Hmm, some SDL error (out of memory?) */
  1050         goto done;
  1051     }
  1052 
  1053     /* Read the colors */
  1054     colors = create_colorhash(ncolors);
  1055     if (!colors) {
  1056         error = "Out of memory";
  1057         goto done;
  1058     }
  1059     for (index = 0; index < ncolors; ++index ) {
  1060         char *p;
  1061         line = get_next_line(xpmlines, src, 0);
  1062         if (!line)
  1063             goto done;
  1064 
  1065         p = line + cpp + 1;
  1066 
  1067         /* parse a colour definition */
  1068         for (;;) {
  1069             char nametype;
  1070             char *colname;
  1071             Uint32 rgb, pixel;
  1072 
  1073             SKIPSPACE(p);
  1074             if (!*p) {
  1075                 error = "colour parse error";
  1076                 goto done;
  1077             }
  1078             nametype = *p;
  1079             SKIPNONSPACE(p);
  1080             SKIPSPACE(p);
  1081             colname = p;
  1082             SKIPNONSPACE(p);
  1083             if (nametype == 's')
  1084                 continue;      /* skip symbolic colour names */
  1085 
  1086             if (!color_to_rgb(colname, (int)(p - colname), &rgb))
  1087                 continue;
  1088 
  1089             SDL_memcpy(nextkey, line, cpp);
  1090             if (indexed) {
  1091                 SDL_Color *c = im_colors + index;
  1092                 c->r = (Uint8)(rgb >> 16);
  1093                 c->g = (Uint8)(rgb >> 8);
  1094                 c->b = (Uint8)(rgb);
  1095                 pixel = index;
  1096             } else
  1097                 pixel = rgb;
  1098             add_colorhash(colors, nextkey, cpp, pixel);
  1099             nextkey += cpp;
  1100             if (rgb == 0xffffffff)
  1101                 SDL_SetColorKey(image, SDL_TRUE, pixel);
  1102             break;
  1103         }
  1104     }
  1105 
  1106     /* Read the pixels */
  1107     pixels_len = w * cpp;
  1108     dst = (Uint8 *)image->pixels;
  1109     for (y = 0; y < h; y++) {
  1110         line = get_next_line(xpmlines, src, pixels_len);
  1111         if (!line)
  1112             goto done;
  1113 
  1114         if (indexed) {
  1115             /* optimization for some common cases */
  1116             if (cpp == 1)
  1117                 for (x = 0; x < w; x++)
  1118                     dst[x] = (Uint8)QUICK_COLORHASH(colors,
  1119                                  line + x);
  1120             else
  1121                 for (x = 0; x < w; x++)
  1122                     dst[x] = (Uint8)get_colorhash(colors,
  1123                                    line + x * cpp,
  1124                                    cpp);
  1125         } else {
  1126             for (x = 0; x < w; x++)
  1127                 ((Uint32*)dst)[x] = get_colorhash(colors,
  1128                                 line + x * cpp,
  1129                                   cpp);
  1130         }
  1131         dst += image->pitch;
  1132     }
  1133 
  1134 done:
  1135     if (error) {
  1136         if ( src )
  1137             SDL_RWseek(src, start, RW_SEEK_SET);
  1138         if ( image ) {
  1139             SDL_FreeSurface(image);
  1140             image = NULL;
  1141         }
  1142         IMG_SetError("%s", error);
  1143     }
  1144     if (keystrings)
  1145         SDL_free(keystrings);
  1146     free_colorhash(colors);
  1147     if (linebuf)
  1148         SDL_free(linebuf);
  1149     return(image);
  1150 }
  1151 
  1152 /* Load a XPM type image from an RWops datasource */
  1153 SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src)
  1154 {
  1155     if ( !src ) {
  1156         /* The error message has been set in SDL_RWFromFile */
  1157         return NULL;
  1158     }
  1159     return load_xpm(NULL, src);
  1160 }
  1161 
  1162 SDL_Surface *IMG_ReadXPMFromArray(char **xpm)
  1163 {
  1164     if (!xpm) {
  1165         IMG_SetError("array is NULL");
  1166         return NULL;
  1167     }
  1168     return load_xpm(xpm, NULL);
  1169 }
  1170 
  1171 #else  /* not LOAD_XPM */
  1172 
  1173 /* See if an image is contained in a data source */
  1174 int IMG_isXPM(SDL_RWops *src)
  1175 {
  1176     return(0);
  1177 }
  1178 
  1179 
  1180 /* Load a XPM type image from an SDL datasource */
  1181 SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src)
  1182 {
  1183     return(NULL);
  1184 }
  1185 
  1186 SDL_Surface *IMG_ReadXPMFromArray(char **xpm)
  1187 {
  1188     return NULL;
  1189 }
  1190 #endif /* not LOAD_XPM */