Details
-
Bug
-
Resolution: Done
-
P2: Important
-
4.6.3, 5.4.0 Alpha
-
None
-
Linux/X11, amd64, Qt Open Source Edition
Seems to be independent of the graphicssystem, tested with -graphicssystem native, -graphicssystem native and -graphicssystem opengl (added QApplication to the test program)
Description
Scaling or painting scaled versions of large QImages (width or height greater than 1<<15) produces unexpected behavior. This can be seen with wide panoramic images in an image viewer such as KDE's Gwenview, but can also be demonstrated by a simple program (expects a test.jpg - an image file with sufficiently large height or width, such as the attached one):
#include <QImage>
#include <QApplication>
int main(int argc, char** argv) {
QApplication app(argc, argv);
QImage img("test.jpg");
int w = 1500;
int h = 1500*img.height()/img.width();
img.scaled(w,h,Qt::IgnoreAspectRatio,Qt::FastTransformation).save("scaled_fast.jpg");
img.scaled(w,h,Qt::IgnoreAspectRatio,Qt::SmoothTransformation).save("scaled_smooth.jpg");
return 0;
}
When using Qt::FastTransformation, the right/bottom part of the scaled down image (where the position in the source image does not fit into 15 bits) will be a copy of somewhere else in the image. This is due to the srcx/srcy variables in the qt_scale_image_??bit functions in src/gui/painting/qblendfunctions.cpp overflowing into the sign bit. These variables contain the x/y coordinates of the sample points, shifted 16 bits to the left to maintain sub-pixel accuracy. Besides the sign bit, this leaves only 15 Bits to store the whole pixel coordinates.
Using Qt::SmoothTransformation results in the first column (row) of pixels being repeated for the whole width (height) of the result image. The bug is analogous to the fast transformation, but with the val and inc variables in the QImageScale::qimageCalc?Points functions in src/gui/painting/qimagescale.cpp.
Both cases can be fixed by using 64-bit integer types for the affected variables.