Fix another crash when converting format of buffer-created QImage
This continues 68762151db
When doing format conversion, the optimized inplace codepath did not
check if the image data was external, i.e. if the QImage had been
created by the constructor taking an existing external buffer.
The previous commit fixed the readonly case. But in the case of the
QImage constructor taking non-const uchar*, data will be read-write,
but still external. This would of course crash if the converter tries
to realloc it.
Task-number: QTBUG-44610
Change-Id: I94d275d464e8af221682b538fc3e4897a59c061e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
This commit is contained in:
parent
227bb20ded
commit
509bc7e59c
@ -716,6 +716,8 @@ static bool convert_BGR30_to_RGB30_inplace(QImageData *data, Qt::ImageConversion
|
||||
static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
|
||||
{
|
||||
Q_ASSERT(data->format == QImage::Format_Indexed8);
|
||||
if (!data->own_data)
|
||||
return false;
|
||||
const int depth = 32;
|
||||
|
||||
const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
|
||||
@ -768,6 +770,8 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve
|
||||
static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags)
|
||||
{
|
||||
Q_ASSERT(data->format == QImage::Format_Indexed8);
|
||||
if (!data->own_data)
|
||||
return false;
|
||||
const int depth = 32;
|
||||
|
||||
const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
|
||||
@ -817,6 +821,8 @@ static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversio
|
||||
static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
|
||||
{
|
||||
Q_ASSERT(data->format == QImage::Format_Indexed8);
|
||||
if (!data->own_data)
|
||||
return false;
|
||||
const int depth = 16;
|
||||
|
||||
const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
|
||||
@ -872,6 +878,8 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers
|
||||
static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
|
||||
{
|
||||
Q_ASSERT(data->format == QImage::Format_RGB32);
|
||||
if (!data->own_data)
|
||||
return false;
|
||||
const int depth = 16;
|
||||
|
||||
const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
|
||||
|
@ -2456,6 +2456,7 @@ void tst_QImage::inplaceConversion_data()
|
||||
QTest::addColumn<QImage::Format>("format");
|
||||
QTest::addColumn<QImage::Format>("dest_format");
|
||||
|
||||
QTest::newRow("Format_RGB32 -> RGB16") << QImage::Format_RGB32 << QImage::Format_RGB16;
|
||||
QTest::newRow("Format_ARGB32 -> Format_RGBA8888") << QImage::Format_ARGB32 << QImage::Format_RGBA8888;
|
||||
QTest::newRow("Format_RGB888 -> Format_ARGB6666_Premultiplied") << QImage::Format_RGB888 << QImage::Format_ARGB6666_Premultiplied;
|
||||
QTest::newRow("Format_RGB16 -> Format_RGB555") << QImage::Format_RGB16 << QImage::Format_RGB555;
|
||||
@ -2494,16 +2495,21 @@ void tst_QImage::inplaceConversion()
|
||||
QCOMPARE(imageConverted.constScanLine(0), originalPtr);
|
||||
|
||||
{
|
||||
// Test attempted inplace conversion of images created on existing, readonly buffer
|
||||
// Test attempted inplace conversion of images created on existing buffer
|
||||
static const quint32 readOnlyData[] = { 0x00010203U, 0x04050607U, 0x08091011U, 0x12131415U };
|
||||
quint32 readWriteData[] = { 0x00010203U, 0x04050607U, 0x08091011U, 0x12131415U };
|
||||
|
||||
QImage roImage((const uchar *)readOnlyData, 2, 2, format);
|
||||
QImage inplaceConverted = std::move(roImage).convertToFormat(dest_format);
|
||||
QImage roInplaceConverted = std::move(roImage).convertToFormat(dest_format);
|
||||
|
||||
QImage rwImage((uchar *)readWriteData, 2, 2, format);
|
||||
QImage rwInplaceConverted = std::move(rwImage).convertToFormat(dest_format);
|
||||
|
||||
QImage roImage2((const uchar *)readOnlyData, 2, 2, format);
|
||||
QImage normalConverted = roImage2.convertToFormat(dest_format);
|
||||
|
||||
QCOMPARE(normalConverted, inplaceConverted);
|
||||
QCOMPARE(normalConverted, roInplaceConverted);
|
||||
QCOMPARE(normalConverted, rwInplaceConverted);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user