Fix half pixel offset and add filtering in sw rendering

Signed-off-by: Dušan Poizl <nou.spiro@gmail.com>
This commit is contained in:
2024-12-05 16:02:46 +01:00
parent be1e65251d
commit 45ee9b7258
+44 -21
View File
@@ -352,7 +352,7 @@ void swPaint(std::shared_ptr<RawImage> &rawImage, float dx, float dy, float scal
int width = widget->width(); int width = widget->width();
int height = widget->height(); int height = widget->height();
QImage img(width, height, QImage::Format_RGB32); QImage img(width, height, QImage::Format_RGB32);
img.fill(Qt::gray); img.fill(Qt::darkGray);
int64_t ox = dx; int64_t ox = dx;
int64_t oy = dy; int64_t oy = dy;
@@ -380,7 +380,7 @@ void swPaint(std::shared_ptr<RawImage> &rawImage, float dx, float dy, float scal
{ {
uint32_t *pixels = (uint32_t*)(img.scanLine(y)); uint32_t *pixels = (uint32_t*)(img.scanLine(y));
float iptr; 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 py = iptr;
int64_t w = py * rawImage->widthBytes(); int64_t w = py * rawImage->widthBytes();
int64_t w2 = w; int64_t w2 = w;
@@ -389,7 +389,7 @@ void swPaint(std::shared_ptr<RawImage> &rawImage, float dx, float dy, float scal
for(int64_t x = std::max((int64_t)0, -ox); x < width; x++) 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 px = iptr;
int px2 = px + 1 < imgWidth ? px + 1 : px; int px2 = px + 1 < imgWidth ? px + 1 : px;
if(px >= imgWidth)break; if(px >= imgWidth)break;
@@ -400,35 +400,58 @@ void swPaint(std::shared_ptr<RawImage> &rawImage, float dx, float dy, float scal
r[0] = src[w + px * 4 + 0]; r[0] = src[w + px * 4 + 0];
g[0] = src[w + px * 4 + 1]; g[0] = src[w + px * 4 + 1];
b[0] = src[w + px * 4 + 2]; b[0] = src[w + px * 4 + 2];
r[1] = src[w + px2 * 4 + 0]; if(FILTERING)
g[1] = src[w + px2 * 4 + 1]; {
b[1] = src[w + px2 * 4 + 2]; r[1] = src[w + px2 * 4 + 0];
r[2] = src[w2 + px * 4 + 0]; g[1] = src[w + px2 * 4 + 1];
g[2] = src[w2 + px * 4 + 1]; b[1] = src[w + px2 * 4 + 2];
b[2] = src[w2 + px * 4 + 2]; r[2] = src[w2 + px * 4 + 0];
r[3] = src[w2 + px2 * 4 + 0]; g[2] = src[w2 + px * 4 + 1];
g[3] = src[w2 + px2 * 4 + 1]; b[2] = src[w2 + px * 4 + 2];
b[3] = src[w2 + px2 * 4 + 2]; r[3] = src[w2 + px2 * 4 + 0];
g[3] = src[w2 + px2 * 4 + 1];
b[3] = src[w2 + px2 * 4 + 2];
}
} }
else else
{ {
r[0] = src[w + px]; r[0] = src[w + px];
r[2] = src[w2 + px]; if(FILTERING)
r[1] = src[w + px2]; {
r[3] = src[w2 + px2]; r[2] = src[w2 + px];
r[1] = src[w + px2];
r[3] = src[w2 + px2];
}
} }
uint32_t rgb = 0xff000000; 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; if(rawImage->channels() > 1)
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); 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 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); if(rawImage->channels() > 1)
rgb = 0xff000000 | (v << 16) | (v << 8) | v; {
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; pixels[x] = rgb;
} }