Skip to content

Commit

Permalink
Fixed crash with right side up BMP files
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Sep 26, 2009
1 parent ce63f67 commit 6fad8aa
Showing 1 changed file with 32 additions and 14 deletions.
46 changes: 32 additions & 14 deletions src/video/SDL_bmp.c
Expand Up @@ -47,7 +47,7 @@

SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
{
int was_error;
SDL_bool was_error;
long fp_offset;
int bmpPitch;
int i, pad;
Expand All @@ -57,6 +57,8 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
Uint32 Bmask;
SDL_Palette *palette;
Uint8 *bits;
Uint8 *top, *end;
SDL_bool topDown;
int ExpandBMP;

/* The Win32 BMP file header (14 bytes) */
Expand All @@ -81,9 +83,9 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)

/* Make sure we are passed a valid data source */
surface = NULL;
was_error = 0;
was_error = SDL_FALSE;
if ( src == NULL ) {
was_error = 1;
was_error = SDL_TRUE;
goto done;
}

Expand All @@ -92,12 +94,12 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
SDL_ClearError();
if ( SDL_RWread(src, magic, 1, 2) != 2 ) {
SDL_Error(SDL_EFREAD);
was_error = 1;
was_error = SDL_TRUE;
goto done;
}
if ( SDL_strncmp(magic, "BM", 2) != 0 ) {
SDL_SetError("File is not a Windows BMP file");
was_error = 1;
was_error = SDL_TRUE;
goto done;
}
bfSize = SDL_ReadLE32(src);
Expand Down Expand Up @@ -130,10 +132,16 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
biClrUsed = SDL_ReadLE32(src);
biClrImportant = SDL_ReadLE32(src);
}
if (biHeight < 0) {
topDown = SDL_TRUE;
biHeight = -biHeight;
} else {
topDown = SDL_FALSE;
}

/* Check for read error */
if ( SDL_strcmp(SDL_GetError(), "") != 0 ) {
was_error = 1;
was_error = SDL_TRUE;
goto done;
}

Expand Down Expand Up @@ -197,15 +205,15 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
break;
default:
SDL_SetError("Compressed BMP files not supported");
was_error = 1;
was_error = SDL_TRUE;
goto done;
}

/* Create a compatible surface, note that the colors are RGB ordered */
surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0);
if ( surface == NULL ) {
was_error = 1;
was_error = SDL_TRUE;
goto done;
}

Expand Down Expand Up @@ -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 */
if ( SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) {
SDL_Error(SDL_EFSEEK);
was_error = 1;
was_error = SDL_TRUE;
goto done;
}
bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
top = (Uint8 *)surface->pixels;
end = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
switch (ExpandBMP) {
case 1:
bmpPitch = (biWidth + 7) >> 3;
Expand All @@ -254,8 +263,12 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
(4-(surface->pitch%4)) : 0);
break;
}
while ( bits > (Uint8 *)surface->pixels ) {
bits -= surface->pitch;
if ( topDown ) {
bits = top;
} else {
bits = end - surface->pitch;
}
while ( bits >= top && bits < end ) {
switch (ExpandBMP) {
case 1:
case 4: {
Expand All @@ -266,7 +279,7 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
if ( !SDL_RWread(src, &pixel, 1, 1) ) {
SDL_SetError(
"Error reading from BMP");
was_error = 1;
was_error = SDL_TRUE;
goto done;
}
}
Expand All @@ -279,7 +292,7 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
if ( SDL_RWread(src, bits, 1, surface->pitch)
!= surface->pitch ) {
SDL_Error(SDL_EFREAD);
was_error = 1;
was_error = SDL_TRUE;
goto done;
}
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
Expand Down Expand Up @@ -311,6 +324,11 @@ SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
SDL_RWread(src, &padbyte, 1, 1);
}
}
if ( topDown ) {
bits += surface->pitch;
} else {
bits -= surface->pitch;
}
}
done:
if ( was_error ) {
Expand Down

0 comments on commit 6fad8aa

Please sign in to comment.