summaryrefslogtreecommitdiffstats
path: root/src/plugins/imageformats/jpeg
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-10-11 16:16:29 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-10-11 16:23:19 +0200
commitf4b4c4f79b629498f3cddbbc10df8c1b4d6020d9 (patch)
tree4119707660438ff58bd51f9cbe0f9e2a33f4b806 /src/plugins/imageformats/jpeg
parent9bd6cec74dbbc5aece55dc0c8808494db29b9963 (diff)
parent93f2f33a49f6c96a4f94f344edf03164ed944d02 (diff)
Merge remote-tracking branch 'origin/wip/qt6' into wip/cmake
Diffstat (limited to 'src/plugins/imageformats/jpeg')
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp29
1 files changed, 27 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;