summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp29
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp7
2 files changed, 34 insertions, 2 deletions
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 0fb21df1d3..1f1675e490 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -492,6 +492,8 @@ inline my_jpeg_destination_mgr::my_jpeg_destination_mgr(QIODevice *device)
free_in_buffer = max_buf;
}
+static constexpr int maxMarkerSize = 65533;
+
static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QString &description)
{
const QMap<QString, QString> text = qt_getImageText(image, description);
@@ -500,12 +502,33 @@ static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QSt
if (!comment.isEmpty())
comment += ": ";
comment += it.value().toUtf8();
- if (comment.length() > 65530)
- comment.truncate(65530);
+ if (comment.length() > maxMarkerSize)
+ comment.truncate(maxMarkerSize);
jpeg_write_marker(cinfo, JPEG_COM, (const JOCTET *)comment.constData(), comment.size());
}
}
+static inline void write_icc_profile(const QImage &image, j_compress_ptr cinfo)
+{
+ const QByteArray iccProfile = image.colorSpace().iccProfile();
+ if (iccProfile.isEmpty())
+ return;
+
+ const QByteArray iccSignature("ICC_PROFILE", 12);
+ constexpr int maxIccMarkerSize = maxMarkerSize - (12 + 2);
+ int index = 0;
+ const int markers = (iccProfile.size() + (maxIccMarkerSize - 1)) / maxIccMarkerSize;
+ Q_ASSERT(markers < 256);
+ for (int marker = 1; marker <= markers; ++marker) {
+ const int len = std::min(iccProfile.size() - index, maxIccMarkerSize);
+ const QByteArray block = iccSignature
+ + QByteArray(1, char(marker)) + QByteArray(1, char(markers))
+ + iccProfile.mid(index, len);
+ jpeg_write_marker(cinfo, JPEG_APP0 + 2, reinterpret_cast<const JOCTET *>(block.constData()), block.size());
+ index += len;
+ }
+}
+
static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description, bool optimize, bool progressive)
{
bool success = false;
@@ -586,6 +609,8 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
jpeg_start_compress(&cinfo, TRUE);
set_text(image, &cinfo, description);
+ if (cinfo.in_color_space == JCS_RGB)
+ write_icc_profile(image, &cinfo);
row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
int w = cinfo.image_width;
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 866a41c3d1..eeabfd0413 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -1914,6 +1914,13 @@ void tst_QImageReader::saveColorSpace()
QCOMPARE(stored, orig);
QCOMPARE(stored.colorSpace(), orig.colorSpace());
+
+ buf.open(QIODevice::WriteOnly);
+ QVERIFY(orig.save(&buf, "jpeg"));
+ buf.close();
+ stored = QImage::fromData(buf.buffer(), "jpeg");
+
+ QCOMPARE(stored.colorSpace(), orig.colorSpace());
}
void tst_QImageReader::readText_data()