summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.0.05
-rw-r--r--src/gui/image/qimage.cpp29
-rw-r--r--src/gui/image/qpicture.cpp22
-rw-r--r--src/gui/image/qpixmap.cpp34
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp85
-rw-r--r--tests/auto/gui/image/qpixmap/tst_qpixmap.cpp85
6 files changed, 217 insertions, 43 deletions
diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0
index a56325d40a..f2164087eb 100644
--- a/dist/changes-5.0.0
+++ b/dist/changes-5.0.0
@@ -494,6 +494,11 @@ QtGui
For consistency with RGB32 and other 32-bit formats, function now expects
image data in RGB layout as opposed to BGR layout.
+* Behavioral change in QImage and QPixmap load()/loadFromData() on a non-null image:
+ If load() or loadFromData() fails to load the image (returns false) then
+ the existent image data will be invalidated, so that isNull() is guaranteed
+ to return true in this case.
+
QtWidgets
---------
* QInputContext removed as well as related getters and setters on QWidget and QApplication.
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index bf12dac41d..25999b7d06 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -4346,7 +4346,8 @@ QImage QImage::rgbSwapped() const
/*!
Loads an image from the file with the given \a fileName. Returns true if
- the image was successfully loaded; otherwise returns false.
+ the image was successfully loaded; otherwise invalidates the image
+ and returns false.
The loader attempts to read the image using the specified \a format, e.g.,
PNG or JPG. If \a format is not specified (which is the default), the
@@ -4363,15 +4364,9 @@ QImage QImage::rgbSwapped() const
bool QImage::load(const QString &fileName, const char* format)
{
- if (fileName.isEmpty())
- return false;
-
QImage image = QImageReader(fileName, format).read();
- if (!image.isNull()) {
- operator=(image);
- return true;
- }
- return false;
+ operator=(image);
+ return !isNull();
}
/*!
@@ -4384,11 +4379,8 @@ bool QImage::load(const QString &fileName, const char* format)
bool QImage::load(QIODevice* device, const char* format)
{
QImage image = QImageReader(device, format).read();
- if(!image.isNull()) {
- operator=(image);
- return true;
- }
- return false;
+ operator=(image);
+ return !isNull();
}
/*!
@@ -4396,7 +4388,7 @@ bool QImage::load(QIODevice* device, const char* format)
Loads an image from the first \a len bytes of the given binary \a
data. Returns true if the image was successfully loaded; otherwise
- returns false.
+ invalidates the image and returns false.
The loader attempts to read the image using the specified \a format, e.g.,
PNG or JPG. If \a format is not specified (which is the default), the
@@ -4408,11 +4400,8 @@ bool QImage::load(QIODevice* device, const char* format)
bool QImage::loadFromData(const uchar *data, int len, const char *format)
{
QImage image = fromData(data, len, format);
- if (!image.isNull()) {
- operator=(image);
- return true;
- }
- return false;
+ operator=(image);
+ return !isNull();
}
/*!
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index 464e31a3e2..f75c6e40df 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -246,7 +246,7 @@ void QPicture::setData(const char* data, uint size)
/*!
Loads a picture from the file specified by \a fileName and returns
- true if successful; otherwise returns false.
+ true if successful; otherwise invalidates the picture and returns false.
Please note that the \a format parameter has been deprecated and
will have no effect.
@@ -257,8 +257,10 @@ void QPicture::setData(const char* data, uint size)
bool QPicture::load(const QString &fileName, const char *format)
{
QFile f(fileName);
- if (!f.open(QIODevice::ReadOnly))
+ if (!f.open(QIODevice::ReadOnly)) {
+ operator=(QPicture());
return false;
+ }
return load(&f, format);
}
@@ -273,18 +275,14 @@ bool QPicture::load(QIODevice *dev, const char *format)
if(format) {
#ifndef QT_NO_PICTUREIO
QPictureIO io(dev, format);
- bool result = io.read();
- if (result) {
+ if (io.read()) {
operator=(io.picture());
-
- } else if (format)
-#else
- bool result = false;
-#endif
- {
- qWarning("QPicture::load: No such picture format: %s", format);
+ return true;
}
- return result;
+#endif
+ qWarning("QPicture::load: No such picture format: %s", format);
+ operator=(QPicture());
+ return false;
}
detach();
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 19497af391..113369fd75 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -684,8 +684,8 @@ QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode)
/*!
Loads a pixmap from the file with the given \a fileName. Returns
- true if the pixmap was successfully loaded; otherwise returns
- false.
+ true if the pixmap was successfully loaded; otherwise invalidates
+ the pixmap and returns false.
The loader attempts to read the pixmap using the specified \a
format. If the \a format is not specified (which is the default),
@@ -711,8 +711,10 @@ QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode)
bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
{
- if (fileName.isEmpty())
+ if (fileName.isEmpty()) {
+ data.reset();
return false;
+ }
QFileInfo info(fileName);
QString key = QLatin1String("qt_pixmap")
@@ -723,19 +725,23 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
// Note: If no extension is provided, we try to match the
// file against known plugin extensions
- if (!info.completeSuffix().isEmpty() && !info.exists())
+ if (!info.completeSuffix().isEmpty() && !info.exists()) {
+ data.reset();
return false;
+ }
- if (QPixmapCache::find(key, *this))
+ if (QPixmapCache::find(key, this))
return true;
- QScopedPointer<QPlatformPixmap> tmp(QPlatformPixmap::create(0, 0, data ? data->type : QPlatformPixmap::PixmapType));
- if (tmp->fromFile(fileName, format, flags)) {
- data = tmp.take();
+ 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;
}
@@ -744,7 +750,7 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
Loads a pixmap from the \a len first bytes of the given binary \a
data. Returns true if the pixmap was loaded successfully;
- otherwise returns false.
+ otherwise invalidates the pixmap and returns false.
The loader attempts to read the pixmap using the specified \a
format. If the \a format is not specified (which is the default),
@@ -760,13 +766,19 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
{
- if (len == 0 || buf == 0)
+ if (len == 0 || buf == 0) {
+ data.reset();
return false;
+ }
if (!data)
data = QPlatformPixmap::create(0, 0, QPlatformPixmap::PixmapType);
- return data->fromData(buf, len, format, flags);
+ if (data->fromData(buf, len, format, flags))
+ return true;
+
+ data.reset();
+ return false;
}
/*!
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index cf1727a106..1b0dbf754b 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -95,6 +95,12 @@ private slots:
void copy();
+ void load();
+ void loadFromData();
+#if !defined(QT_NO_DATASTREAM)
+ void loadFromDataStream();
+#endif
+
void setPixel_data();
void setPixel();
@@ -1006,6 +1012,85 @@ void tst_QImage::copy()
}
}
+void tst_QImage::load()
+{
+ const QString prefix = QFINDTESTDATA("images/");
+ if (prefix.isEmpty())
+ QFAIL("can not find images directory!");
+ const QString filePath = prefix + QLatin1String("image.jpg");
+
+ QImage dest(filePath);
+ QVERIFY(!dest.isNull());
+ QVERIFY(!dest.load("image_that_does_not_exist.png"));
+ QVERIFY(dest.isNull());
+ QVERIFY(dest.load(filePath));
+ QVERIFY(!dest.isNull());
+}
+
+void tst_QImage::loadFromData()
+{
+ const QString prefix = QFINDTESTDATA("images/");
+ if (prefix.isEmpty())
+ QFAIL("can not find images directory!");
+ const QString filePath = prefix + QLatin1String("image.jpg");
+
+ QImage original(filePath);
+ QVERIFY(!original.isNull());
+
+ QByteArray ba;
+ {
+ QBuffer buf(&ba);
+ QVERIFY(buf.open(QIODevice::WriteOnly));
+ QVERIFY(original.save(&buf, "BMP"));
+ }
+ QVERIFY(!ba.isEmpty());
+
+ QImage dest;
+ QVERIFY(dest.loadFromData(ba, "BMP"));
+ QVERIFY(!dest.isNull());
+
+ QCOMPARE(original, dest);
+
+ QVERIFY(!dest.loadFromData(QByteArray()));
+ QVERIFY(dest.isNull());
+}
+
+#if !defined(QT_NO_DATASTREAM)
+void tst_QImage::loadFromDataStream()
+{
+ const QString prefix = QFINDTESTDATA("images/");
+ if (prefix.isEmpty())
+ QFAIL("can not find images directory!");
+ const QString filePath = prefix + QLatin1String("image.jpg");
+
+ QImage original(filePath);
+ QVERIFY(!original.isNull());
+
+ QByteArray ba;
+ {
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ s << original;
+ }
+ QVERIFY(!ba.isEmpty());
+
+ QImage dest;
+ {
+ QDataStream s(&ba, QIODevice::ReadOnly);
+ s >> dest;
+ }
+ QVERIFY(!dest.isNull());
+
+ QCOMPARE(original, dest);
+
+ {
+ ba.clear();
+ QDataStream s(&ba, QIODevice::ReadOnly);
+ s >> dest;
+ }
+ QVERIFY(dest.isNull());
+}
+#endif // QT_NO_DATASTREAM
+
void tst_QImage::setPixel_data()
{
QTest::addColumn<int>("format");
diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
index ee6b78397a..dd6d97043d 100644
--- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
+++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
@@ -139,6 +139,12 @@ private slots:
void fromImage_crash();
+ void load();
+ void loadFromData();
+#if !defined(QT_NO_DATASTREAM)
+ void loadFromDataStream();
+#endif
+
void fromData();
void loadFromDataNullValues();
@@ -1191,6 +1197,85 @@ void tst_QPixmap::transformed2()
QVERIFY(lenientCompare(actual, expected));
}
+void tst_QPixmap::load()
+{
+ const QString prefix = QFINDTESTDATA("images/");
+ if (prefix.isEmpty())
+ QFAIL("can not find images directory!");
+ const QString filePath = prefix + QLatin1String("designer.png");
+
+ QPixmap dest(filePath);
+ QVERIFY(!dest.isNull());
+ QVERIFY(!dest.load("image_that_does_not_exist.png"));
+ QVERIFY(dest.isNull());
+ QVERIFY(dest.load(filePath));
+ QVERIFY(!dest.isNull());
+}
+
+void tst_QPixmap::loadFromData()
+{
+ const QString prefix = QFINDTESTDATA("images/");
+ if (prefix.isEmpty())
+ QFAIL("can not find images directory!");
+ const QString filePath = prefix + QLatin1String("designer.png");
+
+ QPixmap original(filePath);
+ QVERIFY(!original.isNull());
+
+ QByteArray ba;
+ {
+ QBuffer buf(&ba);
+ QVERIFY(buf.open(QIODevice::WriteOnly));
+ QVERIFY(original.save(&buf, "BMP"));
+ }
+ QVERIFY(!ba.isEmpty());
+
+ QPixmap dest;
+ QVERIFY(dest.loadFromData(ba, "BMP"));
+ QVERIFY(!dest.isNull());
+
+ QCOMPARE(original, dest);
+
+ QVERIFY(!dest.loadFromData(QByteArray()));
+ QVERIFY(dest.isNull());
+}
+
+#if !defined(QT_NO_DATASTREAM)
+void tst_QPixmap::loadFromDataStream()
+{
+ const QString prefix = QFINDTESTDATA("images/");
+ if (prefix.isEmpty())
+ QFAIL("can not find images directory!");
+ const QString filePath = prefix + QLatin1String("designer.png");
+
+ QPixmap original(filePath);
+ QVERIFY(!original.isNull());
+
+ QByteArray ba;
+ {
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ s << original;
+ }
+ QVERIFY(!ba.isEmpty());
+
+ QPixmap dest;
+ {
+ QDataStream s(&ba, QIODevice::ReadOnly);
+ s >> dest;
+ }
+ QVERIFY(!dest.isNull());
+
+ QCOMPARE(original, dest);
+
+ {
+ ba.clear();
+ QDataStream s(&ba, QIODevice::ReadOnly);
+ s >> dest;
+ }
+ QVERIFY(dest.isNull());
+}
+#endif // QT_NO_DATASTREAM
+
void tst_QPixmap::fromImage_crash()
{
QImage *img = new QImage(64, 64, QImage::Format_ARGB32_Premultiplied);