1.1 --- a/src/video/SDL_bmp.c Sat Sep 06 23:20:14 2014 +0200
1.2 +++ b/src/video/SDL_bmp.c Mon Sep 08 01:36:22 2014 -0400
1.3 @@ -85,15 +85,17 @@
1.4 int bmpPitch;
1.5 int i, pad;
1.6 SDL_Surface *surface;
1.7 - Uint32 Rmask;
1.8 - Uint32 Gmask;
1.9 - Uint32 Bmask;
1.10 - Uint32 Amask;
1.11 + Uint32 Rmask = 0;
1.12 + Uint32 Gmask = 0;
1.13 + Uint32 Bmask = 0;
1.14 + Uint32 Amask = 0;
1.15 SDL_Palette *palette;
1.16 Uint8 *bits;
1.17 Uint8 *top, *end;
1.18 SDL_bool topDown;
1.19 int ExpandBMP;
1.20 + SDL_bool haveRGBMasks = SDL_FALSE;
1.21 + SDL_bool haveAlphaMask = SDL_FALSE;
1.22 SDL_bool correctAlpha = SDL_FALSE;
1.23
1.24 /* The Win32 BMP file header (14 bytes) */
1.25 @@ -144,15 +146,14 @@
1.26
1.27 /* Read the Win32 BITMAPINFOHEADER */
1.28 biSize = SDL_ReadLE32(src);
1.29 - if (biSize == 12) {
1.30 + if (biSize == 12) { /* really old BITMAPCOREHEADER */
1.31 biWidth = (Uint32) SDL_ReadLE16(src);
1.32 biHeight = (Uint32) SDL_ReadLE16(src);
1.33 /* biPlanes = */ SDL_ReadLE16(src);
1.34 biBitCount = SDL_ReadLE16(src);
1.35 biCompression = BI_RGB;
1.36 - } else {
1.37 - const unsigned int headerSize = 40;
1.38 -
1.39 + } else if (biSize >= 40) { /* some version of BITMAPINFOHEADER */
1.40 + Uint32 headerSize;
1.41 biWidth = SDL_ReadLE32(src);
1.42 biHeight = SDL_ReadLE32(src);
1.43 /* biPlanes = */ SDL_ReadLE16(src);
1.44 @@ -164,6 +165,54 @@
1.45 biClrUsed = SDL_ReadLE32(src);
1.46 /* biClrImportant = */ SDL_ReadLE32(src);
1.47
1.48 + /* 64 == BITMAPCOREHEADER2, an incompatible OS/2 2.x extension. Skip this stuff for now. */
1.49 + if (biSize == 64) {
1.50 + /* ignore these extra fields. */
1.51 + if (biCompression == BI_BITFIELDS) {
1.52 + /* this value is actually huffman compression in this variant. */
1.53 + SDL_SetError("Compressed BMP files not supported");
1.54 + was_error = SDL_TRUE;
1.55 + goto done;
1.56 + }
1.57 + } else {
1.58 + /* This is complicated. If compression is BI_BITFIELDS, then
1.59 + we have 3 DWORDS that specify the RGB masks. This is either
1.60 + stored here in an BITMAPV2INFOHEADER (which only differs in
1.61 + that it adds these RGB masks) and biSize >= 52, or we've got
1.62 + these masks stored in the exact same place, but strictly
1.63 + speaking, this is the bmiColors field in BITMAPINFO immediately
1.64 + following the legacy v1 info header, just past biSize. */
1.65 + if (biCompression == BI_BITFIELDS) {
1.66 + haveRGBMasks = SDL_TRUE;
1.67 + Rmask = SDL_ReadLE32(src);
1.68 + Gmask = SDL_ReadLE32(src);
1.69 + Bmask = SDL_ReadLE32(src);
1.70 +
1.71 + /* ...v3 adds an alpha mask. */
1.72 + if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */
1.73 + haveAlphaMask = SDL_TRUE;
1.74 + Amask = SDL_ReadLE32(src);
1.75 + }
1.76 + } else {
1.77 + /* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */
1.78 + if (biSize >= 52) { /* BITMAPV2INFOHEADER; adds RGB masks */
1.79 + /*Rmask = */ SDL_ReadLE32(src);
1.80 + /*Gmask = */ SDL_ReadLE32(src);
1.81 + /*Bmask = */ SDL_ReadLE32(src);
1.82 + }
1.83 + if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */
1.84 + /*Amask = */ SDL_ReadLE32(src);
1.85 + }
1.86 + }
1.87 +
1.88 + /* Insert other fields here; Wikipedia and MSDN say we're up to
1.89 + v5 of this header, but we ignore those for now (they add gamma,
1.90 + color spaces, etc). Ignoring the weird OS/2 2.x format, we
1.91 + currently parse up to v3 correctly (hopefully!). */
1.92 + }
1.93 +
1.94 + /* skip any header bytes we didn't handle... */
1.95 + headerSize = (Uint32) (SDL_RWtell(src) - (fp_offset + 14));
1.96 if (biSize > headerSize) {
1.97 SDL_RWseek(src, (biSize - headerSize), RW_SEEK_CUR);
1.98 }
1.99 @@ -194,80 +243,46 @@
1.100 }
1.101
1.102 /* We don't support any BMP compression right now */
1.103 - Rmask = Gmask = Bmask = Amask = 0;
1.104 switch (biCompression) {
1.105 case BI_RGB:
1.106 /* If there are no masks, use the defaults */
1.107 - if (bfOffBits == (14 + biSize)) {
1.108 - /* Default values for the BMP format */
1.109 - switch (biBitCount) {
1.110 - case 15:
1.111 - case 16:
1.112 - Rmask = 0x7C00;
1.113 - Gmask = 0x03E0;
1.114 - Bmask = 0x001F;
1.115 - break;
1.116 - case 24:
1.117 -#if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.118 - Rmask = 0x000000FF;
1.119 - Gmask = 0x0000FF00;
1.120 - Bmask = 0x00FF0000;
1.121 -#else
1.122 - Rmask = 0x00FF0000;
1.123 - Gmask = 0x0000FF00;
1.124 - Bmask = 0x000000FF;
1.125 -#endif
1.126 - break;
1.127 - case 32:
1.128 - /* We don't know if this has alpha channel or not */
1.129 - correctAlpha = SDL_TRUE;
1.130 - Amask = 0xFF000000;
1.131 - Rmask = 0x00FF0000;
1.132 - Gmask = 0x0000FF00;
1.133 - Bmask = 0x000000FF;
1.134 - break;
1.135 - default:
1.136 - break;
1.137 - }
1.138 - break;
1.139 - }
1.140 - /* Fall through -- read the RGB masks */
1.141 -
1.142 - case BI_BITFIELDS:
1.143 + SDL_assert(!haveRGBMasks);
1.144 + SDL_assert(!haveAlphaMask);
1.145 + /* Default values for the BMP format */
1.146 switch (biBitCount) {
1.147 case 15:
1.148 case 16:
1.149 - Rmask = SDL_ReadLE32(src);
1.150 - Gmask = SDL_ReadLE32(src);
1.151 - Bmask = SDL_ReadLE32(src);
1.152 + Rmask = 0x7C00;
1.153 + Gmask = 0x03E0;
1.154 + Bmask = 0x001F;
1.155 + break;
1.156 + case 24:
1.157 +#if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.158 + Rmask = 0x000000FF;
1.159 + Gmask = 0x0000FF00;
1.160 + Bmask = 0x00FF0000;
1.161 +#else
1.162 + Rmask = 0x00FF0000;
1.163 + Gmask = 0x0000FF00;
1.164 + Bmask = 0x000000FF;
1.165 +#endif
1.166 break;
1.167 case 32:
1.168 - Rmask = SDL_ReadLE32(src);
1.169 - Gmask = SDL_ReadLE32(src);
1.170 - Bmask = SDL_ReadLE32(src);
1.171 - Amask = SDL_ReadLE32(src);
1.172 -
1.173 - /* ImageMagick seems to put out bogus masks here. Pick a default. */
1.174 - if ((Rmask == 0xFFFFFF) && (Gmask == 0xFFFFFF) &&
1.175 - (Bmask == 0xFFFFFF) && (Amask == 0xFFFFFF) ) {
1.176 - Amask = 0xFF000000;
1.177 - Rmask = 0x00FF0000;
1.178 - Gmask = 0x0000FF00;
1.179 - Bmask = 0x000000FF;
1.180 - } else if ((Rmask == 0xFFFFFF00) && (Gmask == 0xFFFFFF00) &&
1.181 - (Bmask == 0xFFFFFF00) && (Amask == 0xFFFFFF00) ) {
1.182 - /* argh, The Gimp seems to put out different bogus masks! */
1.183 - Amask = 0x000000FF;
1.184 - Rmask = 0xFF000000;
1.185 - Gmask = 0x00FF0000;
1.186 - Bmask = 0x0000FF00;
1.187 - }
1.188 -
1.189 + /* We don't know if this has alpha channel or not */
1.190 + correctAlpha = SDL_TRUE;
1.191 + Amask = 0xFF000000;
1.192 + Rmask = 0x00FF0000;
1.193 + Gmask = 0x0000FF00;
1.194 + Bmask = 0x000000FF;
1.195 break;
1.196 default:
1.197 break;
1.198 }
1.199 break;
1.200 +
1.201 + case BI_BITFIELDS:
1.202 + break; /* we handled this in the info header. */
1.203 +
1.204 default:
1.205 SDL_SetError("Compressed BMP files not supported");
1.206 was_error = SDL_TRUE;