Commit 269b8143 authored by Sam Lantinga's avatar Sam Lantinga

Fixed crash with right side up BMP files

--HG--
branch : SDL-1.2
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%403900
parent 5cbd26fc
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
{ {
int was_error; SDL_bool was_error;
long fp_offset; long fp_offset;
int bmpPitch; int bmpPitch;
int i, pad; int i, pad;
...@@ -57,6 +57,8 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -57,6 +57,8 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
Uint32 Bmask; Uint32 Bmask;
SDL_Palette *palette; SDL_Palette *palette;
Uint8 *bits; Uint8 *bits;
Uint8 *top, *end;
SDL_bool topDown;
int ExpandBMP; int ExpandBMP;
/* The Win32 BMP file header (14 bytes) */ /* The Win32 BMP file header (14 bytes) */
...@@ -81,9 +83,9 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -81,9 +83,9 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
/* Make sure we are passed a valid data source */ /* Make sure we are passed a valid data source */
surface = NULL; surface = NULL;
was_error = 0; was_error = SDL_FALSE;
if ( src == NULL ) { if ( src == NULL ) {
was_error = 1; was_error = SDL_TRUE;
goto done; goto done;
} }
...@@ -92,12 +94,12 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -92,12 +94,12 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
SDL_ClearError(); SDL_ClearError();
if ( SDL_RWread(src, magic, 1, 2) != 2 ) { if ( SDL_RWread(src, magic, 1, 2) != 2 ) {
SDL_Error(SDL_EFREAD); SDL_Error(SDL_EFREAD);
was_error = 1; was_error = SDL_TRUE;
goto done; goto done;
} }
if ( SDL_strncmp(magic, "BM", 2) != 0 ) { if ( SDL_strncmp(magic, "BM", 2) != 0 ) {
SDL_SetError("File is not a Windows BMP file"); SDL_SetError("File is not a Windows BMP file");
was_error = 1; was_error = SDL_TRUE;
goto done; goto done;
} }
bfSize = SDL_ReadLE32(src); bfSize = SDL_ReadLE32(src);
...@@ -130,10 +132,16 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -130,10 +132,16 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
biClrUsed = SDL_ReadLE32(src); biClrUsed = SDL_ReadLE32(src);
biClrImportant = SDL_ReadLE32(src); biClrImportant = SDL_ReadLE32(src);
} }
if (biHeight < 0) {
topDown = SDL_TRUE;
biHeight = -biHeight;
} else {
topDown = SDL_FALSE;
}
/* Check for read error */ /* Check for read error */
if ( SDL_strcmp(SDL_GetError(), "") != 0 ) { if ( SDL_strcmp(SDL_GetError(), "") != 0 ) {
was_error = 1; was_error = SDL_TRUE;
goto done; goto done;
} }
...@@ -197,7 +205,7 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -197,7 +205,7 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
break; break;
default: default:
SDL_SetError("Compressed BMP files not supported"); SDL_SetError("Compressed BMP files not supported");
was_error = 1; was_error = SDL_TRUE;
goto done; goto done;
} }
...@@ -205,7 +213,7 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -205,7 +213,7 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
surface = SDL_CreateRGBSurface(SDL_SWSURFACE, surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0); biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0);
if ( surface == NULL ) { if ( surface == NULL ) {
was_error = 1; was_error = SDL_TRUE;
goto done; goto done;
} }
...@@ -236,10 +244,11 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -236,10 +244,11 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
/* Read the surface pixels. Note that the bmp image is upside down */ /* Read the surface pixels. Note that the bmp image is upside down */
if ( SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) { if ( SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) {
SDL_Error(SDL_EFSEEK); SDL_Error(SDL_EFSEEK);
was_error = 1; was_error = SDL_TRUE;
goto done; goto done;
} }
bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch); top = (Uint8 *)surface->pixels;
end = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
switch (ExpandBMP) { switch (ExpandBMP) {
case 1: case 1:
bmpPitch = (biWidth + 7) >> 3; bmpPitch = (biWidth + 7) >> 3;
...@@ -254,8 +263,12 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -254,8 +263,12 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
(4-(surface->pitch%4)) : 0); (4-(surface->pitch%4)) : 0);
break; break;
} }
while ( bits > (Uint8 *)surface->pixels ) { if ( topDown ) {
bits -= surface->pitch; bits = top;
} else {
bits = end - surface->pitch;
}
while ( bits >= top && bits < end ) {
switch (ExpandBMP) { switch (ExpandBMP) {
case 1: case 1:
case 4: { case 4: {
...@@ -266,7 +279,7 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -266,7 +279,7 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
if ( !SDL_RWread(src, &pixel, 1, 1) ) { if ( !SDL_RWread(src, &pixel, 1, 1) ) {
SDL_SetError( SDL_SetError(
"Error reading from BMP"); "Error reading from BMP");
was_error = 1; was_error = SDL_TRUE;
goto done; goto done;
} }
} }
...@@ -279,7 +292,7 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -279,7 +292,7 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
if ( SDL_RWread(src, bits, 1, surface->pitch) if ( SDL_RWread(src, bits, 1, surface->pitch)
!= surface->pitch ) { != surface->pitch ) {
SDL_Error(SDL_EFREAD); SDL_Error(SDL_EFREAD);
was_error = 1; was_error = SDL_TRUE;
goto done; goto done;
} }
#if SDL_BYTEORDER == SDL_BIG_ENDIAN #if SDL_BYTEORDER == SDL_BIG_ENDIAN
...@@ -311,6 +324,11 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) ...@@ -311,6 +324,11 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
SDL_RWread(src, &padbyte, 1, 1); SDL_RWread(src, &padbyte, 1, 1);
} }
} }
if ( topDown ) {
bits += surface->pitch;
} else {
bits -= surface->pitch;
}
} }
done: done:
if ( was_error ) { if ( was_error ) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment