Fix rounding error in fetchTransformedBilinear
To calculate the real count we need to use the actual fixed point increment and can not use the floating point value increment wass based on since it might round differently. Includes auto-test by Gabriel de Dietrich. Task-number: QTBUG-50153 Change-Id: Ia973088f361c90370fa20bac14a4b8f373b5d234 Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com> Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>bb10
parent
72b57a5dfa
commit
6ec7d7658d
|
|
@ -1938,9 +1938,10 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
|
|||
|
||||
// intermediate_buffer[0] is a buffer of red-blue component of the pixel, in the form 0x00RR00BB
|
||||
// intermediate_buffer[1] is the alpha-green component of the pixel, in the form 0x00AA00GG
|
||||
// +1 for the last pixel to interpolate with, and +1 for rounding errors.
|
||||
quint32 intermediate_buffer[2][buffer_size + 2];
|
||||
// count is the size used in the intermediate_buffer.
|
||||
int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors.
|
||||
int count = (qint64(length) * fdx + fixed_scale - 1) / fixed_scale + 2;
|
||||
Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
|
||||
int f = 0;
|
||||
int lim = count;
|
||||
|
|
@ -2448,12 +2449,13 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
|
|||
// The idea is first to do the interpolation between the row s1 and the row s2
|
||||
// into an intermediate buffer, then we interpolate between two pixel of this buffer.
|
||||
FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
|
||||
// +1 for the last pixel to interpolate with, and +1 for rounding errors.
|
||||
uint buf1[buffer_size + 2];
|
||||
uint buf2[buffer_size + 2];
|
||||
const uint *ptr1;
|
||||
const uint *ptr2;
|
||||
|
||||
int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors.
|
||||
int count = (qint64(length) * fdx + fixed_scale - 1) / fixed_scale + 2;
|
||||
Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
|
||||
|
||||
if (blendType == BlendTransformedBilinearTiled) {
|
||||
|
|
|
|||
|
|
@ -305,6 +305,8 @@ private slots:
|
|||
void drawPolyline_data();
|
||||
void drawPolyline();
|
||||
|
||||
void QTBUG50153_drawImage_assert();
|
||||
|
||||
private:
|
||||
void fillData();
|
||||
void setPenColor(QPainter& p);
|
||||
|
|
@ -5052,6 +5054,30 @@ void tst_QPainter::drawPolyline()
|
|||
QCOMPARE(images[0], images[1]);
|
||||
}
|
||||
|
||||
void tst_QPainter::QTBUG50153_drawImage_assert()
|
||||
{
|
||||
QImage::Format formats[] = {
|
||||
QImage::Format_RGB32, // fetchTransformedBilinearARGB32PM
|
||||
QImage::Format_ARGB32 // fetchTransformedBilinear
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
|
||||
QImage image(3027, 2999, formats[i]);
|
||||
|
||||
QImage backingStore(image.size(), QImage::Format_ARGB32);
|
||||
QPainter backingStorePainter(&backingStore);
|
||||
|
||||
QTransform transform;
|
||||
transform.scale( 0.999987, 0.999987 );
|
||||
|
||||
backingStorePainter.setTransform(transform);
|
||||
backingStorePainter.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
||||
backingStorePainter.drawImage(0, 0, image);
|
||||
|
||||
// No crash, all fine
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QPainter)
|
||||
|
||||
#include "tst_qpainter.moc"
|
||||
|
|
|
|||
Loading…
Reference in New Issue