diff --git a/src/video/SDL_bmp.c b/src/video/SDL_bmp.c index bcde0c5786..2880ba03ef 100644 --- a/src/video/SDL_bmp.c +++ b/src/video/SDL_bmp.c @@ -76,16 +76,16 @@ static bool readRlePixels(SDL_Surface *surface, SDL_IOStream *src, int isRle8) int ofs = 0; Uint8 ch; Uint8 needsPad; + const int pixels_per_byte = (isRle8 ? 1 : 2); #define COPY_PIXEL(x) \ spot = &bits[ofs++]; \ if (spot >= start && spot < end) \ - *spot = (x) + *spot = (x) - // !!! FIXME: for all these reads, handle error vs eof? handle -2 if non-blocking? for (;;) { if (!SDL_ReadU8(src, &ch)) { - return true; + return false; } /* | encoded mode starts with a run length, and then a byte @@ -94,26 +94,12 @@ static bool readRlePixels(SDL_Surface *surface, SDL_IOStream *src, int isRle8) if (ch) { Uint8 pixel; if (!SDL_ReadU8(src, &pixel)) { - return true; - } - if (isRle8) { // 256-color bitmap, compressed - do { - COPY_PIXEL(pixel); - } while (--ch); - } else { // 16-color bitmap, compressed - Uint8 pixel0 = pixel >> 4; - Uint8 pixel1 = pixel & 0x0F; - for (;;) { - COPY_PIXEL(pixel0); // even count, high nibble - if (!--ch) { - break; - } - COPY_PIXEL(pixel1); // odd count, low nibble - if (!--ch) { - break; - } - } + return false; } + ch /= pixels_per_byte; + do { + COPY_PIXEL(pixel); + } while (--ch); } else { /* | A leading zero is an escape; it may signal the end of the bitmap, @@ -121,7 +107,7 @@ static bool readRlePixels(SDL_Surface *surface, SDL_IOStream *src, int isRle8) | zero tag may be absolute mode or an escape */ if (!SDL_ReadU8(src, &ch)) { - return true; + return false; } switch (ch) { case 0: // end of line @@ -129,47 +115,33 @@ static bool readRlePixels(SDL_Surface *surface, SDL_IOStream *src, int isRle8) bits -= pitch; // go to previous break; case 1: // end of bitmap - return false; // success! +printf("SUCCESS!\n"); + return true; // success! case 2: // delta if (!SDL_ReadU8(src, &ch)) { - return true; + return false; } - ofs += ch; + ofs += ch / pixels_per_byte; + if (!SDL_ReadU8(src, &ch)) { - return true; + return false; } - bits -= (ch * pitch); + bits -= ((ch / pixels_per_byte) * pitch); break; default: // no compression - if (isRle8) { - needsPad = (ch & 1); - do { - Uint8 pixel; - if (!SDL_ReadU8(src, &pixel)) { - return true; - } - COPY_PIXEL(pixel); - } while (--ch); - } else { - needsPad = (((ch + 1) >> 1) & 1); // (ch+1)>>1: bytes size - for (;;) { - Uint8 pixel; - if (!SDL_ReadU8(src, &pixel)) { - return true; - } - COPY_PIXEL(pixel >> 4); - if (!--ch) { - break; - } - COPY_PIXEL(pixel & 0x0F); - if (!--ch) { - break; - } + ch /= pixels_per_byte; + needsPad = (ch & 1); + do { + Uint8 pixel; + if (!SDL_ReadU8(src, &pixel)) { + return false; } - } + COPY_PIXEL(pixel); + } while (--ch); + // pad at even boundary if (needsPad && !SDL_ReadU8(src, &ch)) { - return true; + return false; } break; } @@ -513,10 +485,13 @@ SDL_Surface *SDL_LoadBMP_IO(SDL_IOStream *src, bool closeio) goto done; } if ((biCompression == BI_RLE4) || (biCompression == BI_RLE8)) { - was_error = readRlePixels(surface, src, biCompression == BI_RLE8); - if (was_error) { + if (!readRlePixels(surface, src, biCompression == BI_RLE8)) { SDL_SetError("Error reading from datastream"); + goto done; } + + // Success! + was_error = false; goto done; } top = (Uint8 *)surface->pixels;