diff --git a/kimgio/tiff.cpp b/kimgio/tiff.cpp index 087c612a..a90be199 100644 --- a/kimgio/tiff.cpp +++ b/kimgio/tiff.cpp @@ -19,6 +19,7 @@ #include "tiff.h" #include +#include #include #include @@ -348,6 +349,81 @@ QByteArray TIFFHandler::name() const return s_tiffpluginformat; } +bool TIFFHandler::supportsOption(QImageIOHandler::ImageOption option) const +{ + switch (option) { + case QImageIOHandler::Size: { + return true; + } + default: { + return false; + } + } + Q_UNREACHABLE(); +} + +QVariant TIFFHandler::option(QImageIOHandler::ImageOption option) const +{ + switch (option) { + case QImageIOHandler::Size: { + const qint64 devicepos = device()->pos(); + + s_tifferrorhandler = TIFFSetErrorHandler(tiff_error_handler); + s_tiffwarninghandler = TIFFSetWarningHandler(tiff_warning_handler); + + TIFF* tiffclient = TIFFClientOpen( + "TIFFHandler", "r", + device(), + tiff_read_proc, + tiff_write_proc, + tiff_seek_proc, + tiff_close_proc, + tiff_size_proc, + tiff_mapfile_proc, + tiff_unmapfile_proc + ); + if (!Q_UNLIKELY(tiffclient)) { + kWarning() << "Could not open client"; + TIFFSetErrorHandler(s_tifferrorhandler); + TIFFSetWarningHandler(s_tiffwarninghandler); + return false; + } + + uint32_t tiffwidth = 0; + int tiffresult = TIFFGetField(tiffclient, TIFFTAG_IMAGEWIDTH, &tiffwidth); + if (Q_UNLIKELY(tiffresult != 1)) { + kWarning() << "Could not get image width"; + TIFFClose(tiffclient); + TIFFSetErrorHandler(s_tifferrorhandler); + TIFFSetWarningHandler(s_tiffwarninghandler); + device()->seek(devicepos); + return false; + } + + uint32_t tiffheight = 0; + tiffresult = TIFFGetField(tiffclient, TIFFTAG_IMAGELENGTH, &tiffheight); + if (Q_UNLIKELY(tiffresult != 1)) { + kWarning() << "Could not get image length"; + TIFFClose(tiffclient); + TIFFSetErrorHandler(s_tifferrorhandler); + TIFFSetWarningHandler(s_tiffwarninghandler); + device()->seek(devicepos); + return false; + } + + TIFFClose(tiffclient); + TIFFSetErrorHandler(s_tifferrorhandler); + TIFFSetWarningHandler(s_tiffwarninghandler); + device()->seek(devicepos); + return QVariant(QSize(tiffwidth, tiffheight)); + } + default: { + return QVariant(); + } + } + Q_UNREACHABLE(); +} + bool TIFFHandler::canRead(QIODevice *device) { if (Q_UNLIKELY(!device)) { diff --git a/kimgio/tiff.h b/kimgio/tiff.h index 14562087..22ad3d2d 100644 --- a/kimgio/tiff.h +++ b/kimgio/tiff.h @@ -34,6 +34,9 @@ public: QByteArray name() const final; + bool supportsOption(QImageIOHandler::ImageOption option) const final; + QVariant option(QImageIOHandler::ImageOption option) const final; + static bool canRead(QIODevice *device); };