From 2613521aa87b5aba3bcfc75c944255c9ba4b327f Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Sun, 4 Feb 2024 20:11:53 +0900 Subject: [PATCH] sw_engine: Improve image up-scaler quality Adjusted the sampling position basis by -0.5 pixel to enhance edge line interpolation quality. This change addresses an issue with the image up-scaling process, resulting in clearer and more accurate visuals. issue: https://github.com/thorvg/thorvg/issues/1949 --- src/renderer/sw_engine/tvgSwRaster.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/renderer/sw_engine/tvgSwRaster.cpp b/src/renderer/sw_engine/tvgSwRaster.cpp index a3118b83..98374d3f 100644 --- a/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/src/renderer/sw_engine/tvgSwRaster.cpp @@ -257,15 +257,15 @@ static uint32_t _interpUpScaler(const uint32_t *img, TVG_UNUSED uint32_t stride, auto ry2 = ry + 1; if (ry2 >= h) ry2 = h - 1; - auto dx = static_cast((sx - rx) * 255.0f); - auto dy = static_cast((sy - ry) * 255.0f); + auto dx = (sx > 0.0f) ? static_cast((sx - rx) * 255.0f) : 0; + auto dy = (sy > 0.0f) ? static_cast((sy - ry) * 255.0f) : 0; auto c1 = img[rx + ry * w]; auto c2 = img[rx2 + ry * w]; - auto c3 = img[rx2 + ry2 * w]; - auto c4 = img[rx + ry2 * w]; + auto c3 = img[rx + ry2 * w]; + auto c4 = img[rx2 + ry2 * w]; - return INTERPOLATE(INTERPOLATE(c3, c4, dx), INTERPOLATE(c2, c1, dx), dy); + return INTERPOLATE(INTERPOLATE(c4, c3, dx), INTERPOLATE(c2, c1, dx), dy); } @@ -671,10 +671,10 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, /************************************************************************/ #define SCALED_IMAGE_RANGE_Y(y) \ - auto sy = (y) * itransform->e22 + itransform->e23; \ - auto my = (int32_t)round(sy); \ - if (my < 0 || (uint32_t)sy >= image->h) continue; \ + auto sy = (y) * itransform->e22 + itransform->e23 - 0.49f; \ + if (sy <= -0.5f || (uint32_t)(sy + 0.5f) >= image->h) continue; \ if (scaleMethod == _interpDownScaler) { \ + auto my = (int32_t)round(sy); \ miny = my - (int32_t)sampleSize; \ if (miny < 0) miny = 0; \ maxy = my + (int32_t)sampleSize; \ @@ -682,8 +682,8 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, } #define SCALED_IMAGE_RANGE_X \ - auto sx = x * itransform->e11 + itransform->e13; \ - if ((int32_t)round(sx) < 0 || (uint32_t) sx >= image->w) continue; + auto sx = (x) * itransform->e11 + itransform->e13 - 0.49f; \ + if (sx <= -0.5f || (uint32_t)(sx + 0.5f) >= image->w) continue; \ #if 0 //Enable it when GRAYSCALE image is supported