1.1.0:
authorSam Lantinga <slouken@lokigames.com>
Wed, 29 Nov 2000 11:55:32 +0000
changeset 7e1b6443ffb6b
parent 6 0f9c50ca2592
child 8 f39c13a577e8
1.1.0:
Sam Lantinga - Wed Nov 29 00:46:27 PST 2000
* Added XPM file format support
Supports color, greyscale, and mono XPMs with and without transparency
Mattias Engdeg�rd - Thu, 2 Nov 2000 23:23:17 +0100 (MET)
* Fixed array overrun when loading an unsupported format
* Minor compilation fixes for various platforms
CHANGES
IMG.c
IMG_gif.c
IMG_jpg.c
IMG_pcx.c
IMG_png.c
IMG_ppm.c
IMG_xpm.c
Makefile.am
SDL_image.h
configure.in
showimage.c
     1.1 --- a/CHANGES	Fri Nov 17 21:42:53 2000 +0000
     1.2 +++ b/CHANGES	Wed Nov 29 11:55:32 2000 +0000
     1.3 @@ -1,3 +1,11 @@
     1.4 +
     1.5 +1.1.0:
     1.6 +Sam Lantinga - Wed Nov 29 00:46:27 PST 2000
     1.7 + * Added XPM file format support
     1.8 +   Supports color, greyscale, and mono XPMs with and without transparency
     1.9 +Mattias Engdegård - Thu, 2 Nov 2000 23:23:17 +0100 (MET)
    1.10 + * Fixed array overrun when loading an unsupported format
    1.11 + * Minor compilation fixes for various platforms
    1.12  
    1.13  1.0.10:
    1.14  Mattias Engdegård - Wed Aug  9 20:32:22 MET DST 2000
     2.1 --- a/IMG.c	Fri Nov 17 21:42:53 2000 +0000
     2.2 +++ b/IMG.c	Wed Nov 29 11:55:32 2000 +0000
     2.3 @@ -30,6 +30,8 @@
     2.4  
     2.5  #include "SDL_image.h"
     2.6  
     2.7 +#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
     2.8 +
     2.9  /* Table of image detection and loading functions */
    2.10  static struct {
    2.11  	char *type;
    2.12 @@ -40,11 +42,12 @@
    2.13  	{ "TGA", NULL,      IMG_LoadTGA_RW },
    2.14  	{ "BMP", IMG_isBMP, IMG_LoadBMP_RW },
    2.15  	{ "PPM", IMG_isPPM, IMG_LoadPPM_RW },
    2.16 +	{ "XPM", IMG_isXPM, IMG_LoadXPM_RW },
    2.17  	{ "PCX", IMG_isPCX, IMG_LoadPCX_RW },
    2.18  	{ "GIF", IMG_isGIF, IMG_LoadGIF_RW },
    2.19  	{ "JPG", IMG_isJPG, IMG_LoadJPG_RW },
    2.20  	{ "TIF", IMG_isTIF, IMG_LoadTIF_RW },
    2.21 -	{ "PNG", IMG_isPNG, IMG_LoadPNG_RW },
    2.22 +	{ "PNG", IMG_isPNG, IMG_LoadPNG_RW }
    2.23  };
    2.24  
    2.25  /* Load an image from a file */
    2.26 @@ -96,7 +99,7 @@
    2.27  	/* Detect the type of image being loaded */
    2.28  	start = SDL_RWtell(src);
    2.29  	image = NULL;
    2.30 -	for ( i=0; supported[i].type && !image; ++i ) {
    2.31 +	for ( i=0; i < ARRAYSIZE(supported) && !image; ++i ) {
    2.32  	        if( (supported[i].is
    2.33  		     && (SDL_RWseek(src, start, SEEK_SET),
    2.34  			 supported[i].is(src)))
     3.1 --- a/IMG_gif.c	Fri Nov 17 21:42:53 2000 +0000
     3.2 +++ b/IMG_gif.c	Wed Nov 29 11:55:32 2000 +0000
     3.3 @@ -254,7 +254,7 @@
     3.4  
     3.5  #ifdef USED_BY_SDL
     3.6      if ( Gif89.transparent > 0 ) {
     3.7 -        SDL_SetColorKey(image, SDL_SRCCOLORKEY, Gif89. transparent);
     3.8 +        SDL_SetColorKey(image, SDL_SRCCOLORKEY, Gif89.transparent);
     3.9      }
    3.10  #endif
    3.11  
     4.1 --- a/IMG_jpg.c	Fri Nov 17 21:42:53 2000 +0000
     4.2 +++ b/IMG_jpg.c	Wed Nov 29 11:55:32 2000 +0000
     4.3 @@ -25,6 +25,7 @@
     4.4  /* This is a JPEG image file loading framework */
     4.5  
     4.6  #include <stdio.h>
     4.7 +#include <string.h>
     4.8  
     4.9  #include "SDL_image.h"
    4.10  
     5.1 --- a/IMG_pcx.c	Fri Nov 17 21:42:53 2000 +0000
     5.2 +++ b/IMG_pcx.c	Wed Nov 29 11:55:32 2000 +0000
     5.3 @@ -113,7 +113,6 @@
     5.4  			Gmask = 0x0000FF00;
     5.5  			Bmask = 0x00FF0000;
     5.6  		} else {
     5.7 -		        int s = (pcxh.NPlanes == 4) ? 0 : 8;
     5.8  			Rmask = 0xFF0000;
     5.9  			Gmask = 0x00FF00;
    5.10  			Bmask = 0x0000FF;
     6.1 --- a/IMG_png.c	Fri Nov 17 21:42:53 2000 +0000
     6.2 +++ b/IMG_png.c	Wed Nov 29 11:55:32 2000 +0000
     6.3 @@ -93,7 +93,7 @@
     6.4  }
     6.5  SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
     6.6  {
     6.7 -	SDL_Surface *surface;
     6.8 +	SDL_Surface *volatile surface;
     6.9  	png_structp png_ptr;
    6.10  	png_infop info_ptr;
    6.11  	png_uint_32 width, height;
    6.12 @@ -103,9 +103,9 @@
    6.13  	Uint32 Bmask;
    6.14  	Uint32 Amask;
    6.15  	SDL_Palette *palette;
    6.16 -	png_bytep *row_pointers;
    6.17 +	png_bytep *volatile row_pointers;
    6.18  	int row, i;
    6.19 -	int ckey = -1;
    6.20 +	volatile int ckey = -1;
    6.21  	png_color_16 *transv;
    6.22  
    6.23  	/* Initialize the data we will clean up when we're done */
     7.1 --- a/IMG_ppm.c	Fri Nov 17 21:42:53 2000 +0000
     7.2 +++ b/IMG_ppm.c	Wed Nov 29 11:55:32 2000 +0000
     7.3 @@ -88,6 +88,7 @@
     7.4  
     7.5  	return(number);
     7.6  }
     7.7 +
     7.8  SDL_Surface *IMG_LoadPPM_RW(SDL_RWops *src)
     7.9  {
    7.10  	SDL_Surface *surface;
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/IMG_xpm.c	Wed Nov 29 11:55:32 2000 +0000
     8.3 @@ -0,0 +1,470 @@
     8.4 +/*
     8.5 +    IMGLIB:  An example image loading library for use with SDL
     8.6 +    Copyright (C) 1999  Sam Lantinga
     8.7 +
     8.8 +    This library is free software; you can redistribute it and/or
     8.9 +    modify it under the terms of the GNU Library General Public
    8.10 +    License as published by the Free Software Foundation; either
    8.11 +    version 2 of the License, or (at your option) any later version.
    8.12 +
    8.13 +    This library is distributed in the hope that it will be useful,
    8.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.16 +    Library General Public License for more details.
    8.17 +
    8.18 +    You should have received a copy of the GNU Library General Public
    8.19 +    License along with this library; if not, write to the Free
    8.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.21 +
    8.22 +    Sam Lantinga
    8.23 +    5635-34 Springhouse Dr.
    8.24 +    Pleasanton, CA 94588 (USA)
    8.25 +    slouken@devolution.com
    8.26 +*/
    8.27 +
    8.28 +/* This is an XPM image file loading framework */
    8.29 +
    8.30 +#include <stdio.h>
    8.31 +#include <string.h>
    8.32 +#include <ctype.h>
    8.33 +
    8.34 +#include "SDL_image.h"
    8.35 +
    8.36 +#ifdef LOAD_XPM
    8.37 +
    8.38 +/* See if an image is contained in a data source */
    8.39 +int IMG_isXPM(SDL_RWops *src)
    8.40 +{
    8.41 +	int is_XPM;
    8.42 +	char magic[10];
    8.43 +
    8.44 +	is_XPM = 0;
    8.45 +	if ( SDL_RWread(src, magic, sizeof(magic), 1) ) {
    8.46 +		if ( strncmp(magic, "/* XPM */", 9) == 0 ) {
    8.47 +			is_XPM = 1;
    8.48 +		}
    8.49 +	}
    8.50 +	return(is_XPM);
    8.51 +}
    8.52 +
    8.53 +static char *SDL_RWgets(char *string, int maxlen, SDL_RWops *src)
    8.54 +{
    8.55 +	int i;
    8.56 +
    8.57 +	for ( i=0; i<(maxlen-1); ++i ) {
    8.58 +		if ( SDL_RWread(src, &string[i], 1, 1) <= 0 ) {
    8.59 +			/* EOF or error */
    8.60 +			if ( i == 0 ) {
    8.61 +				/* Hmm, EOF on initial read, return NULL */
    8.62 +				string = NULL;
    8.63 +			}
    8.64 +			break;
    8.65 +		}
    8.66 +		/* In this case it's okay to use either '\r' or '\n'
    8.67 +		   as line separators because blank lines are just
    8.68 +		   ignored by the XPM format.
    8.69 +		*/
    8.70 +		if ( (string[i] == '\n') || (string[i] == '\n') ) {
    8.71 +			break;
    8.72 +		}
    8.73 +	}
    8.74 +	if ( string ) {
    8.75 +		string[i] = '\0';
    8.76 +	}
    8.77 +	return(string);
    8.78 +}
    8.79 +
    8.80 +/* Hash table to look up colors from pixel strings */
    8.81 +#define HASH_SIZE	256
    8.82 +struct color_hash {
    8.83 +	struct hash_entry {
    8.84 +		int keylen;
    8.85 +		char *key;
    8.86 +		Uint32 color;
    8.87 +		struct hash_entry *next;
    8.88 +	} *entries[HASH_SIZE];
    8.89 +};
    8.90 +
    8.91 +static int hash_key(const char *key, int cpp)
    8.92 +{
    8.93 +	int hash;
    8.94 +
    8.95 +	hash = 0;
    8.96 +	while ( cpp-- > 0 ) {
    8.97 +		hash += *key++;
    8.98 +	}
    8.99 +	return(hash%HASH_SIZE);
   8.100 +}
   8.101 +
   8.102 +static struct color_hash *create_colorhash(void)
   8.103 +{
   8.104 +	struct color_hash *hash;
   8.105 +
   8.106 +	hash = (struct color_hash *)malloc(sizeof *hash);
   8.107 +	if ( hash ) {
   8.108 +		memset(hash, 0, (sizeof *hash));
   8.109 +	}
   8.110 +	return(hash);
   8.111 +}
   8.112 +
   8.113 +static int add_colorhash(struct color_hash *hash,
   8.114 +                         const char *key, int cpp, Uint32 color)
   8.115 +{
   8.116 +	int hash_index;
   8.117 +	struct hash_entry *prev, *entry;
   8.118 +
   8.119 +	/* Create the hash entry */
   8.120 +	entry = (struct hash_entry *)malloc(sizeof *entry);
   8.121 +	if ( ! entry ) {
   8.122 +		return(0);
   8.123 +	}
   8.124 +	entry->keylen = cpp;
   8.125 +	entry->key = strdup(key);
   8.126 +	if ( ! entry->key ) {
   8.127 +		free(entry);
   8.128 +		return(0);
   8.129 +	}
   8.130 +	entry->color = color;
   8.131 +	entry->next = NULL;
   8.132 +
   8.133 +	/* Add it to the hash table */
   8.134 +	hash_index = hash_key(key, cpp);
   8.135 +	for ( prev = hash->entries[hash_index];
   8.136 +	      prev && prev->next; prev = prev->next ) {
   8.137 +		/* Go to the end of the list */ ;
   8.138 +	}
   8.139 +	if ( prev ) {
   8.140 +		prev->next = entry;
   8.141 +	} else {
   8.142 +		hash->entries[hash_index] = entry;
   8.143 +	}
   8.144 +	return(1);
   8.145 +}
   8.146 +
   8.147 +static int get_colorhash(struct color_hash *hash,
   8.148 +                         const char *key, int cpp, Uint32 *color)
   8.149 +{
   8.150 +	int hash_index;
   8.151 +	struct hash_entry *entry;
   8.152 +
   8.153 +	hash_index = hash_key(key, cpp);
   8.154 +	for ( entry = hash->entries[hash_index]; entry; entry = entry->next ) {
   8.155 +		if ( strncmp(key, entry->key, entry->keylen) == 0 ) {
   8.156 +			*color = entry->color;
   8.157 +			return(1);
   8.158 +		}
   8.159 +	}
   8.160 +	return(0);
   8.161 +}
   8.162 +
   8.163 +static void free_colorhash(struct color_hash *hash)
   8.164 +{
   8.165 +	int i;
   8.166 +	struct hash_entry *entry, *freeable;
   8.167 +
   8.168 +	for ( i=0; i<HASH_SIZE; ++i ) {
   8.169 +		entry = hash->entries[i];
   8.170 +		while ( entry ) {
   8.171 +			freeable = entry;
   8.172 +			entry = entry->next;
   8.173 +			free(freeable->key);
   8.174 +			free(freeable);
   8.175 +		}
   8.176 +	}
   8.177 +	free(hash);
   8.178 +}
   8.179 +
   8.180 +static int color_to_rgb(const char *colorspec, int *r, int *g, int *b)
   8.181 +{
   8.182 +	char rbuf[3];
   8.183 +	char gbuf[3];
   8.184 +	char bbuf[3];
   8.185 +
   8.186 +	/* Handle monochrome black and white */
   8.187 +	if ( strcasecmp(colorspec, "black") == 0 ) {
   8.188 +		*r = 0;
   8.189 +		*g = 0;
   8.190 +		*b = 0;
   8.191 +		return(1);
   8.192 +	}
   8.193 +	if ( strcasecmp(colorspec, "white") == 0 ) {
   8.194 +		*r = 255;
   8.195 +		*g = 255;
   8.196 +		*b = 255;
   8.197 +		return(1);
   8.198 +	}
   8.199 +
   8.200 +	/* Normal hexidecimal color */
   8.201 +	switch (strlen(colorspec)) {
   8.202 +		case 3:
   8.203 +			rbuf[0] = colorspec[0];
   8.204 +			rbuf[1] = colorspec[0];
   8.205 +			gbuf[0] = colorspec[1];
   8.206 +			gbuf[1] = colorspec[1];
   8.207 +			bbuf[0] = colorspec[2];
   8.208 +			bbuf[1] = colorspec[2];
   8.209 +			break;
   8.210 +		case 6:
   8.211 +			rbuf[0] = colorspec[0];
   8.212 +			rbuf[1] = colorspec[1];
   8.213 +			gbuf[0] = colorspec[2];
   8.214 +			gbuf[1] = colorspec[3];
   8.215 +			bbuf[0] = colorspec[4];
   8.216 +			bbuf[1] = colorspec[5];
   8.217 +			break;
   8.218 +		case 12:
   8.219 +			rbuf[0] = colorspec[0];
   8.220 +			rbuf[1] = colorspec[1];
   8.221 +			gbuf[0] = colorspec[4];
   8.222 +			gbuf[1] = colorspec[5];
   8.223 +			bbuf[0] = colorspec[8];
   8.224 +			bbuf[1] = colorspec[9];
   8.225 +			break;
   8.226 +		default:
   8.227 +			return(0);
   8.228 +	}
   8.229 +	rbuf[2] = '\0';
   8.230 +	*r = (int)strtol(rbuf, NULL, 16);
   8.231 +	gbuf[2] = '\0';
   8.232 +	*g = (int)strtol(gbuf, NULL, 16);
   8.233 +	bbuf[2] = '\0';
   8.234 +	*b = (int)strtol(bbuf, NULL, 16);
   8.235 +	return(1);
   8.236 +}
   8.237 +
   8.238 +/* Load a XPM type image from an SDL datasource */
   8.239 +SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src)
   8.240 +{
   8.241 +	SDL_Surface *image;
   8.242 +	char line[1024];
   8.243 +	char *here, *stop;
   8.244 +	int index;
   8.245 +	int i, x, y;
   8.246 +	int w, h, ncolors, cpp;
   8.247 +	int found;
   8.248 +	int r, g, b;
   8.249 +	Uint32 colorkey;
   8.250 +	char *colorkey_string;
   8.251 +	int pixels_len;
   8.252 +	char *pixels;
   8.253 +	int indexed;
   8.254 +	Uint8 *dst;
   8.255 +	Uint32 pixel;
   8.256 +	struct color_hash *colors;
   8.257 +
   8.258 +	/* Skip to the first string, which describes the image */
   8.259 +	image = NULL;
   8.260 +	do {
   8.261 +		here = SDL_RWgets(line, sizeof(line), src);
   8.262 +		if ( ! here ) {
   8.263 +			IMG_SetError("Premature end of data");
   8.264 +			return(NULL);
   8.265 +		}
   8.266 +		if ( *here == '"' ) {
   8.267 +			++here;
   8.268 +			/* Skip to width */
   8.269 +			while ( isspace(*here) ) ++here;
   8.270 +			w = atoi(here);
   8.271 +			while ( ! isspace(*here) ) ++here;
   8.272 +			/* Skip to height */
   8.273 +			while ( isspace(*here) ) ++here;
   8.274 +			h = atoi(here);
   8.275 +			while ( ! isspace(*here) ) ++here;
   8.276 +			/* Skip to number of colors */
   8.277 +			while ( isspace(*here) ) ++here;
   8.278 +			ncolors = atoi(here);
   8.279 +			while ( ! isspace(*here) ) ++here;
   8.280 +			/* Skip to characters per pixel */
   8.281 +			while ( isspace(*here) ) ++here;
   8.282 +			cpp = atoi(here);
   8.283 +			while ( ! isspace(*here) ) ++here;
   8.284 +
   8.285 +			/* Verify the parameters */
   8.286 +			if ( !w || !h || !ncolors || !cpp ) {
   8.287 +				IMG_SetError("Invalid format description");
   8.288 +				return(NULL);
   8.289 +			}
   8.290 +			pixels_len = 1+w*cpp+1+1;
   8.291 +			pixels = (char *)malloc(pixels_len);
   8.292 +			if ( ! pixels ) {
   8.293 +				IMG_SetError("Out of memory");
   8.294 +				return(NULL);
   8.295 +			}
   8.296 +
   8.297 +			/* Create the new surface */
   8.298 +			if ( ncolors <= 256 ) {
   8.299 +				indexed = 1;
   8.300 +				image = SDL_CreateRGBSurface(SDL_SWSURFACE,
   8.301 +							w, h, 8, 0, 0, 0, 0);
   8.302 +			} else {
   8.303 +				int rmask, gmask, bmask;
   8.304 +				indexed = 0;
   8.305 +				if ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) {
   8.306 +					rmask = 0x000000ff;
   8.307 +					gmask = 0x0000ff00;
   8.308 +					bmask = 0x00ff0000;
   8.309 +				} else {
   8.310 +					rmask = 0x00ff0000;
   8.311 +					gmask = 0x0000ff00;
   8.312 +					bmask = 0x000000ff;
   8.313 +				}
   8.314 +				image = SDL_CreateRGBSurface(SDL_SWSURFACE,
   8.315 +							w, h, 32,
   8.316 +							rmask, gmask, bmask, 0);
   8.317 +			}
   8.318 +			if ( ! image ) {
   8.319 +				/* Hmm, some SDL error (out of memory?) */
   8.320 +				free(pixels);
   8.321 +				return(NULL);
   8.322 +			}
   8.323 +		}
   8.324 +	} while ( ! image );
   8.325 +
   8.326 +	/* Read the colors */
   8.327 +	colors = create_colorhash();
   8.328 +	if ( ! colors ) {
   8.329 +		SDL_FreeSurface(image);
   8.330 +		free(pixels);
   8.331 +		IMG_SetError("Out of memory");
   8.332 +		return(NULL);
   8.333 +	}
   8.334 +	colorkey_string = NULL;
   8.335 +	for ( index=0; index < ncolors; ++index ) {
   8.336 +		here = SDL_RWgets(line, sizeof(line), src);
   8.337 +		if ( ! here ) {
   8.338 +			SDL_FreeSurface(image);
   8.339 +			image = NULL;
   8.340 +			IMG_SetError("Premature end of data");
   8.341 +			goto done;
   8.342 +		}
   8.343 +		if ( *here == '"' ) {
   8.344 +			const char *key;
   8.345 +			++here;
   8.346 +			/* Grab the pixel key */
   8.347 +			key = here;
   8.348 +			for ( i=0; i<cpp; ++i ) {
   8.349 +				if ( ! *here++ ) {
   8.350 +					/* Parse error */
   8.351 +					continue;
   8.352 +				}
   8.353 +			}
   8.354 +			if ( *here ) {
   8.355 +				*here++ = '\0';
   8.356 +			}
   8.357 +			/* Find the color identifier */
   8.358 +			found = 0;
   8.359 +			while ( *here && ! found ) {
   8.360 +				while ( isspace(*here) ) ++here;
   8.361 +				if ( (*here != 'c') &&
   8.362 +				     (*here != 'g') &&
   8.363 +				     (*here != 'm') ) {
   8.364 +					/* Skip color type */
   8.365 +					while ( *here && !isspace(*here) )
   8.366 +						++here;
   8.367 +					/* Skip color name */
   8.368 +					while ( isspace(*here) ) ++here;
   8.369 +					while ( *here && !isspace(*here) )
   8.370 +						++here;
   8.371 +					continue;
   8.372 +				}
   8.373 +				++here;
   8.374 +				while ( isspace(*here) ) ++here;
   8.375 +				if ( strncasecmp(here, "None", 4) == 0 ) {
   8.376 +					colorkey_string = strdup(key);
   8.377 +					if ( indexed ) {
   8.378 +						colorkey = (Uint32)index;
   8.379 +					} else {
   8.380 +						colorkey = 0xFFFFFFFF;
   8.381 +					}
   8.382 +					found = 1;
   8.383 +					continue;
   8.384 +				}
   8.385 +				if ( *here == '#' ) {
   8.386 +					++here;
   8.387 +				}
   8.388 +				while ( isspace(*here) ) ++here;
   8.389 +				for ( stop=here; isalnum(*stop); ++stop ) {
   8.390 +					/* Skip the pixel color */;
   8.391 +				}
   8.392 +				*stop++ = '\0';
   8.393 +				found = color_to_rgb(here, &r, &g, &b);
   8.394 +				if ( found ) {
   8.395 +					if ( indexed ) {
   8.396 +						SDL_Color *color;
   8.397 +						color = &image->format->palette->colors[index];
   8.398 +						color->r = (Uint8)r;
   8.399 +						color->g = (Uint8)g;
   8.400 +						color->b = (Uint8)b;
   8.401 +						pixel = index;
   8.402 +					} else {
   8.403 +						pixel = (r<<16)|(g<<8)|b;
   8.404 +					}
   8.405 +					add_colorhash(colors, key, cpp, pixel);
   8.406 +				}
   8.407 +				*here = '\0';
   8.408 +			}
   8.409 +			if ( ! found ) {
   8.410 +				/* Hum, couldn't parse a color.. */;
   8.411 +			}
   8.412 +		}
   8.413 +	}
   8.414 +
   8.415 +	/* Read the pixels */
   8.416 +	for ( y=0; y < h; ) {
   8.417 +		here = SDL_RWgets(pixels, pixels_len, src);
   8.418 +		if ( ! here ) {
   8.419 +			SDL_FreeSurface(image);
   8.420 +			image = NULL;
   8.421 +			IMG_SetError("Premature end of data");
   8.422 +			goto done;
   8.423 +		}
   8.424 +		if ( *here == '"' ) {
   8.425 +			++here;
   8.426 +			dst = (Uint8 *)image->pixels + y*image->pitch;
   8.427 +			for ( x=0; x<w; ++x ) {
   8.428 +				pixel = 0;
   8.429 +				if ( colorkey_string &&
   8.430 +				     (strncmp(here,colorkey_string,cpp)==0) ) {
   8.431 +					pixel = colorkey;
   8.432 +				} else {
   8.433 +					get_colorhash(colors, here,cpp, &pixel);
   8.434 +				}
   8.435 +				if ( indexed ) {
   8.436 +					*dst++ = pixel;
   8.437 +				} else {
   8.438 +					*((Uint32 *)dst)++ = pixel;
   8.439 +				}
   8.440 +				for ( i=0; *here && i<cpp; ++i ) {
   8.441 +					++here;
   8.442 +				}
   8.443 +			}
   8.444 +			++y;
   8.445 +		}
   8.446 +	}
   8.447 +	if ( colorkey_string ) {
   8.448 +        	SDL_SetColorKey(image, SDL_SRCCOLORKEY, colorkey);
   8.449 +	}
   8.450 +done:
   8.451 +	free(pixels);
   8.452 +	free_colorhash(colors);
   8.453 +	if ( colorkey_string ) {
   8.454 +		free(colorkey_string);
   8.455 +	}
   8.456 +	return(image);
   8.457 +}
   8.458 +
   8.459 +#else
   8.460 +
   8.461 +/* See if an image is contained in a data source */
   8.462 +int IMG_isXPM(SDL_RWops *src)
   8.463 +{
   8.464 +	return(0);
   8.465 +}
   8.466 +
   8.467 +/* Load a XPM type image from an SDL datasource */
   8.468 +SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src)
   8.469 +{
   8.470 +	return(NULL);
   8.471 +}
   8.472 +
   8.473 +#endif /* LOAD_XPM */
     9.1 --- a/Makefile.am	Fri Nov 17 21:42:53 2000 +0000
     9.2 +++ b/Makefile.am	Wed Nov 29 11:55:32 2000 +0000
     9.3 @@ -15,7 +15,8 @@
     9.4  	IMG_png.c		\
     9.5  	IMG_ppm.c		\
     9.6  	IMG_tga.c		\
     9.7 -	IMG_tif.c
     9.8 +	IMG_tif.c		\
     9.9 +	IMG_xpm.c
    9.10  
    9.11  EXTRA_DIST =			\
    9.12  	CHANGES			\
    10.1 --- a/SDL_image.h	Fri Nov 17 21:42:53 2000 +0000
    10.2 +++ b/SDL_image.h	Wed Nov 29 11:55:32 2000 +0000
    10.3 @@ -57,6 +57,7 @@
    10.4  /* Functions to detect a file type, given a seekable source */
    10.5  extern DECLSPEC int IMG_isBMP(SDL_RWops *src);
    10.6  extern DECLSPEC int IMG_isPPM(SDL_RWops *src);
    10.7 +extern DECLSPEC int IMG_isXPM(SDL_RWops *src);
    10.8  extern DECLSPEC int IMG_isPCX(SDL_RWops *src);
    10.9  extern DECLSPEC int IMG_isGIF(SDL_RWops *src);
   10.10  extern DECLSPEC int IMG_isJPG(SDL_RWops *src);
   10.11 @@ -66,6 +67,7 @@
   10.12  /* Individual loading functions */
   10.13  extern DECLSPEC SDL_Surface *IMG_LoadBMP_RW(SDL_RWops *src);
   10.14  extern DECLSPEC SDL_Surface *IMG_LoadPPM_RW(SDL_RWops *src);
   10.15 +extern DECLSPEC SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src);
   10.16  extern DECLSPEC SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src);
   10.17  extern DECLSPEC SDL_Surface *IMG_LoadGIF_RW(SDL_RWops *src);
   10.18  extern DECLSPEC SDL_Surface *IMG_LoadJPG_RW(SDL_RWops *src);
    11.1 --- a/configure.in	Fri Nov 17 21:42:53 2000 +0000
    11.2 +++ b/configure.in	Wed Nov 29 11:55:32 2000 +0000
    11.3 @@ -12,10 +12,10 @@
    11.4  # set BINARY_AGE and INTERFACE_AGE to 0.
    11.5  
    11.6  MAJOR_VERSION=1
    11.7 -MINOR_VERSION=0
    11.8 -MICRO_VERSION=10
    11.9 -INTERFACE_AGE=1
   11.10 -BINARY_AGE=10
   11.11 +MINOR_VERSION=1
   11.12 +MICRO_VERSION=0
   11.13 +INTERFACE_AGE=0
   11.14 +BINARY_AGE=0
   11.15  VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
   11.16  
   11.17  AC_SUBST(MAJOR_VERSION)
   11.18 @@ -157,6 +157,12 @@
   11.19          AC_MSG_WARN([TIF image loading disabled])
   11.20      fi
   11.21  fi
   11.22 +AC_ARG_ENABLE(xpm,
   11.23 +[  --enable-xpm            support loading XPM images [default=yes]],
   11.24 +              , enable_xpm=yes)
   11.25 +if test x$enable_xpm = xyes; then
   11.26 +    CFLAGS="$CFLAGS -DLOAD_XPM"
   11.27 +fi
   11.28  AC_SUBST(IMG_LIBS)
   11.29  
   11.30  # Finally create all the generated files
    12.1 --- a/showimage.c	Fri Nov 17 21:42:53 2000 +0000
    12.2 +++ b/showimage.c	Wed Nov 29 11:55:32 2000 +0000
    12.3 @@ -85,12 +85,12 @@
    12.4  		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
    12.5  		exit(255);
    12.6  	}
    12.7 -	atexit(SDL_Quit);
    12.8  
    12.9  	/* Open the image file */
   12.10  	image = IMG_Load(argv[1]);
   12.11  	if ( image == NULL ) {
   12.12  		fprintf(stderr,"Couldn't load %s: %s\n",argv[1],SDL_GetError());
   12.13 +		SDL_Quit();
   12.14  		exit(2);
   12.15  	}
   12.16  	SDL_WM_SetCaption(argv[1], "showimage");
   12.17 @@ -106,6 +106,7 @@
   12.18  	if ( screen == NULL ) {
   12.19  		fprintf(stderr,"Couldn't set %dx%dx%d video mode: %s\n",
   12.20  				image->w, image->h, depth, SDL_GetError());
   12.21 +		SDL_Quit();
   12.22  		exit(3);
   12.23  	}
   12.24  
   12.25 @@ -141,5 +142,6 @@
   12.26  
   12.27  	/* We're done! */
   12.28  	SDL_FreeSurface(image);
   12.29 +	SDL_Quit();
   12.30  	exit(0);
   12.31  }