summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den.exter@jollamobile.com>2019-05-13 11:57:00 +1000
committerAndrew den Exter <andrew.den.exter@qinetic.com.au>2019-05-13 13:03:01 +1000
commit345f86a2d8d69c6d3cbae314028902f090f39a43 (patch)
tree69e432f3d5db50560ad54cbe5f957201638b0937 /src/gui/text
parent795af729d38343e16b0902323609cd1e959a5973 (diff)
Avoid re-encoding embedded images when writing an ODF file
If an embedded image is already encodeded as an png or jpg write the data as is instead of decoding to a QImage and re-encoding as a new image. Change-Id: I479ae1fddbf59900a500497dd1bdf7449c21f273 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qtextodfwriter.cpp87
1 files changed, 68 insertions, 19 deletions
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 103e0a8222..1a96f7608f 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -43,6 +43,7 @@
#include "qtextodfwriter_p.h"
+#include <QImageReader>
#include <QImageWriter>
#include <QTextListFormat>
#include <QTextList>
@@ -410,6 +411,29 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc
writer.writeEndElement(); // list-item
}
+static bool probeImageData(QIODevice *device, QImage *image, QString *mimeType, qreal *width, qreal *height)
+{
+ QImageReader reader(device);
+ const QByteArray format = reader.format().toLower();
+ if (format == "png") {
+ *mimeType = QStringLiteral("image/png");
+ } else if (format == "jpg") {
+ *mimeType = QStringLiteral("image/jpg");
+ } else if (format == "svg") {
+ *mimeType = QStringLiteral("image/svg+xml");
+ } else {
+ *image = reader.read();
+ return false;
+ }
+
+ const QSize size = reader.size();
+
+ *width = size.width();
+ *height = size.height();
+
+ return true;
+}
+
void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextFragment &fragment) const
{
writer.writeStartElement(drawNS, QString::fromLatin1("frame"));
@@ -420,46 +444,71 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF
QTextImageFormat imageFormat = fragment.charFormat().toImageFormat();
writer.writeAttribute(drawNS, QString::fromLatin1("name"), imageFormat.name());
+ QByteArray data;
+ QString mimeType;
+ qreal width = 0;
+ qreal height = 0;
+
QImage image;
QString name = imageFormat.name();
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
name.prepend(QLatin1String("qrc"));
QUrl url = QUrl(name);
- const QVariant data = m_document->resource(QTextDocument::ImageResource, url);
- if (data.type() == QVariant::Image) {
- image = qvariant_cast<QImage>(data);
- } else if (data.type() == QVariant::ByteArray) {
- image.loadFromData(data.toByteArray());
- }
-
- if (image.isNull()) {
- if (image.isNull()) { // try direct loading
- name = imageFormat.name(); // remove qrc:/ prefix again
- image.load(name);
+ const QVariant variant = m_document->resource(QTextDocument::ImageResource, url);
+ if (variant.type() == QVariant::Image) {
+ image = qvariant_cast<QImage>(variant);
+ } else if (variant.type() == QVariant::ByteArray) {
+ data = variant.toByteArray();
+
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly);
+ probeImageData(&buffer, &image, &mimeType, &width, &height);
+ } else {
+ // try direct loading
+ QFile file(imageFormat.name());
+ if (file.open(QIODevice::ReadOnly) && !probeImageData(&file, &image, &mimeType, &width, &height)) {
+ file.seek(0);
+ data = file.readAll();
}
}
if (! image.isNull()) {
QBuffer imageBytes;
- QString filename = m_strategy->createUniqueImageName();
+
int imgQuality = imageFormat.quality();
if (imgQuality >= 100 || imgQuality < 0 || image.hasAlphaChannel()) {
QImageWriter imageWriter(&imageBytes, "png");
imageWriter.write(image);
- m_strategy->addFile(filename, QString::fromLatin1("image/png"), imageBytes.data());
+
+ data = imageBytes.data();
+ mimeType = QStringLiteral("image/png");
} else {
// Write images without alpha channel as jpg with quality set by QTextImageFormat
QImageWriter imageWriter(&imageBytes, "jpg");
imageWriter.setQuality(imgQuality);
imageWriter.write(image);
- m_strategy->addFile(filename, QString::fromLatin1("image/jpg"), imageBytes.data());
+
+ data = imageBytes.data();
+ mimeType = QStringLiteral("image/jpg");
}
- // get the width/height from the format.
- qreal width = imageFormat.hasProperty(QTextFormat::ImageWidth)
- ? imageFormat.width() : image.width();
+
+ width = image.width();
+ height = image.height();
+ }
+
+ if (!data.isEmpty()) {
+ if (imageFormat.hasProperty(QTextFormat::ImageWidth)) {
+ width = imageFormat.width();
+ }
+ if (imageFormat.hasProperty(QTextFormat::ImageHeight)) {
+ height = imageFormat.height();
+ }
+
+ QString filename = m_strategy->createUniqueImageName();
+
+ m_strategy->addFile(filename, mimeType, data);
+
writer.writeAttribute(svgNS, QString::fromLatin1("width"), pixelToPoint(width));
- qreal height = imageFormat.hasProperty(QTextFormat::ImageHeight)
- ? imageFormat.height() : image.height();
writer.writeAttribute(svgNS, QString::fromLatin1("height"), pixelToPoint(height));
writer.writeStartElement(drawNS, QString::fromLatin1("image"));
writer.writeAttribute(xlinkNS, QString::fromLatin1("href"), filename);