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