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>
This commit is contained in:
parent
1576f62eaf
commit
f15d6c3fa9
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user