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