Support writing color space profile in JPEG
That way the image formats with color space supports all have both read and write support. Change-Id: Ib52ebd56192c4a8a0897a6afc7c4a26020319270 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
This commit is contained in:
parent
aa6e0e3e30
commit
9e86fdb6e8
@ -492,6 +492,8 @@ inline my_jpeg_destination_mgr::my_jpeg_destination_mgr(QIODevice *device)
|
|||||||
free_in_buffer = max_buf;
|
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)
|
static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QString &description)
|
||||||
{
|
{
|
||||||
const QMap<QString, QString> text = qt_getImageText(image, 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())
|
if (!comment.isEmpty())
|
||||||
comment += ": ";
|
comment += ": ";
|
||||||
comment += it.value().toUtf8();
|
comment += it.value().toUtf8();
|
||||||
if (comment.length() > 65530)
|
if (comment.length() > maxMarkerSize)
|
||||||
comment.truncate(65530);
|
comment.truncate(maxMarkerSize);
|
||||||
jpeg_write_marker(cinfo, JPEG_COM, (const JOCTET *)comment.constData(), comment.size());
|
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)
|
static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description, bool optimize, bool progressive)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
@ -586,6 +609,8 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
|
|||||||
jpeg_start_compress(&cinfo, TRUE);
|
jpeg_start_compress(&cinfo, TRUE);
|
||||||
|
|
||||||
set_text(image, &cinfo, description);
|
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];
|
row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
|
||||||
int w = cinfo.image_width;
|
int w = cinfo.image_width;
|
||||||
|
@ -1914,6 +1914,13 @@ void tst_QImageReader::saveColorSpace()
|
|||||||
|
|
||||||
QCOMPARE(stored, orig);
|
QCOMPARE(stored, orig);
|
||||||
QCOMPARE(stored.colorSpace(), orig.colorSpace());
|
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()
|
void tst_QImageReader::readText_data()
|
||||||
|
Loading…
Reference in New Issue
Block a user