TIFF: add support for CMYK image load/save

This work has been kindly sponsored by the QGIS project
(https://qgis.org/).

[ChangeLog][TIFF] Added support for loading and saving of 8-bit CMYK
TIFF files.

Change-Id: I380ef56023fea17f6155ee50fd09421891fbf192
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
Giuseppe D'Angelo 2023-10-24 02:44:08 +02:00
parent 266f87720f
commit 3cf129582b
1 changed files with 30 additions and 1 deletions

View File

@ -310,6 +310,15 @@ bool QTiffHandlerPrivate::readHeaders(QIODevice *device)
format = QImage::Format_RGBA32FPx4_Premultiplied;
else
format = QImage::Format_RGBA32FPx4;
} else if (samplesPerPixel == 4 && bitPerSample == 8 && photometric == PHOTOMETRIC_SEPARATED) {
uint16_t inkSet;
const bool gotInkSetField = TIFFGetField(tiff, TIFFTAG_INKSET, &inkSet);
if (!gotInkSetField || inkSet == INKSET_CMYK) {
format = QImage::Format_CMYK8888;
} else {
close();
return false;
}
} else {
if (premultiplied)
format = QImage::Format_ARGB32_Premultiplied;
@ -411,12 +420,13 @@ bool QTiffHandler::read(QImage *image)
}
bool format8bit = (format == QImage::Format_Mono || format == QImage::Format_Indexed8 || format == QImage::Format_Grayscale8);
bool format16bit = (format == QImage::Format_Grayscale16);
bool formatCmyk32bit = (format == QImage::Format_CMYK8888);
bool format64bit = (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64 || format == QImage::Format_RGBA64_Premultiplied);
bool format64fp = (format == QImage::Format_RGBX16FPx4 || format == QImage::Format_RGBA16FPx4 || format == QImage::Format_RGBA16FPx4_Premultiplied);
bool format128fp = (format == QImage::Format_RGBX32FPx4 || format == QImage::Format_RGBA32FPx4 || format == QImage::Format_RGBA32FPx4_Premultiplied);
// Formats we read directly, instead of over RGBA32:
if (format8bit || format16bit || format64bit || format64fp || format128fp) {
if (format8bit || format16bit || formatCmyk32bit || format64bit || format64fp || format128fp) {
int bytesPerPixel = image->depth() / 8;
if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBX16FPx4)
bytesPerPixel = d->photometric == PHOTOMETRIC_RGB ? 6 : 2;
@ -825,6 +835,25 @@ bool QTiffHandler::write(const QImage &image)
return false;
}
}
TIFFClose(tiff);
} else if (format == QImage::Format_CMYK8888) {
if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_SEPARATED)
|| !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression == NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW)
|| !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4)
|| !TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8)
|| !TIFFSetField(tiff, TIFFTAG_INKSET, INKSET_CMYK)
|| !TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, defaultStripSize(tiff))) {
TIFFClose(tiff);
return false;
}
for (int y = 0; y < image.height(); ++y) {
if (TIFFWriteScanline(tiff, (void*)image.scanLine(y), y) != 1) {
TIFFClose(tiff);
return false;
}
}
TIFFClose(tiff);
} else if (!image.hasAlphaChannel()) {
if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)