src/video/SDL_bmp.c
changeset 3310 b907e83deb88
parent 3026 69ab1117dd3b
child 3497 74d2f44a85de
     1.1 --- a/src/video/SDL_bmp.c	Sat Sep 26 03:58:35 2009 +0000
     1.2 +++ b/src/video/SDL_bmp.c	Sat Sep 26 06:21:36 2009 +0000
     1.3 @@ -49,7 +49,7 @@
     1.4  SDL_Surface *
     1.5  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 @@ -59,6 +59,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 @@ -83,9 +85,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 @@ -94,12 +96,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 @@ -132,10 +134,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 @@ -199,7 +207,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 @@ -208,7 +216,7 @@
    1.76          SDL_CreateRGBSurface(0, biWidth, biHeight, biBitCount, Rmask, Gmask,
    1.77                               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 @@ -226,7 +234,7 @@
    1.85                                            sizeof(*palette->colors));
    1.86              if (!palette->colors) {
    1.87                  SDL_OutOfMemory();
    1.88 -                was_error = 1;
    1.89 +                was_error = SDL_TRUE;
    1.90                  goto done;
    1.91              }
    1.92          } else if ((int) biClrUsed < palette->ncolors) {
    1.93 @@ -252,10 +260,11 @@
    1.94      /* Read the surface pixels.  Note that the bmp image is upside down */
    1.95      if (SDL_RWseek(src, fp_offset + bfOffBits, RW_SEEK_SET) < 0) {
    1.96          SDL_Error(SDL_EFSEEK);
    1.97 -        was_error = 1;
    1.98 +        was_error = SDL_TRUE;
    1.99          goto done;
   1.100      }
   1.101 -    bits = (Uint8 *) surface->pixels + (surface->h * surface->pitch);
   1.102 +    top = (Uint8 *)surface->pixels;
   1.103 +    end = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
   1.104      switch (ExpandBMP) {
   1.105      case 1:
   1.106          bmpPitch = (biWidth + 7) >> 3;
   1.107 @@ -269,19 +278,22 @@
   1.108          pad = ((surface->pitch % 4) ? (4 - (surface->pitch % 4)) : 0);
   1.109          break;
   1.110      }
   1.111 -    while (bits > (Uint8 *) surface->pixels) {
   1.112 -        bits -= surface->pitch;
   1.113 +    if (topDown) {
   1.114 +        bits = top;
   1.115 +    } else {
   1.116 +        bits = end - surface->pitch;
   1.117 +    }
   1.118 +    while (bits >= top && bits < end) {
   1.119          switch (ExpandBMP) {
   1.120          case 1:
   1.121 -        case 4:
   1.122 -            {
   1.123 +        case 4:{
   1.124                  Uint8 pixel = 0;
   1.125                  int shift = (8 - ExpandBMP);
   1.126                  for (i = 0; i < surface->w; ++i) {
   1.127                      if (i % (8 / ExpandBMP) == 0) {
   1.128                          if (!SDL_RWread(src, &pixel, 1, 1)) {
   1.129                              SDL_SetError("Error reading from BMP");
   1.130 -                            was_error = 1;
   1.131 +                            was_error = SDL_TRUE;
   1.132                              goto done;
   1.133                          }
   1.134                      }
   1.135 @@ -295,7 +307,7 @@
   1.136              if (SDL_RWread(src, bits, 1, surface->pitch)
   1.137                  != surface->pitch) {
   1.138                  SDL_Error(SDL_EFREAD);
   1.139 -                was_error = 1;
   1.140 +                was_error = SDL_TRUE;
   1.141                  goto done;
   1.142              }
   1.143  #if SDL_BYTEORDER == SDL_BIG_ENDIAN
   1.144 @@ -303,16 +315,14 @@
   1.145                 case has already been taken care of above. */
   1.146              switch (biBitCount) {
   1.147              case 15:
   1.148 -            case 16:
   1.149 -                {
   1.150 +            case 16:{
   1.151                      Uint16 *pix = (Uint16 *) bits;
   1.152                      for (i = 0; i < surface->w; i++)
   1.153                          pix[i] = SDL_Swap16(pix[i]);
   1.154                      break;
   1.155                  }
   1.156  
   1.157 -            case 32:
   1.158 -                {
   1.159 +            case 32:{
   1.160                      Uint32 *pix = (Uint32 *) bits;
   1.161                      for (i = 0; i < surface->w; i++)
   1.162                          pix[i] = SDL_Swap32(pix[i]);
   1.163 @@ -329,6 +339,11 @@
   1.164                  SDL_RWread(src, &padbyte, 1, 1);
   1.165              }
   1.166          }
   1.167 +        if (topDown) {
   1.168 +            bits += surface->pitch;
   1.169 +        } else {
   1.170 +            bits -= surface->pitch;
   1.171 +        }
   1.172      }
   1.173    done:
   1.174      if (was_error) {