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)
|
||||
{
|
||||
if (fileName.isEmpty()) {
|
||||
data.reset();
|
||||
return false;
|
||||
if (!fileName.isEmpty()) {
|
||||
|
||||
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")
|
||||
% info.absoluteFilePath()
|
||||
% HexString<uint>(info.lastModified().toTime_t())
|
||||
% HexString<quint64>(info.size())
|
||||
% HexString<uint>(data ? data->pixelType() : QPlatformPixmap::PixmapType);
|
||||
|
||||
if (QPixmapCache::find(key, this))
|
||||
return true;
|
||||
|
||||
data = QPlatformPixmap::create(0, 0, data ? data->pixelType() : QPlatformPixmap::PixmapType);
|
||||
|
||||
if (data->fromFile(fileName, format, flags)) {
|
||||
QPixmapCache::insert(key, *this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
detach();
|
||||
|
||||
QFileInfo info(fileName);
|
||||
QString key = QLatin1String("qt_pixmap")
|
||||
% info.absoluteFilePath()
|
||||
% HexString<uint>(info.lastModified().toTime_t())
|
||||
% HexString<quint64>(info.size())
|
||||
% 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 (!isNull()) {
|
||||
if (isQBitmap())
|
||||
*this = QBitmap();
|
||||
else
|
||||
data.reset();
|
||||
}
|
||||
|
||||
if (QPixmapCache::find(key, this))
|
||||
return true;
|
||||
|
||||
if (!data)
|
||||
data = QPlatformPixmap::create(0, 0, QPlatformPixmap::PixmapType);
|
||||
|
||||
if (data->fromFile(fileName, format, flags)) {
|
||||
QPixmapCache::insert(key, *this);
|
||||
return true;
|
||||
}
|
||||
|
||||
data.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1508,6 +1508,33 @@ void tst_QPixmap::loadAsBitmapOrPixmap()
|
||||
QVERIFY(!bitmap.isNull());
|
||||
QCOMPARE(bitmap.depth(), 1);
|
||||
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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user