src/video/SDL_bmp.c
branchSDL-1.2
changeset 4241 d3a210342761
parent 4159 a1b03ba2fcd0
child 5988 bf927e528813
     1.1 --- a/src/video/SDL_bmp.c	Wed Sep 23 07:18:02 2009 +0000
     1.2 +++ b/src/video/SDL_bmp.c	Sat Sep 26 06:01:27 2009 +0000
     1.3 @@ -47,7 +47,7 @@
     1.4  
     1.5  SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
     1.6  {
     1.7 -	int was_error;
     1.8 +	SDL_bool was_error;
     1.9  	long fp_offset;
    1.10  	int bmpPitch;
    1.11  	int i, pad;
    1.12 @@ -57,6 +57,8 @@
    1.13  	Uint32 Bmask;
    1.14  	SDL_Palette *palette;
    1.15  	Uint8 *bits;
    1.16 +	Uint8 *top, *end;
    1.17 +	SDL_bool topDown;
    1.18  	int ExpandBMP;
    1.19  
    1.20  	/* The Win32 BMP file header (14 bytes) */
    1.21 @@ -81,9 +83,9 @@
    1.22  
    1.23  	/* Make sure we are passed a valid data source */
    1.24  	surface = NULL;
    1.25 -	was_error = 0;
    1.26 +	was_error = SDL_FALSE;
    1.27  	if ( src == NULL ) {
    1.28 -		was_error = 1;
    1.29 +		was_error = SDL_TRUE;
    1.30  		goto done;
    1.31  	}
    1.32  
    1.33 @@ -92,12 +94,12 @@
    1.34  	SDL_ClearError();
    1.35  	if ( SDL_RWread(src, magic, 1, 2) != 2 ) {
    1.36  		SDL_Error(SDL_EFREAD);
    1.37 -		was_error = 1;
    1.38 +		was_error = SDL_TRUE;
    1.39  		goto done;
    1.40  	}
    1.41  	if ( SDL_strncmp(magic, "BM", 2) != 0 ) {
    1.42  		SDL_SetError("File is not a Windows BMP file");
    1.43 -		was_error = 1;
    1.44 +		was_error = SDL_TRUE;
    1.45  		goto done;
    1.46  	}
    1.47  	bfSize		= SDL_ReadLE32(src);
    1.48 @@ -130,10 +132,16 @@
    1.49  		biClrUsed	= SDL_ReadLE32(src);
    1.50  		biClrImportant	= SDL_ReadLE32(src);
    1.51  	}
    1.52 +	if (biHeight < 0) {
    1.53 +		topDown = SDL_TRUE;
    1.54 +		biHeight = -biHeight;
    1.55 +	} else {
    1.56 +		topDown = SDL_FALSE;
    1.57 +	}
    1.58  
    1.59  	/* Check for read error */
    1.60  	if ( SDL_strcmp(SDL_GetError(), "") != 0 ) {
    1.61 -		was_error = 1;
    1.62 +		was_error = SDL_TRUE;
    1.63  		goto done;
    1.64  	}
    1.65  
    1.66 @@ -197,7 +205,7 @@
    1.67  			break;
    1.68  		default:
    1.69  			SDL_SetError("Compressed BMP files not supported");
    1.70 -			was_error = 1;
    1.71 +			was_error = SDL_TRUE;
    1.72  			goto done;
    1.73  	}
    1.74  
    1.75 @@ -205,7 +213,7 @@
    1.76  	surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
    1.77  			biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0);
    1.78  	if ( surface == NULL ) {
    1.79 -		was_error = 1;
    1.80 +		was_error = SDL_TRUE;
    1.81  		goto done;
    1.82  	}
    1.83  
    1.84 @@ -236,10 +244,11 @@
    1.85  	/* Read the surface pixels.  Note that the bmp image is upside down */
    1.86  	if ( SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) {
    1.87  		SDL_Error(SDL_EFSEEK);
    1.88 -		was_error = 1;
    1.89 +		was_error = SDL_TRUE;
    1.90  		goto done;
    1.91  	}
    1.92 -	bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
    1.93 +	top = (Uint8 *)surface->pixels;
    1.94 +	end = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
    1.95  	switch (ExpandBMP) {
    1.96  		case 1:
    1.97  			bmpPitch = (biWidth + 7) >> 3;
    1.98 @@ -254,8 +263,12 @@
    1.99  					(4-(surface->pitch%4)) : 0);
   1.100  			break;
   1.101  	}
   1.102 -	while ( bits > (Uint8 *)surface->pixels ) {
   1.103 -		bits -= surface->pitch;
   1.104 +	if ( topDown ) {
   1.105 +		bits = top;
   1.106 +	} else {
   1.107 +		bits = end - surface->pitch;
   1.108 +	}
   1.109 +	while ( bits >= top && bits < end ) {
   1.110  		switch (ExpandBMP) {
   1.111  			case 1:
   1.112  			case 4: {
   1.113 @@ -266,7 +279,7 @@
   1.114  					if ( !SDL_RWread(src, &pixel, 1, 1) ) {
   1.115  						SDL_SetError(
   1.116  					"Error reading from BMP");
   1.117 -						was_error = 1;
   1.118 +						was_error = SDL_TRUE;
   1.119  						goto done;
   1.120  					}
   1.121  				}
   1.122 @@ -279,7 +292,7 @@
   1.123  			if ( SDL_RWread(src, bits, 1, surface->pitch)
   1.124  							 != surface->pitch ) {
   1.125  				SDL_Error(SDL_EFREAD);
   1.126 -				was_error = 1;
   1.127 +				was_error = SDL_TRUE;
   1.128  				goto done;
   1.129  			}
   1.130  #if SDL_BYTEORDER == SDL_BIG_ENDIAN
   1.131 @@ -311,6 +324,11 @@
   1.132  				SDL_RWread(src, &padbyte, 1, 1);
   1.133  			}
   1.134  		}
   1.135 +		if ( topDown ) {
   1.136 +			bits += surface->pitch;
   1.137 +		} else {
   1.138 +			bits -= surface->pitch;
   1.139 +		}
   1.140  	}
   1.141  done:
   1.142  	if ( was_error ) {