summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-04-24 16:04:14 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-04-28 12:42:12 +0000
commitf15d6c3fa910d5200e245fe15ae9932f4b4eca78 (patch)
tree9f2d7352f2b2cb3779ffd2110aa0b9cf308adcb9
parent1576f62eaf962aaaaba83337284d23c732bfb52b (diff)
Preserve QImage metadata in image transforms
Some QImage methods were not preserving image metadata, or only preserving some of it. This adds the missing parts and adds a test for metadata. Change-Id: Ib5892a23e49dfde5ea26074d3deaa887fa930c6b Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
-rw-r--r--src/gui/image/qimage.cpp58
-rw-r--r--src/gui/image/qimage.h1
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp36
3 files changed, 64 insertions, 31 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index f09e73f214..7b558bf4dd 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -1087,6 +1087,15 @@ void QImage::detach()
}
+static void copyMetadata(QImageData *dst, const QImageData *src)
+{
+ // Doesn't copy colortable and alpha_clut, or offset.
+ dst->dpmx = src->dpmx;
+ dst->dpmy = src->dpmy;
+ dst->devicePixelRatio = src->devicePixelRatio;
+ dst->text = src->text;
+}
+
/*!
\fn QImage QImage::copy(int x, int y, int width, int height) const
\overload
@@ -1136,12 +1145,9 @@ QImage QImage::copy(const QRect& r) const
} else
memcpy(image.bits(), bits(), d->nbytes);
image.d->colortable = d->colortable;
- image.d->dpmx = d->dpmx;
- image.d->dpmy = d->dpmy;
- image.d->devicePixelRatio = d->devicePixelRatio;
image.d->offset = d->offset;
image.d->has_alpha_clut = d->has_alpha_clut;
- image.d->text = d->text;
+ copyMetadata(image.d, d);
return image;
}
@@ -1227,12 +1233,9 @@ QImage QImage::copy(const QRect& r) const
}
}
- image.d->dpmx = dotsPerMeterX();
- image.d->dpmy = dotsPerMeterY();
- image.d->devicePixelRatio = devicePixelRatio();
+ copyMetadata(image.d, d);
image.d->offset = offset();
image.d->has_alpha_clut = d->has_alpha_clut;
- image.d->text = d->text;
return image;
}
@@ -1983,11 +1986,8 @@ QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags fl
QIMAGE_SANITYCHECK_MEMORY(image);
- image.setDotsPerMeterY(dotsPerMeterY());
- image.setDotsPerMeterX(dotsPerMeterX());
- image.setDevicePixelRatio(devicePixelRatio());
-
- image.d->text = d->text;
+ image.d->offset = offset();
+ copyMetadata(image.d, d);
converter(image.d, d, flags);
return image;
@@ -2112,9 +2112,9 @@ QImage QImage::convertToFormat(Format format, const QVector<QRgb> &colorTable, Q
QImage image(d->width, d->height, format);
QIMAGE_SANITYCHECK_MEMORY(image);
- image.setDevicePixelRatio(devicePixelRatio());
- image.d->text = d->text;
+ image.d->offset = offset();
+ copyMetadata(image.d, d);
converter(image.d, d, flags);
return image;
@@ -2952,9 +2952,7 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
result.d->colortable = d->colortable;
result.d->has_alpha_clut = d->has_alpha_clut;
- result.d->devicePixelRatio = d->devicePixelRatio;
- result.d->dpmx = d->dpmx;
- result.d->dpmy = d->dpmy;
+ copyMetadata(result.d, d);
do_mirror(result.d, d, horizontal, vertical);
@@ -3103,6 +3101,7 @@ QImage QImage::rgbSwapped_helper() const
rgbSwapped_generic(d->width, d->height, this, &res, &qPixelLayouts[d->format]);
break;
}
+ copyMetadata(res.d, d);
return res;
}
@@ -4254,8 +4253,8 @@ int QImage::bitPlaneCount() const
return bpc;
}
-static QImage smoothScaled(const QImage &source, int w, int h) {
- QImage src = source;
+QImage QImage::smoothScaled(int w, int h) const {
+ QImage src = *this;
switch (src.format()) {
case QImage::Format_RGB32:
case QImage::Format_ARGB32_Premultiplied:
@@ -4270,11 +4269,11 @@ static QImage smoothScaled(const QImage &source, int w, int h) {
else
src = src.convertToFormat(QImage::Format_RGB32);
}
-
- return qSmoothScaleImage(src, w, h);
+ src = qSmoothScaleImage(src, w, h);
+ copyMetadata(src.d, d);
+ return src;
}
-
static QImage rotated90(const QImage &image) {
QImage out(image.height(), image.width(), image.format());
if (image.colorCount() > 0)
@@ -4475,13 +4474,13 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode
// Make use of the optimized algorithm when we're scaling
if (scale_xform && mode == Qt::SmoothTransformation) {
if (mat.m11() < 0.0F && mat.m22() < 0.0F) { // horizontal/vertical flip
- return smoothScaled(mirrored(true, true), wd, hd);
+ return smoothScaled(wd, hd).mirrored(true, true);
} else if (mat.m11() < 0.0F) { // horizontal flip
- return smoothScaled(mirrored(true, false), wd, hd);
+ return smoothScaled(wd, hd).mirrored(true, false);
} else if (mat.m22() < 0.0F) { // vertical flip
- return smoothScaled(mirrored(false, true), wd, hd);
+ return smoothScaled(wd, hd).mirrored(false, true);
} else { // no flipping
- return smoothScaled(*this, wd, hd);
+ return smoothScaled(wd, hd);
}
}
@@ -4533,9 +4532,6 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode
dImage.d->has_alpha_clut = d->has_alpha_clut | complex_xform;
}
- dImage.d->dpmx = dotsPerMeterX();
- dImage.d->dpmy = dotsPerMeterY();
-
// initizialize the data
if (d->format == QImage::Format_Indexed8) {
if (dImage.d->colortable.size() < 256) {
@@ -4573,8 +4569,8 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode
int dbpl = dImage.bytesPerLine();
qt_xForm_helper(mat, 0, type, bpp, dImage.bits(), dbpl, 0, hd, sptr, sbpl, ws, hs);
}
+ copyMetadata(dImage.d, d);
- dImage.d->devicePixelRatio = devicePixelRatio();
return dImage;
}
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 4ce99b9ab1..99044bd4e3 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -328,6 +328,7 @@ protected:
void rgbSwapped_inplace();
QImage convertToFormat_helper(Format format, Qt::ImageConversionFlags flags) const;
bool convertToFormat_inplace(Format format, Qt::ImageConversionFlags flags);
+ QImage smoothScaled(int w, int h) const;
private:
friend class QWSOnScreenSurface;
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 5691a654d7..51e4c6233e 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -184,6 +184,8 @@ private slots:
void devicePixelRatio();
+ void metadataPassthrough();
+
private:
const QString m_prefix;
};
@@ -2827,5 +2829,39 @@ void tst_QImage::devicePixelRatio()
QCOMPARE(b.devicePixelRatio(), qreal(1.0));
}
+void tst_QImage::metadataPassthrough()
+{
+ QImage a(64, 64, QImage::Format_ARGB32);
+ a.fill(Qt::white);
+ a.setText(QStringLiteral("Test"), QStringLiteral("Text"));
+ a.setDotsPerMeterX(100);
+ a.setDotsPerMeterY(80);
+ a.setDevicePixelRatio(2.0);
+
+ QImage scaled = a.scaled(QSize(32, 32), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ QCOMPARE(scaled.text(QStringLiteral("Test")), a.text(QStringLiteral("Test")));
+ QCOMPARE(scaled.dotsPerMeterX(), a.dotsPerMeterX());
+ QCOMPARE(scaled.dotsPerMeterY(), a.dotsPerMeterY());
+ QCOMPARE(scaled.devicePixelRatio(), a.devicePixelRatio());
+
+ scaled = a.scaled(QSize(128, 128), Qt::IgnoreAspectRatio, Qt::FastTransformation);
+ QCOMPARE(scaled.text(QStringLiteral("Test")), a.text(QStringLiteral("Test")));
+ QCOMPARE(scaled.dotsPerMeterX(), a.dotsPerMeterX());
+ QCOMPARE(scaled.dotsPerMeterY(), a.dotsPerMeterY());
+ QCOMPARE(scaled.devicePixelRatio(), a.devicePixelRatio());
+
+ QImage mirrored = a.mirrored();
+ QCOMPARE(mirrored.text(QStringLiteral("Test")), a.text(QStringLiteral("Test")));
+ QCOMPARE(mirrored.dotsPerMeterX(), a.dotsPerMeterX());
+ QCOMPARE(mirrored.dotsPerMeterY(), a.dotsPerMeterY());
+ QCOMPARE(mirrored.devicePixelRatio(), a.devicePixelRatio());
+
+ QImage swapped = a.rgbSwapped();
+ QCOMPARE(swapped.text(QStringLiteral("Test")), a.text(QStringLiteral("Test")));
+ QCOMPARE(swapped.dotsPerMeterX(), a.dotsPerMeterX());
+ QCOMPARE(swapped.dotsPerMeterY(), a.dotsPerMeterY());
+ QCOMPARE(swapped.devicePixelRatio(), a.devicePixelRatio());
+}
+
QTEST_GUILESS_MAIN(tst_QImage)
#include "tst_qimage.moc"