From 01a4f5d3594ce39a2514f076cebc59abc21c9e8e Mon Sep 17 00:00:00 2001 From: cutealien Date: Sun, 14 Jun 2020 20:42:30 +0000 Subject: [PATCH] Fix CImage::copyToScaling bug introduced in r5994. The change to the scaling code caused scaling to read outside of original image memory. Was caused because scaling step factor was based on image-sizes, but has to be based on amount of scaling steps taking (off-by-one error). Thanks @Maksym Hamarnyk for reporting that there was some problem. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6121 dfc29bdd-3216-0410-991c-e03cc46cb475 --- source/Irrlicht/CImage.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/Irrlicht/CImage.cpp b/source/Irrlicht/CImage.cpp index ffd23fcb..753262b7 100644 --- a/source/Irrlicht/CImage.cpp +++ b/source/Irrlicht/CImage.cpp @@ -216,13 +216,21 @@ void CImage::copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT fo } } - const f32 sourceXStep = (f32)Size.Width / (f32)width; - const f32 sourceYStep = (f32)Size.Height / (f32)height; + // NOTE: Scaling is coded to keep the border pixels intact. + // Alternatively we could for example work with first pixel being taken at half step-size. + // Then we have one more step here and it would be: + // sourceXStep = (f32)(Size.Width-1) / (f32)(width); + // And sx would start at 0.5f + sourceXStep / 2.f; + // Similar for y. + // As scaling is done without any antialiasing it doesn't matter too much which outermost pixels we use and keeping + // border pixels intact is probably mostly better (with AA the other solution would be more correct). + const f32 sourceXStep = width > 1 ? (f32)(Size.Width-1) / (f32)(width-1) : 0.f; + const f32 sourceYStep = height > 1 ? (f32)(Size.Height-1) / (f32)(height-1) : 0.f; s32 yval=0, syval=0; - f32 sy = 0.5f; // nearest pixel (used in float-int conversion below) + f32 sy = 0.5f; // for rounding to nearest pixel for (u32 y=0; y