From 45ee9b72589d5f925cdc039eef0d58a18699e11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Poizl?= Date: Thu, 5 Dec 2024 16:02:46 +0100 Subject: [PATCH] Fix half pixel offset and add filtering in sw rendering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: DuĊĦan Poizl --- imagewidget.cpp | 65 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/imagewidget.cpp b/imagewidget.cpp index 38ac3cd..1b0849c 100644 --- a/imagewidget.cpp +++ b/imagewidget.cpp @@ -352,7 +352,7 @@ void swPaint(std::shared_ptr &rawImage, float dx, float dy, float scal int width = widget->width(); int height = widget->height(); QImage img(width, height, QImage::Format_RGB32); - img.fill(Qt::gray); + img.fill(Qt::darkGray); int64_t ox = dx; int64_t oy = dy; @@ -380,7 +380,7 @@ void swPaint(std::shared_ptr &rawImage, float dx, float dy, float scal { uint32_t *pixels = (uint32_t*)(img.scanLine(y)); float iptr; - float fy = std::modf((y + oy) * iscale - 0.5f, &iptr); + float fy = std::modf((y + oy) * iscale, &iptr); int64_t py = iptr; int64_t w = py * rawImage->widthBytes(); int64_t w2 = w; @@ -389,7 +389,7 @@ void swPaint(std::shared_ptr &rawImage, float dx, float dy, float scal for(int64_t x = std::max((int64_t)0, -ox); x < width; x++) { - float fx = std::modf((x + ox) * iscale - 0.5f, &iptr); + float fx = std::modf((x + ox) * iscale, &iptr); int px = iptr; int px2 = px + 1 < imgWidth ? px + 1 : px; if(px >= imgWidth)break; @@ -400,35 +400,58 @@ void swPaint(std::shared_ptr &rawImage, float dx, float dy, float scal r[0] = src[w + px * 4 + 0]; g[0] = src[w + px * 4 + 1]; b[0] = src[w + px * 4 + 2]; - r[1] = src[w + px2 * 4 + 0]; - g[1] = src[w + px2 * 4 + 1]; - b[1] = src[w + px2 * 4 + 2]; - r[2] = src[w2 + px * 4 + 0]; - g[2] = src[w2 + px * 4 + 1]; - b[2] = src[w2 + px * 4 + 2]; - r[3] = src[w2 + px2 * 4 + 0]; - g[3] = src[w2 + px2 * 4 + 1]; - b[3] = src[w2 + px2 * 4 + 2]; + if(FILTERING) + { + r[1] = src[w + px2 * 4 + 0]; + g[1] = src[w + px2 * 4 + 1]; + b[1] = src[w + px2 * 4 + 2]; + r[2] = src[w2 + px * 4 + 0]; + g[2] = src[w2 + px * 4 + 1]; + b[2] = src[w2 + px * 4 + 2]; + r[3] = src[w2 + px2 * 4 + 0]; + g[3] = src[w2 + px2 * 4 + 1]; + b[3] = src[w2 + px2 * 4 + 2]; + } } else { r[0] = src[w + px]; - r[2] = src[w2 + px]; - r[1] = src[w + px2]; - r[3] = src[w2 + px2]; + if(FILTERING) + { + r[2] = src[w2 + px]; + r[1] = src[w + px2]; + r[3] = src[w2 + px2]; + } } uint32_t rgb = 0xff000000; - if(rawImage->channels() > 1) + if(FILTERING) { - rgb |= (uint8_t)(mtf(0, ((r[3] * fx + r[2] * (1.0f - fx)) * fy + (r[1] * fx + r[0] * (1.0f - fx)) * (1.0f - fy)) / s) * 255.0f) << 16; - rgb |= (uint8_t)(mtf(1, ((g[3] * fx + g[2] * (1.0f - fx)) * fy + (g[1] * fx + g[0] * (1.0f - fx)) * (1.0f - fy)) / s) * 255.0f) << 8; - rgb |= (uint8_t)(mtf(1, ((b[3] * fx + b[2] * (1.0f - fx)) * fy + (b[1] * fx + b[0] * (1.0f - fx)) * (1.0f - fy)) / s) * 255.0f); + if(rawImage->channels() > 1) + { + rgb |= (uint8_t)(mtf(0, ((r[3] * fx + r[2] * (1.0f - fx)) * fy + (r[1] * fx + r[0] * (1.0f - fx)) * (1.0f - fy)) / s) * 255.0f) << 16; + rgb |= (uint8_t)(mtf(1, ((g[3] * fx + g[2] * (1.0f - fx)) * fy + (g[1] * fx + g[0] * (1.0f - fx)) * (1.0f - fy)) / s) * 255.0f) << 8; + rgb |= (uint8_t)(mtf(1, ((b[3] * fx + b[2] * (1.0f - fx)) * fy + (b[1] * fx + b[0] * (1.0f - fx)) * (1.0f - fy)) / s) * 255.0f); + } + else + { + uint32_t v = (uint8_t)(mtf(0, ((r[3] * fx + r[2] * (1.0f - fx)) * fy + (r[1] * fx + r[0] * (1.0f - fx)) * (1.0f - fy)) / s) * 255.0f); + rgb = 0xff000000 | (v << 16) | (v << 8) | v; + } } else { - uint32_t v = (uint8_t)(mtf(0, ((r[3] * fx + r[2] * (1.0f - fx)) * fy + (r[1] * fx + r[0] * (1.0f - fx)) * (1.0f - fy)) / s) * 255.0f); - rgb = 0xff000000 | (v << 16) | (v << 8) | v; + if(rawImage->channels() > 1) + { + rgb |= (uint8_t)(mtf(0, r[0] / s) * 255.0f) << 16; + rgb |= (uint8_t)(mtf(1, g[0] / s) * 255.0f) << 8; + rgb |= (uint8_t)(mtf(1, b[0] / s) * 255.0f); + } + else + { + uint32_t v = (uint8_t)(mtf(0, r[0] / s) * 255.0f); + rgb = 0xff000000 | (v << 16) | (v << 8) | v; + } } pixels[x] = rgb; }