# HG changeset patch # User Sam Lantinga # Date 1253944887 0 # Node ID d3a210342761d710d507ad3d901f78fc0a86c747 # Parent cb44bf8f8a0fde68880ccaa6396d187560fc5283 Fixed crash with right side up BMP files diff -r cb44bf8f8a0f -r d3a210342761 src/video/SDL_bmp.c --- a/src/video/SDL_bmp.c Wed Sep 23 07:18:02 2009 +0000 +++ b/src/video/SDL_bmp.c Sat Sep 26 06:01:27 2009 +0000 @@ -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; @@ -57,6 +57,8 @@ Uint32 Bmask; SDL_Palette *palette; Uint8 *bits; + Uint8 *top, *end; + SDL_bool topDown; int ExpandBMP; /* The Win32 BMP file header (14 bytes) */ @@ -81,9 +83,9 @@ /* 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; } @@ -92,12 +94,12 @@ 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); @@ -130,10 +132,16 @@ 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; } @@ -197,7 +205,7 @@ break; default: SDL_SetError("Compressed BMP files not supported"); - was_error = 1; + was_error = SDL_TRUE; goto done; } @@ -205,7 +213,7 @@ surface = SDL_CreateRGBSurface(SDL_SWSURFACE, biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0); if ( surface == NULL ) { - was_error = 1; + was_error = SDL_TRUE; goto done; } @@ -236,10 +244,11 @@ /* 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; @@ -254,8 +263,12 @@ (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: { @@ -266,7 +279,7 @@ if ( !SDL_RWread(src, &pixel, 1, 1) ) { SDL_SetError( "Error reading from BMP"); - was_error = 1; + was_error = SDL_TRUE; goto done; } } @@ -279,7 +292,7 @@ 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 @@ -311,6 +324,11 @@ SDL_RWread(src, &padbyte, 1, 1); } } + if ( topDown ) { + bits += surface->pitch; + } else { + bits -= surface->pitch; + } } done: if ( was_error ) {