diff options
author | Christian Ehrlicher <ch.ehrlicher@gmx.de> | 2024-03-01 21:26:15 +0100 |
---|---|---|
committer | Christian Ehrlicher <ch.ehrlicher@gmx.de> | 2024-04-09 14:58:00 +0000 |
commit | adbede1e675be185da233673be853ced3423033c (patch) | |
tree | 76caf51f1fde93ae4e9b43bbb99b4eebd1bf21cb | |
parent | 22a97e80aca03a8175f389cc5b5105ed6f686c3d (diff) |
Tiff: Add message handler to pass errors/warnings through Qt logging
Use TIFFClientOpenExt() and set an error/warning handler to be able
to pass the output through the Qt logging system. Use
qt.imageformats.tiff as the logging channel.
This requires libtiff >= 4.5.0
Pick-to: 6.7
Fixes: QTBUG-122829
Change-Id: I19d453ced9af0b6bc20988f6f1505988c1c1aa5c
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
-rw-r--r-- | src/plugins/imageformats/tiff/qtiffhandler.cpp | 123 |
1 files changed, 81 insertions, 42 deletions
diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp index 549b142..95d30d7 100644 --- a/src/plugins/imageformats/tiff/qtiffhandler.cpp +++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp @@ -7,6 +7,7 @@ #include <qdebug.h> #include <qfloat16.h> #include <qimage.h> +#include <qloggingcategory.h> #include <qvariant.h> #include <qvarlengtharray.h> #include <qbuffer.h> @@ -20,6 +21,8 @@ extern "C" { QT_BEGIN_NAMESPACE +static Q_LOGGING_CATEGORY(lcTiff, "qt.imageformats.tiff") + tsize_t qtiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) { QIODevice *device = static_cast<QIODevice *>(fd); @@ -99,6 +102,13 @@ public: bool openForRead(QIODevice *device); bool readHeaders(QIODevice *device); void close(); + TIFF *openInternal(const char *mode, QIODevice *device); +#if TIFFLIB_VERSION >= 20221213 + static int tiffErrorHandler(TIFF *tif, void *user_data, const char *, + const char *fmt, va_list ap); + static int tiffWarningHandler(TIFF *tif, void *user_data, const char *, + const char *fmt, va_list ap); +#endif TIFF *tiff; int compression; @@ -133,7 +143,7 @@ static QImageIOHandler::Transformations exif2Qt(int exifOrientation) case 8: // rotate 270 CW return QImageIOHandler::TransformationRotate270; } - qWarning("Invalid EXIF orientation"); + qCWarning(lcTiff, "Invalid EXIF orientation"); return QImageIOHandler::TransformationNone; } @@ -157,7 +167,7 @@ static int qt2Exif(QImageIOHandler::Transformations transformation) case QImageIOHandler::TransformationRotate270: return 8; } - qWarning("Invalid Qt image transformation"); + qCWarning(lcTiff, "Invalid Qt image transformation"); return 1; } @@ -186,10 +196,67 @@ void QTiffHandlerPrivate::close() tiff = 0; } +TIFF *QTiffHandlerPrivate::openInternal(const char *mode, QIODevice *device) +{ +// TIFFLIB_VERSION 20221213 -> 4.5.0 +#if TIFFLIB_VERSION >= 20221213 + TIFFOpenOptions *opts = TIFFOpenOptionsAlloc(); + TIFFOpenOptionsSetErrorHandlerExtR(opts, &tiffErrorHandler, this); + TIFFOpenOptionsSetWarningHandlerExtR(opts, &tiffWarningHandler, this); + auto handle = TIFFClientOpenExt("foo", + mode, + device, + qtiffReadProc, + qtiffWriteProc, + qtiffSeekProc, + qtiffCloseProc, + qtiffSizeProc, + qtiffMapProc, + qtiffUnmapProc, + opts); + TIFFOpenOptionsFree(opts); +#else + auto handle = TIFFClientOpen("foo", + mode, + device, + qtiffReadProc, + qtiffWriteProc, + qtiffSeekProc, + qtiffCloseProc, + qtiffSizeProc, + qtiffMapProc, + qtiffUnmapProc); +#endif + return handle; +} + + +#if TIFFLIB_VERSION >= 20221213 +int QTiffHandlerPrivate::tiffErrorHandler(TIFF *tif, void *user_data, const char *, + const char *fmt, va_list ap) +{ + const auto priv = static_cast<QTiffHandlerPrivate *>(user_data); + if (!priv || priv->tiff != tif) + return 0; + qCCritical(lcTiff) << QString::vasprintf(fmt, ap); + return 1; +} + +int QTiffHandlerPrivate::tiffWarningHandler(TIFF *tif, void *user_data, const char *, + const char *fmt, va_list ap) +{ + const auto priv = static_cast<QTiffHandlerPrivate *>(user_data); + if (!priv || priv->tiff != tif) + return 0; + qCWarning(lcTiff) << QString::vasprintf(fmt, ap); + return 1; +} +#endif + bool QTiffHandlerPrivate::canRead(QIODevice *device) { if (!device) { - qWarning("QTiffHandler::canRead() called with no device"); + qCWarning(lcTiff, "QTiffHandler::canRead() called with no device"); return false; } @@ -213,21 +280,8 @@ bool QTiffHandlerPrivate::openForRead(QIODevice *device) if (!canRead(device)) return false; - tiff = TIFFClientOpen("foo", - "r", - device, - qtiffReadProc, - qtiffWriteProc, - qtiffSeekProc, - qtiffCloseProc, - qtiffSizeProc, - qtiffMapProc, - qtiffUnmapProc); - - if (!tiff) { - return false; - } - return true; + tiff = openInternal("rh", device); + return tiff != nullptr; } bool QTiffHandlerPrivate::readHeaders(QIODevice *device) @@ -238,7 +292,10 @@ bool QTiffHandlerPrivate::readHeaders(QIODevice *device) if (!openForRead(device)) return false; - TIFFSetDirectory(tiff, currentDirectory); + if (!TIFFSetDirectory(tiff, currentDirectory)) { + close(); + return false; + } uint32_t width; uint32_t height; @@ -592,16 +649,7 @@ bool QTiffHandler::write(const QImage &image) if (!device()->isWritable()) return false; - TIFF *const tiff = TIFFClientOpen("foo", - "wB", - device(), - qtiffReadProc, - qtiffWriteProc, - qtiffSeekProc, - qtiffCloseProc, - qtiffSizeProc, - qtiffMapProc, - qtiffUnmapProc); + TIFF *const tiff = d->openInternal("wB", device()); if (!tiff) return false; @@ -1093,24 +1141,15 @@ bool QTiffHandler::ensureHaveDirectoryCount() const if (d->directoryCount > 0) return true; - TIFF *tiff = TIFFClientOpen("foo", - "r", - device(), - qtiffReadProc, - qtiffWriteProc, - qtiffSeekProc, - qtiffCloseProc, - qtiffSizeProc, - qtiffMapProc, - qtiffUnmapProc); + TIFF *tiff = d->openInternal("rh", device()); + if (!tiff) { device()->reset(); return false; } - do { - ++d->directoryCount; - } while (TIFFReadDirectory(tiff)); + while (TIFFReadDirectory(tiff)) + ++d->directoryCount; TIFFClose(tiff); device()->reset(); return true; |