From c71abd08605b8bb7078372307a93274725c99fe0 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Fri, 28 Aug 2026 21:20:32 -0400
Subject: [PATCH] bmp: Correctly load RLE-encoded bitmaps with irregular
widths.
(Such as a 4-bpp image--two pixels per byte--with an odd number of pixels.)
Fixes #16210.
---
src/video/SDL_bmp.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/src/video/SDL_bmp.c b/src/video/SDL_bmp.c
index 14e7fb76f11a6..941429c4e5c1b 100644
--- a/src/video/SDL_bmp.c
+++ b/src/video/SDL_bmp.c
@@ -96,10 +96,11 @@ static bool readRlePixels(SDL_Surface *surface, SDL_IOStream *src, int isRle8)
if (!SDL_ReadU8(src, &pixelvalue)) {
return false;
}
- ch /= pixels_per_byte;
+ int ich = (int) ch;
do {
COPY_PIXEL(pixelvalue);
- } while (--ch);
+ ich -= pixels_per_byte;
+ } while (ich > 0);
} else {
/*
| A leading zero is an escape; it may signal the end of the bitmap,
@@ -121,22 +122,31 @@ static bool readRlePixels(SDL_Surface *surface, SDL_IOStream *src, int isRle8)
return false;
}
ofs += ch / pixels_per_byte;
-
+ if (ch & pixels_per_byte) {
+ ofs++;
+ }
if (!SDL_ReadU8(src, &ch)) {
return false;
}
- bits -= ((ch / pixels_per_byte) * pitch);
+ bits -= (ch * pitch);
break;
default: // no compression
- ch /= pixels_per_byte;
- needsPad = (ch & 1);
+ // !!! FIXME: this needsPad calculation can probably be simpler than this.
+ if (pixels_per_byte == 1) {
+ needsPad = (ch & 1) != 0;
+ } else {
+ needsPad = (((ch + (pixels_per_byte-1)) / pixels_per_byte) & (pixels_per_byte-1)) != 0;
+ }
+
+ int ich = (int) ch;
do {
Uint8 pixelvalue;
if (!SDL_ReadU8(src, &pixelvalue)) {
return false;
}
COPY_PIXEL(pixelvalue);
- } while (--ch);
+ ich -= pixels_per_byte;
+ } while (ich > 0);
// pad at even boundary
if (needsPad && !SDL_ReadU8(src, &ch)) {