QPixmap::load: ensure QBitmap stays a QBitmap even on failure
... and avoid detach()ing potentially large data for just preserving the QPlatformPixmap::pixelType(). A QBitmap differs from a QPixmap (its base class, urgh) by always having a data != nullptr and a Bitmap pixel type, yet load() was unconditionally setting 'data' to nullptr on failure, turning a QBitmap into a non-QBitmap. Fix by move-assigning a null QBitmap instead of resetting 'data'. Add some tests. Change-Id: Ida58b3b24d96472a5f9d0f18f81cc763edcf3c16 Reviewed-by: Anton Kudryavtsev <a.kudryavtsev@netris.ru> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
parent
237b36a72c
commit
f9acbaccde
@ -762,39 +762,37 @@ QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode)
|
|||||||
|
|
||||||
bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
|
bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
|
||||||
{
|
{
|
||||||
if (fileName.isEmpty()) {
|
if (!fileName.isEmpty()) {
|
||||||
data.reset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
detach();
|
|
||||||
|
|
||||||
QFileInfo info(fileName);
|
QFileInfo info(fileName);
|
||||||
|
// Note: If no extension is provided, we try to match the
|
||||||
|
// file against known plugin extensions
|
||||||
|
if (info.completeSuffix().isEmpty() || info.exists()) {
|
||||||
|
|
||||||
QString key = QLatin1String("qt_pixmap")
|
QString key = QLatin1String("qt_pixmap")
|
||||||
% info.absoluteFilePath()
|
% info.absoluteFilePath()
|
||||||
% HexString<uint>(info.lastModified().toTime_t())
|
% HexString<uint>(info.lastModified().toTime_t())
|
||||||
% HexString<quint64>(info.size())
|
% HexString<quint64>(info.size())
|
||||||
% HexString<uint>(data ? data->pixelType() : QPlatformPixmap::PixmapType);
|
% HexString<uint>(data ? data->pixelType() : QPlatformPixmap::PixmapType);
|
||||||
|
|
||||||
// Note: If no extension is provided, we try to match the
|
|
||||||
// file against known plugin extensions
|
|
||||||
if (!info.completeSuffix().isEmpty() && !info.exists()) {
|
|
||||||
data.reset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (QPixmapCache::find(key, this))
|
if (QPixmapCache::find(key, this))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!data)
|
data = QPlatformPixmap::create(0, 0, data ? data->pixelType() : QPlatformPixmap::PixmapType);
|
||||||
data = QPlatformPixmap::create(0, 0, QPlatformPixmap::PixmapType);
|
|
||||||
|
|
||||||
if (data->fromFile(fileName, format, flags)) {
|
if (data->fromFile(fileName, format, flags)) {
|
||||||
QPixmapCache::insert(key, *this);
|
QPixmapCache::insert(key, *this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNull()) {
|
||||||
|
if (isQBitmap())
|
||||||
|
*this = QBitmap();
|
||||||
|
else
|
||||||
data.reset();
|
data.reset();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1508,6 +1508,33 @@ void tst_QPixmap::loadAsBitmapOrPixmap()
|
|||||||
QVERIFY(!bitmap.isNull());
|
QVERIFY(!bitmap.isNull());
|
||||||
QCOMPARE(bitmap.depth(), 1);
|
QCOMPARE(bitmap.depth(), 1);
|
||||||
QVERIFY(bitmap.isQBitmap());
|
QVERIFY(bitmap.isQBitmap());
|
||||||
|
|
||||||
|
// check that a QBitmap stays a QBitmap even when loading fails:
|
||||||
|
ok = bitmap.load(QString());
|
||||||
|
QVERIFY(!ok);
|
||||||
|
QVERIFY(bitmap.isNull());
|
||||||
|
QVERIFY(bitmap.isQBitmap());
|
||||||
|
|
||||||
|
ok = bitmap.load("does not exist");
|
||||||
|
QVERIFY(!ok);
|
||||||
|
QVERIFY(bitmap.isNull());
|
||||||
|
QVERIFY(bitmap.isQBitmap());
|
||||||
|
|
||||||
|
ok = bitmap.load("does not exist.png");
|
||||||
|
QVERIFY(!ok);
|
||||||
|
QVERIFY(bitmap.isNull());
|
||||||
|
QVERIFY(bitmap.isQBitmap());
|
||||||
|
|
||||||
|
QTemporaryFile garbage;
|
||||||
|
QVERIFY(garbage.open());
|
||||||
|
const QString garbagePath = garbage.fileName();
|
||||||
|
garbage.write(reinterpret_cast<const char *>(&garbage), sizeof garbage);
|
||||||
|
garbage.close();
|
||||||
|
|
||||||
|
ok = bitmap.load(garbagePath);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
QVERIFY(bitmap.isNull());
|
||||||
|
QVERIFY(bitmap.isQBitmap());
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QPixmap::toImageDeepCopy()
|
void tst_QPixmap::toImageDeepCopy()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user