Fix rare crash when generating mipmaps, fixes #923

When generating mipmaps from a 1 wide pixel bitmap (e.g. 1x256 --> 1x128), the bilinear filtering code would accidentally read 1 pixel past the end of the source bitmap when generating the last row.
On most devices this happened to just always work by accident, but on one user's device this would sometimes result in a SEGFAULT
This commit is contained in:
UnknownShadow200 2021-12-31 15:24:49 +11:00
parent ade58b702e
commit 465771e2ec

View File

@ -275,28 +275,34 @@ static BitmapCol AverageCol(BitmapCol p1, BitmapCol p2) {
aSum >> 1); aSum >> 1);
} }
/* Generates the next mipmaps level bitmap for the given bitmap. */ /* Generates the next mipmaps level bitmap by downsampling from the given bitmap. */
static void GenMipmaps(int width, int height, BitmapCol* lvlScan0, BitmapCol* scan0, int rowWidth) { static void GenMipmaps(int width, int height, BitmapCol* dst, BitmapCol* src, int srcWidth) {
BitmapCol* baseSrc = (BitmapCol*)scan0;
BitmapCol* baseDst = (BitmapCol*)lvlScan0;
int x, y; int x, y;
/* Downsampling from a 1 pixel wide bitmap requires simpler filtering */
if (srcWidth == 1) {
for (y = 0; y < height; y++) { for (y = 0; y < height; y++) {
int srcY = (y << 1); /* 1x2 bilinear filter */
BitmapCol* src0 = baseSrc + srcY * rowWidth; dst[0] = AverageCol(*src, *(src + srcWidth));
BitmapCol* src1 = src0 + rowWidth;
BitmapCol* dst = baseDst + y * width; dst += width;
src += (srcWidth << 1);
}
return;
}
for (y = 0; y < height; y++) {
BitmapCol* src0 = src;
BitmapCol* src1 = src + srcWidth;
for (x = 0; x < width; x++) { for (x = 0; x < width; x++) {
int srcX = (x << 1); int srcX = (x << 1);
BitmapCol src00 = src0[srcX], src01 = src0[srcX + 1]; /* 2x2 bilinear filter */
BitmapCol src10 = src1[srcX], src11 = src1[srcX + 1]; BitmapCol ave0 = AverageCol(src0[srcX], src0[srcX + 1]);
BitmapCol ave1 = AverageCol(src1[srcX], src1[srcX + 1]);
/* bilinear filter this mipmap */
BitmapCol ave0 = AverageCol(src00, src01);
BitmapCol ave1 = AverageCol(src10, src11);
dst[x] = AverageCol(ave0, ave1); dst[x] = AverageCol(ave0, ave1);
} }
src += (srcWidth << 1);
dst += width;
} }
} }