summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Ehrlicher <ch.ehrlicher@gmx.de>2024-03-01 21:26:15 +0100
committerChristian Ehrlicher <ch.ehrlicher@gmx.de>2024-04-09 14:58:00 +0000
commitadbede1e675be185da233673be853ced3423033c (patch)
tree76caf51f1fde93ae4e9b43bbb99b4eebd1bf21cb
parent22a97e80aca03a8175f389cc5b5105ed6f686c3d (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.cpp123
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;