summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2023-05-04 11:11:10 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2023-05-05 11:18:13 +0200
commit2bf281891b67e87b549b227800f325bc58ba033c (patch)
treed58bd63fe321d5186d90c141d3c6ee737b28608d
parent46fa217d01b3bb0d433196ae0b03aa997514071d (diff)
downloadqtimageformats-2bf281891b67e87b549b227800f325bc58ba033c.tar.gz
Add support for reading monochromatic floating point formats
It seems the builtin converting reader doesn't support all formats. Change-Id: Ia24b4d017476e2dd806861c3e98f3df19dce4584 Fixes: QTBUG-112947 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
-rw-r--r--src/plugins/imageformats/tiff/qtiffhandler.cpp59
-rw-r--r--src/plugins/imageformats/tiff/qtiffhandler_p.h1
2 files changed, 52 insertions, 8 deletions
diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp
index d01e888..aadf134 100644
--- a/src/plugins/imageformats/tiff/qtiffhandler.cpp
+++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp
@@ -277,9 +277,9 @@ bool QTiffHandlerPrivate::readHeaders(QIODevice *device)
else if ((grayscale || photometric == PHOTOMETRIC_PALETTE) && bitPerSample == 8 && samplesPerPixel == 1)
format = QImage::Format_Indexed8;
else if (samplesPerPixel < 4)
- if (bitPerSample == 16 && photometric == PHOTOMETRIC_RGB)
+ if (bitPerSample == 16 && (photometric == PHOTOMETRIC_RGB || photometric == PHOTOMETRIC_MINISBLACK))
format = floatingPoint ? QImage::Format_RGBX16FPx4 : QImage::Format_RGBX64;
- else if (bitPerSample == 32 && floatingPoint && photometric == PHOTOMETRIC_RGB)
+ else if (bitPerSample == 32 && floatingPoint && (photometric == PHOTOMETRIC_RGB || photometric == PHOTOMETRIC_MINISBLACK))
format = QImage::Format_RGBX32FPx4;
else
format = QImage::Format_RGB32;
@@ -419,9 +419,9 @@ bool QTiffHandler::read(QImage *image)
if (format8bit || format16bit || format64bit || format64fp || format128fp) {
int bytesPerPixel = image->depth() / 8;
if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBX16FPx4)
- bytesPerPixel = 6;
+ bytesPerPixel = d->photometric == PHOTOMETRIC_RGB ? 6 : 2;
else if (format == QImage::Format_RGBX32FPx4)
- bytesPerPixel = 12;
+ bytesPerPixel = d->photometric == PHOTOMETRIC_RGB ? 12 : 4;
if (TIFFIsTiled(tiff)) {
quint32 tileWidth, tileLength;
TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &tileWidth);
@@ -470,10 +470,17 @@ bool QTiffHandler::read(QImage *image)
}
}
}
- if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBX16FPx4)
- rgb48fixup(image, d->floatingPoint);
- else if (format == QImage::Format_RGBX32FPx4)
- rgb96fixup(image);
+ if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBX16FPx4) {
+ if (d->photometric == PHOTOMETRIC_RGB)
+ rgb48fixup(image, d->floatingPoint);
+ else
+ rgbFixup(image);
+ } else if (format == QImage::Format_RGBX32FPx4) {
+ if (d->photometric == PHOTOMETRIC_RGB)
+ rgb96fixup(image);
+ else
+ rgbFixup(image);
+ }
} else {
const int stopOnError = 1;
if (TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast<uint32_t *>(image->bits()), qt2Exif(d->transformation), stopOnError)) {
@@ -1016,6 +1023,42 @@ void QTiffHandler::rgb96fixup(QImage *image)
}
}
+void QTiffHandler::rgbFixup(QImage *image)
+{
+ Q_ASSERT(d->floatingPoint);
+ if (image->depth() == 64) {
+ const int h = image->height();
+ const int w = image->width();
+ uchar *scanline = image->bits();
+ const qsizetype bpl = image->bytesPerLine();
+ for (int y = 0; y < h; ++y) {
+ qfloat16 *dst = reinterpret_cast<qfloat16 *>(scanline);
+ for (int x = w - 1; x >= 0; --x) {
+ dst[x * 4 + 3] = qfloat16(1.0f);
+ dst[x * 4 + 2] = dst[x];
+ dst[x * 4 + 1] = dst[x];
+ dst[x * 4 + 0] = dst[x];
+ }
+ scanline += bpl;
+ }
+ } else {
+ const int h = image->height();
+ const int w = image->width();
+ uchar *scanline = image->bits();
+ const qsizetype bpl = image->bytesPerLine();
+ for (int y = 0; y < h; ++y) {
+ float *dst = reinterpret_cast<float *>(scanline);
+ for (int x = w - 1; x >= 0; --x) {
+ dst[x * 4 + 3] = 1.0f;
+ dst[x * 4 + 2] = dst[x];
+ dst[x * 4 + 1] = dst[x];
+ dst[x * 4 + 0] = dst[x];
+ }
+ scanline += bpl;
+ }
+ }
+}
+
bool QTiffHandler::ensureHaveDirectoryCount() const
{
if (d->directoryCount > 0)
diff --git a/src/plugins/imageformats/tiff/qtiffhandler_p.h b/src/plugins/imageformats/tiff/qtiffhandler_p.h
index e874984..738b992 100644
--- a/src/plugins/imageformats/tiff/qtiffhandler_p.h
+++ b/src/plugins/imageformats/tiff/qtiffhandler_p.h
@@ -38,6 +38,7 @@ private:
void convert32BitOrder(void *buffer, int width);
void rgb48fixup(QImage *image, bool floatingPoint);
void rgb96fixup(QImage *image);
+ void rgbFixup(QImage *image);
const QScopedPointer<QTiffHandlerPrivate> d;
bool ensureHaveDirectoryCount() const;
};