diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2023-05-04 11:11:10 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2023-05-05 11:18:13 +0200 |
commit | 2bf281891b67e87b549b227800f325bc58ba033c (patch) | |
tree | d58bd63fe321d5186d90c141d3c6ee737b28608d /src | |
parent | 46fa217d01b3bb0d433196ae0b03aa997514071d (diff) | |
download | qtimageformats-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>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/imageformats/tiff/qtiffhandler.cpp | 59 | ||||
-rw-r--r-- | src/plugins/imageformats/tiff/qtiffhandler_p.h | 1 |
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; }; |