IMG_bmp.c
changeset 202 8e1d88c68bda
parent 189 39d5ac4ec0f8
child 236 cce1251de477
     1.1 --- a/IMG_bmp.c	Tue Sep 22 07:32:17 2009 +0000
     1.2 +++ b/IMG_bmp.c	Sat Sep 26 06:44:08 2009 +0000
     1.3 @@ -185,7 +185,7 @@
     1.4  
     1.5  static SDL_Surface *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 @@ -196,6 +196,8 @@
    1.13  	Uint32 Amask;
    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 @@ -220,9 +222,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 @@ -231,12 +233,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 ( 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 @@ -269,10 +271,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 ( 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 @@ -346,7 +354,7 @@
    1.67  	surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
    1.68  			biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, Amask);
    1.69  	if ( surface == NULL ) {
    1.70 -		was_error = 1;
    1.71 +		was_error = SDL_TRUE;
    1.72  		goto done;
    1.73  	}
    1.74  
    1.75 @@ -355,7 +363,7 @@
    1.76  	if ( palette ) {
    1.77  		if ( SDL_RWseek(src, fp_offset+14+biSize, SEEK_SET) < 0 ) {
    1.78  			SDL_Error(SDL_EFSEEK);
    1.79 -			was_error = 1;
    1.80 +			was_error = SDL_TRUE;
    1.81  			goto done;
    1.82  		}
    1.83  
    1.84 @@ -387,7 +395,7 @@
    1.85  	/* Read the surface pixels.  Note that the bmp image is upside down */
    1.86  	if ( SDL_RWseek(src, fp_offset+bfOffBits, 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  	if ((biCompression == BI_RLE4) || (biCompression == BI_RLE8)) {
    1.93 @@ -395,7 +403,8 @@
    1.94  		if (was_error) SDL_SetError("Error reading from BMP");
    1.95  		goto done;
    1.96  	}
    1.97 -	bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
    1.98 +	top = (Uint8 *)surface->pixels;
    1.99 +	end = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
   1.100  	switch (ExpandBMP) {
   1.101  		case 1:
   1.102  			bmpPitch = (biWidth + 7) >> 3;
   1.103 @@ -410,8 +419,12 @@
   1.104  					(4-(surface->pitch%4)) : 0);
   1.105  			break;
   1.106  	}
   1.107 -	while ( bits > (Uint8 *)surface->pixels ) {
   1.108 -		bits -= surface->pitch;
   1.109 +	if ( topDown ) {
   1.110 +		bits = top;
   1.111 +	} else {
   1.112 +		bits = end - surface->pitch;
   1.113 +	}
   1.114 +	while ( bits >= top && bits < end ) {
   1.115  		switch (ExpandBMP) {
   1.116  			case 1:
   1.117  			case 4: {
   1.118 @@ -422,7 +435,7 @@
   1.119  					if ( !SDL_RWread(src, &pixel, 1, 1) ) {
   1.120  						SDL_SetError(
   1.121  					"Error reading from BMP");
   1.122 -						was_error = 1;
   1.123 +						was_error = SDL_TRUE;
   1.124  						goto done;
   1.125  					}
   1.126  				}
   1.127 @@ -435,7 +448,7 @@
   1.128  			if ( SDL_RWread(src, bits, 1, surface->pitch)
   1.129  							 != surface->pitch ) {
   1.130  				SDL_Error(SDL_EFREAD);
   1.131 -				was_error = 1;
   1.132 +				was_error = SDL_TRUE;
   1.133  				goto done;
   1.134  			}
   1.135  #if SDL_BYTEORDER == SDL_BIG_ENDIAN
   1.136 @@ -467,6 +480,11 @@
   1.137  				SDL_RWread(src, &padbyte, 1, 1);
   1.138  			}
   1.139  		}
   1.140 +		if ( topDown ) {
   1.141 +			bits += surface->pitch;
   1.142 +		} else {
   1.143 +			bits -= surface->pitch;
   1.144 +		}
   1.145  	}
   1.146  done:
   1.147  	if ( was_error ) {
   1.148 @@ -496,7 +514,7 @@
   1.149  static SDL_Surface *
   1.150  LoadICOCUR_RW(SDL_RWops * src, int type, int freesrc)
   1.151  {
   1.152 -    int was_error;
   1.153 +    SDL_bool was_error;
   1.154      long fp_offset;
   1.155      int bmpPitch;
   1.156      int i, pad;
   1.157 @@ -530,9 +548,9 @@
   1.158  
   1.159      /* Make sure we are passed a valid data source */
   1.160      surface = NULL;
   1.161 -    was_error = 0;
   1.162 +    was_error = SDL_FALSE;
   1.163      if (src == NULL) {
   1.164 -        was_error = 1;
   1.165 +        was_error = SDL_TRUE;
   1.166          goto done;
   1.167      }
   1.168  
   1.169 @@ -545,7 +563,7 @@
   1.170      bfCount = SDL_ReadLE16(src);
   1.171      if ((bfReserved != 0) || (bfType != type) || (bfCount == 0)) {
   1.172          SDL_SetError("File is not a Windows %s file", type == 1 ? "ICO" : "CUR");
   1.173 -        was_error = 1;
   1.174 +        was_error = SDL_TRUE;
   1.175          goto done;
   1.176      }
   1.177  
   1.178 @@ -579,7 +597,7 @@
   1.179      /* Advance to the DIB Data */
   1.180      if (SDL_RWseek(src, icoOfs, RW_SEEK_SET) < 0) {
   1.181          SDL_Error(SDL_EFSEEK);
   1.182 -        was_error = 1;
   1.183 +        was_error = SDL_TRUE;
   1.184          goto done;
   1.185      }
   1.186  
   1.187 @@ -598,13 +616,13 @@
   1.188          biClrImportant = SDL_ReadLE32(src);
   1.189      } else {
   1.190          SDL_SetError("Unsupported ICO bitmap format");
   1.191 -        was_error = 1;
   1.192 +        was_error = SDL_TRUE;
   1.193          goto done;
   1.194      }
   1.195  
   1.196      /* Check for read error */
   1.197      if (SDL_strcmp(SDL_GetError(), "") != 0) {
   1.198 -        was_error = 1;
   1.199 +        was_error = SDL_TRUE;
   1.200          goto done;
   1.201      }
   1.202  
   1.203 @@ -629,13 +647,13 @@
   1.204              break;
   1.205          default:
   1.206              SDL_SetError("ICO file with unsupported bit count");
   1.207 -            was_error = 1;
   1.208 +            was_error = SDL_TRUE;
   1.209              goto done;
   1.210          }
   1.211          break;
   1.212      default:
   1.213          SDL_SetError("Compressed ICO files not supported");
   1.214 -        was_error = 1;
   1.215 +        was_error = SDL_TRUE;
   1.216          goto done;
   1.217      }
   1.218  
   1.219 @@ -646,7 +664,7 @@
   1.220          SDL_CreateRGBSurface(0, biWidth, biHeight, 32, 0x00FF0000,
   1.221                               0x0000FF00, 0x000000FF, 0xFF000000);
   1.222      if (surface == NULL) {
   1.223 -        was_error = 1;
   1.224 +        was_error = SDL_TRUE;
   1.225          goto done;
   1.226      }
   1.227  
   1.228 @@ -694,7 +712,7 @@
   1.229                      if (i % (8 / ExpandBMP) == 0) {
   1.230                          if (!SDL_RWread(src, &pixel, 1, 1)) {
   1.231                              SDL_SetError("Error reading from ICO");
   1.232 -                            was_error = 1;
   1.233 +                            was_error = SDL_TRUE;
   1.234                              goto done;
   1.235                          }
   1.236                      }
   1.237 @@ -708,7 +726,7 @@
   1.238              if (SDL_RWread(src, bits, 1, surface->pitch)
   1.239                  != surface->pitch) {
   1.240                  SDL_Error(SDL_EFREAD);
   1.241 -                was_error = 1;
   1.242 +                was_error = SDL_TRUE;
   1.243                  goto done;
   1.244              }
   1.245              break;
   1.246 @@ -735,7 +753,7 @@
   1.247              if (i % (8 / ExpandBMP) == 0) {
   1.248                  if (!SDL_RWread(src, &pixel, 1, 1)) {
   1.249                      SDL_SetError("Error reading from ICO");
   1.250 -                    was_error = 1;
   1.251 +                    was_error = SDL_TRUE;
   1.252                      goto done;
   1.253                  }
   1.254              }