diff options
Diffstat (limited to 'src/plugins')
28 files changed, 484 insertions, 163 deletions
diff --git a/src/plugins/imageformats/dds/qddshandler.cpp b/src/plugins/imageformats/dds/qddshandler.cpp index 845f9b3..a0ac19b 100644 --- a/src/plugins/imageformats/dds/qddshandler.cpp +++ b/src/plugins/imageformats/dds/qddshandler.cpp @@ -1382,13 +1382,6 @@ QDDSHandler::QDDSHandler() : { } -#if QT_DEPRECATED_SINCE(5, 13) -QByteArray QDDSHandler::name() const -{ - return QByteArrayLiteral("dds"); -} -#endif - bool QDDSHandler::canRead() const { if (m_scanState == ScanNotScanned && !canRead(device())) diff --git a/src/plugins/imageformats/dds/qddshandler.h b/src/plugins/imageformats/dds/qddshandler.h index f4bc888..0c6449a 100644 --- a/src/plugins/imageformats/dds/qddshandler.h +++ b/src/plugins/imageformats/dds/qddshandler.h @@ -53,10 +53,6 @@ class QDDSHandler : public QImageIOHandler public: QDDSHandler(); -#if QT_DEPRECATED_SINCE(5, 13) - QByteArray name() const override; -#endif - bool canRead() const override; bool read(QImage *image) override; bool write(const QImage &image) override; diff --git a/src/plugins/imageformats/icns/main.cpp b/src/plugins/imageformats/icns/main.cpp index 70dd034..6a5af47 100644 --- a/src/plugins/imageformats/icns/main.cpp +++ b/src/plugins/imageformats/icns/main.cpp @@ -60,12 +60,12 @@ QImageIOPlugin::Capabilities QICNSPlugin::capabilities(QIODevice *device, const { if (format == QByteArrayLiteral("icns")) return Capabilities(CanRead | CanWrite); + Capabilities cap; if (!format.isEmpty()) - return 0; + return cap; if (!device || !device->isOpen()) - return 0; + return cap; - Capabilities cap; if (device->isReadable() && QICNSHandler::canRead(device)) cap |= CanRead; if (device->isWritable()) diff --git a/src/plugins/imageformats/icns/qicnshandler.cpp b/src/plugins/imageformats/icns/qicnshandler.cpp index 9733ed7..1bf9074 100644 --- a/src/plugins/imageformats/icns/qicnshandler.cpp +++ b/src/plugins/imageformats/icns/qicnshandler.cpp @@ -462,8 +462,12 @@ static bool parseIconEntryInfo(ICNSEntry &icon) if (isIconCompressed(icon)) return true; // Icon depth: - if (!depth.isEmpty()) - icon.depth = ICNSEntry::Depth(depth.toUInt()); + if (!depth.isEmpty()) { + const uint depthUInt = depth.toUInt(); + if (depthUInt > 32) + return false; + icon.depth = ICNSEntry::Depth(depthUInt); + } // Try mono if depth not found if (icon.depth == ICNSEntry::DepthUnknown) icon.depth = ICNSEntry::DepthMono; @@ -515,6 +519,9 @@ static bool parseIconEntryInfo(ICNSEntry &icon) } icon.height = icon.width; } + // Sanity check + if (icon.width == 0 || icon.width > 4096) + return false; return true; } @@ -651,13 +658,6 @@ QICNSHandler::QICNSHandler() : { } -#if QT_DEPRECATED_SINCE(5, 13) -QByteArray QICNSHandler::name() const -{ - return QByteArrayLiteral("icns"); -} -#endif - bool QICNSHandler::canRead(QIODevice *device) { if (!device || !device->isReadable()) { @@ -692,7 +692,7 @@ bool QICNSHandler::canRead() const bool QICNSHandler::read(QImage *outImage) { QImage img; - if (!ensureScanned()) { + if (!ensureScanned() || m_currentIconIndex >= m_icons.size()) { qWarning("QICNSHandler::read(): The device wasn't parsed properly!"); return false; } @@ -899,7 +899,7 @@ bool QICNSHandler::scanDevice() return false; const qint64 blockDataOffset = device()->pos(); - if (!isBlockHeaderValid(blockHeader)) { + if (!isBlockHeaderValid(blockHeader, ICNSBlockHeaderSize + filelength - blockDataOffset)) { qWarning("QICNSHandler::scanDevice(): Failed, bad header at pos %s. OSType \"%s\", length %u", QByteArray::number(blockDataOffset).constData(), nameFromOSType(blockHeader.ostype).constData(), blockHeader.length); @@ -934,11 +934,14 @@ bool QICNSHandler::scanDevice() case ICNSBlockHeader::TypeOdrp: // Icns container seems to have an embedded icon variant container // Let's start a scan for entries - while (device()->pos() < nextBlockOffset) { + while (!stream.atEnd() && device()->pos() < nextBlockOffset) { ICNSBlockHeader icon; stream >> icon; + if (stream.status() != QDataStream::Ok) + return false; // Check for incorrect variant entry header and stop scan - if (!isBlockHeaderValid(icon, blockDataLength)) + quint64 remaining = blockDataLength - (device()->pos() - blockDataOffset); + if (!isBlockHeaderValid(icon, ICNSBlockHeaderSize + remaining)) break; if (!addEntry(icon, device()->pos(), blockHeader.ostype)) return false; @@ -1010,7 +1013,7 @@ bool QICNSHandler::scanDevice() break; } } - return true; + return (m_icons.size() > 0); } const ICNSEntry &QICNSHandler::getIconMask(const ICNSEntry &icon) const diff --git a/src/plugins/imageformats/icns/qicnshandler_p.h b/src/plugins/imageformats/icns/qicnshandler_p.h index b532045..e83d4eb 100644 --- a/src/plugins/imageformats/icns/qicnshandler_p.h +++ b/src/plugins/imageformats/icns/qicnshandler_p.h @@ -132,10 +132,6 @@ public: bool read(QImage *image) override; bool write(const QImage &image) override; -#if QT_DEPRECATED_SINCE(5, 13) - QByteArray name() const override; -#endif - bool supportsOption(ImageOption option) const override; QVariant option(ImageOption option) const override; diff --git a/src/plugins/imageformats/jp2/main.cpp b/src/plugins/imageformats/jp2/main.cpp index a1f1281..22368a5 100644 --- a/src/plugins/imageformats/jp2/main.cpp +++ b/src/plugins/imageformats/jp2/main.cpp @@ -64,12 +64,12 @@ QImageIOPlugin::Capabilities QJp2Plugin::capabilities(QIODevice *device, const Q { if (format == "jp2" || format == "j2k") return Capabilities(CanRead | CanWrite); + Capabilities cap; if (!format.isEmpty()) - return 0; + return cap; if (!device->isOpen()) - return 0; + return cap; - Capabilities cap; if (device->isReadable() && QJp2Handler::canRead(device, 0)) cap |= CanRead; if (device->isWritable()) diff --git a/src/plugins/imageformats/jp2/qjp2handler.cpp b/src/plugins/imageformats/jp2/qjp2handler.cpp index ce23480..cb34374 100644 --- a/src/plugins/imageformats/jp2/qjp2handler.cpp +++ b/src/plugins/imageformats/jp2/qjp2handler.cpp @@ -43,8 +43,10 @@ #include "qimage.h" #include "qvariant.h" #include "qcolor.h" +#include "qimagereader.h" #include <jasper/jasper.h> +#include <math.h> // for pow QT_BEGIN_NAMESPACE @@ -308,17 +310,6 @@ bool QJp2Handler::supportsOption(ImageOption option) const return (option == Quality || option == SubType); } -#if QT_DEPRECATED_SINCE(5, 13) -/*! - Return the common identifier of the format. - For JPEG 2000 this will return "jp2". - */ -QByteArray QJp2Handler::name() const -{ - return QByteArrayLiteral("jp2"); -} -#endif - /*! Automatic resource handling for a jas_image_t*. */ @@ -343,16 +334,46 @@ private: Jpeg2000JasperReader::Jpeg2000JasperReader(QIODevice *iod, SubFormat format) : jasperOk(true), ioDevice(iod), format(format), hasAlpha(false) { +#if JAS_VERSION_MAJOR < 3 if (jas_init()) { jasperOk = false; qDebug("Jasper Library initialization failed"); } +#else + jas_conf_clear(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + jas_conf_set_max_mem_usage(QImageReader::allocationLimit() * 1024 * 1024); +#else + // 128MB seems to be enough. + jas_conf_set_max_mem_usage(128 * 1024 * 1024); +#endif + if (jas_init_library()) { + jasperOk = false; + qDebug("Jasper library initialization failed"); + } + if (jas_init_thread()) { + jas_cleanup_library(); + jasperOk = false; + qDebug("Jasper thread initialization failed"); + } +#endif } Jpeg2000JasperReader::~Jpeg2000JasperReader() { +#if JAS_VERSION_MAJOR < 3 if (jasperOk) jas_cleanup(); +#else + if (jasperOk) { + if (jas_cleanup_thread()) { + qDebug("Jasper thread cleanup failed"); + } + if (jas_cleanup_library()) { + qDebug("Jasper library cleanup failed"); + } + } +#endif } /*! \internal @@ -867,7 +888,7 @@ bool Jpeg2000JasperReader::write(const QImage &image, int quality) } // Open an empty jasper stream that grows automatically - jas_stream_t * memory_stream = jas_stream_memopen(0, -1); + jas_stream_t * memory_stream = jas_stream_memopen(0, 0); // Jasper wants a non-const string. char *str = qstrdup(jasperFormatString.toLatin1().constData()); diff --git a/src/plugins/imageformats/jp2/qjp2handler_p.h b/src/plugins/imageformats/jp2/qjp2handler_p.h index 16ddc8a..bdaf601 100644 --- a/src/plugins/imageformats/jp2/qjp2handler_p.h +++ b/src/plugins/imageformats/jp2/qjp2handler_p.h @@ -64,9 +64,6 @@ public: QVariant option(ImageOption option) const override; void setOption(ImageOption option, const QVariant &value) override; bool supportsOption(ImageOption option) const override; -#if QT_DEPRECATED_SINCE(5, 13) - QByteArray name() const override; -#endif private: Q_DECLARE_PRIVATE(QJp2Handler) diff --git a/src/plugins/imageformats/macheif/main.cpp b/src/plugins/imageformats/macheif/main.cpp index 12d9a4a..785ad1f 100644 --- a/src/plugins/imageformats/macheif/main.cpp +++ b/src/plugins/imageformats/macheif/main.cpp @@ -58,16 +58,16 @@ QImageIOPlugin::Capabilities QMacHeifPlugin::capabilities(QIODevice *device, con { static const Capabilities sysCaps = QIIOFHelpers::systemCapabilities(QStringLiteral("public.heic")); + Capabilities cap; if (!sysCaps) - return 0; + return cap; if (format == "heic" || format == "heif") return sysCaps; if (!format.isEmpty()) - return 0; + return cap; if (!device->isOpen()) - return 0; + return cap; - Capabilities cap; if (sysCaps.testFlag(CanRead) && device->isReadable() && QMacHeifHandler::canRead(device)) cap |= CanRead; if (sysCaps.testFlag(CanWrite) && device->isWritable()) diff --git a/src/plugins/imageformats/macjp2/main.cpp b/src/plugins/imageformats/macjp2/main.cpp index 08b497e..ea0cf44 100644 --- a/src/plugins/imageformats/macjp2/main.cpp +++ b/src/plugins/imageformats/macjp2/main.cpp @@ -57,12 +57,12 @@ QImageIOPlugin::Capabilities QMacJp2Plugin::capabilities(QIODevice *device, cons { if (format == "jp2") return Capabilities(CanRead | CanWrite); + Capabilities cap; if (!format.isEmpty()) - return 0; + return cap; if (!device->isOpen()) - return 0; + return cap; - Capabilities cap; if (device->isReadable() && QMacJp2Handler::canRead(device)) cap |= CanRead; if (device->isWritable()) diff --git a/src/plugins/imageformats/macjp2/qmacjp2handler.cpp b/src/plugins/imageformats/macjp2/qmacjp2handler.cpp index 72f753a..11df94a 100644 --- a/src/plugins/imageformats/macjp2/qmacjp2handler.cpp +++ b/src/plugins/imageformats/macjp2/qmacjp2handler.cpp @@ -118,10 +118,4 @@ bool QMacJp2Handler::supportsOption(ImageOption option) const return (option == Quality); } -QByteArray QMacJp2Handler::name() const -{ - return QByteArrayLiteral("jp2"); -} - - QT_END_NAMESPACE diff --git a/src/plugins/imageformats/macjp2/qmacjp2handler.h b/src/plugins/imageformats/macjp2/qmacjp2handler.h index bf0496d..e1deaf7 100644 --- a/src/plugins/imageformats/macjp2/qmacjp2handler.h +++ b/src/plugins/imageformats/macjp2/qmacjp2handler.h @@ -63,7 +63,6 @@ public: QVariant option(ImageOption option) const override; void setOption(ImageOption option, const QVariant &value) override; bool supportsOption(ImageOption option) const override; - QByteArray name() const override; static bool canRead(QIODevice *iod); diff --git a/src/plugins/imageformats/mng/main.cpp b/src/plugins/imageformats/mng/main.cpp index 5e5b0a3..be82312 100644 --- a/src/plugins/imageformats/mng/main.cpp +++ b/src/plugins/imageformats/mng/main.cpp @@ -66,12 +66,12 @@ QImageIOPlugin::Capabilities QMngPlugin::capabilities(QIODevice *device, const Q { if (format == "mng") return Capabilities(CanRead); + Capabilities cap; if (!format.isEmpty()) - return 0; + return cap; if (!device->isOpen()) - return 0; + return cap; - Capabilities cap; if (device->isReadable() && QMngHandler::canRead(device)) cap |= CanRead; return cap; diff --git a/src/plugins/imageformats/mng/qmnghandler.cpp b/src/plugins/imageformats/mng/qmnghandler.cpp index 4106ba6..b37dca1 100644 --- a/src/plugins/imageformats/mng/qmnghandler.cpp +++ b/src/plugins/imageformats/mng/qmnghandler.cpp @@ -403,12 +403,6 @@ bool QMngHandler::canRead(QIODevice *device) } /*! \reimp */ -QByteArray QMngHandler::name() const -{ - return "mng"; -} - -/*! \reimp */ bool QMngHandler::read(QImage *image) { Q_D(QMngHandler); diff --git a/src/plugins/imageformats/mng/qmnghandler_p.h b/src/plugins/imageformats/mng/qmnghandler_p.h index 0f9a207..de2ff5c 100644 --- a/src/plugins/imageformats/mng/qmnghandler_p.h +++ b/src/plugins/imageformats/mng/qmnghandler_p.h @@ -57,7 +57,6 @@ class QMngHandler : public QImageIOHandler QMngHandler(); ~QMngHandler(); bool canRead() const override; - QByteArray name() const override; bool read(QImage *image) override; bool write(const QImage &image) override; int currentImageNumber() const override; diff --git a/src/plugins/imageformats/tga/main.cpp b/src/plugins/imageformats/tga/main.cpp index 22fd3be..9177aa8 100644 --- a/src/plugins/imageformats/tga/main.cpp +++ b/src/plugins/imageformats/tga/main.cpp @@ -64,12 +64,12 @@ QImageIOPlugin::Capabilities QTgaPlugin::capabilities(QIODevice *device, const Q { if (format == "tga") return Capabilities(CanRead); + Capabilities cap; if (!format.isEmpty()) - return 0; + return cap; if (!device->isOpen()) - return 0; + return cap; - Capabilities cap; if (device->isReadable() && QTgaHandler::canRead(device)) cap |= CanRead; return cap; diff --git a/src/plugins/imageformats/tga/qtgafile.cpp b/src/plugins/imageformats/tga/qtgafile.cpp index 5d086c6..3961c16 100644 --- a/src/plugins/imageformats/tga/qtgafile.cpp +++ b/src/plugins/imageformats/tga/qtgafile.cpp @@ -220,9 +220,18 @@ QImage QTgaFile::readImage() int offset = mHeader[IdLength]; // Mostly always zero - // Even in TrueColor files a color pallette may be present - if (mHeader[ColorMapType] == 1) - offset += littleEndianInt(&mHeader[CMapLength]) * littleEndianInt(&mHeader[CMapDepth]); + // Even in TrueColor files a color palette may be present so we have to check it here + // even we only support image type 2 (= uncompressed true-color image) + if (mHeader[ColorMapType] == 1) { + int cmapDepth = mHeader[CMapDepth]; + if (cmapDepth == 15) // 15 bit is stored as 16 bit + ignoring the highest bit (no alpha) + cmapDepth = 16; + if (cmapDepth != 16 && cmapDepth != 24 && cmapDepth != 32) { + mErrorMessage = tr("Invalid color map depth (%1)").arg(cmapDepth); + return {}; + } + offset += littleEndianInt(&mHeader[CMapLength]) * cmapDepth / 8; + } mDevice->seek(HeaderSize + offset); diff --git a/src/plugins/imageformats/tga/qtgahandler.cpp b/src/plugins/imageformats/tga/qtgahandler.cpp index 9277e50..53a16d0 100644 --- a/src/plugins/imageformats/tga/qtgahandler.cpp +++ b/src/plugins/imageformats/tga/qtgahandler.cpp @@ -66,6 +66,7 @@ bool QTgaHandler::canRead() const setFormat("tga"); return true; } + qWarning("QTgaHandler::canRead(): %s", qPrintable(tga->errorMessage())); return false; } @@ -98,13 +99,6 @@ bool QTgaHandler::read(QImage *image) return !image->isNull(); } -#if QT_DEPRECATED_SINCE(5, 13) -QByteArray QTgaHandler::name() const -{ - return "tga"; -} -#endif - QVariant QTgaHandler::option(ImageOption option) const { if (option == Size && canRead()) { diff --git a/src/plugins/imageformats/tga/qtgahandler.h b/src/plugins/imageformats/tga/qtgahandler.h index 6550a11..8e16bb6 100644 --- a/src/plugins/imageformats/tga/qtgahandler.h +++ b/src/plugins/imageformats/tga/qtgahandler.h @@ -55,10 +55,6 @@ public: bool canRead() const override; bool read(QImage *image) override; -#if QT_DEPRECATED_SINCE(5, 13) - QByteArray name() const override; -#endif - static bool canRead(QIODevice *device); QVariant option(ImageOption option) const override; diff --git a/src/plugins/imageformats/tiff/CMakeLists.txt b/src/plugins/imageformats/tiff/CMakeLists.txt new file mode 100644 index 0000000..d38a8ec --- /dev/null +++ b/src/plugins/imageformats/tiff/CMakeLists.txt @@ -0,0 +1,100 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Generated from tiff.pro. + +##################################################################### +## QTiffPlugin Plugin: +##################################################################### + +# special case begin +# Handle the conditional finding of either system zlib or qt zlib. +if(NOT QT_FEATURE_system_zlib) + find_package(Qt6 COMPONENTS ZlibPrivate) +elseif(NOT TARGET WrapZLIB::WrapZLIB) + qt_find_package(WrapZLIB PROVIDED_TARGETS WrapZLIB::WrapZLIB) +endif() +# special case end + +qt_internal_add_plugin(QTiffPlugin + OUTPUT_NAME qtiff + PLUGIN_TYPE imageformats + SOURCES + main.cpp + qtiffhandler.cpp qtiffhandler_p.h + LIBRARIES + Qt::Core + Qt::Gui +) + +#### Keys ignored in scope 1:.:.:tiff.pro:<TRUE>: +# OTHER_FILES = "tiff.json" +# QT_FOR_CONFIG = "imageformats-private" + +## Scopes: +##################################################################### + +qt_internal_extend_target(QTiffPlugin CONDITION QT_FEATURE_system_tiff + LIBRARIES + TIFF::TIFF +) + +qt_internal_extend_target(QTiffPlugin CONDITION NOT QT_FEATURE_system_tiff + SOURCES + ../../../3rdparty/libtiff/libtiff/tif_aux.c + ../../../3rdparty/libtiff/libtiff/tif_close.c + ../../../3rdparty/libtiff/libtiff/tif_codec.c + ../../../3rdparty/libtiff/libtiff/tif_color.c + ../../../3rdparty/libtiff/libtiff/tif_compress.c + ../../../3rdparty/libtiff/libtiff/tif_dir.c + ../../../3rdparty/libtiff/libtiff/tif_dirinfo.c + ../../../3rdparty/libtiff/libtiff/tif_dirread.c + ../../../3rdparty/libtiff/libtiff/tif_dirwrite.c + ../../../3rdparty/libtiff/libtiff/tif_dumpmode.c + ../../../3rdparty/libtiff/libtiff/tif_error.c + ../../../3rdparty/libtiff/libtiff/tif_extension.c + ../../../3rdparty/libtiff/libtiff/tif_fax3.c + ../../../3rdparty/libtiff/libtiff/tif_fax3sm.c + ../../../3rdparty/libtiff/libtiff/tif_flush.c + ../../../3rdparty/libtiff/libtiff/tif_getimage.c + ../../../3rdparty/libtiff/libtiff/tif_hash_set.c + ../../../3rdparty/libtiff/libtiff/tif_luv.c + ../../../3rdparty/libtiff/libtiff/tif_lzw.c + ../../../3rdparty/libtiff/libtiff/tif_next.c + ../../../3rdparty/libtiff/libtiff/tif_open.c + ../../../3rdparty/libtiff/libtiff/tif_packbits.c + ../../../3rdparty/libtiff/libtiff/tif_pixarlog.c + ../../../3rdparty/libtiff/libtiff/tif_predict.c + ../../../3rdparty/libtiff/libtiff/tif_print.c + ../../../3rdparty/libtiff/libtiff/tif_read.c + ../../../3rdparty/libtiff/libtiff/tif_strip.c + ../../../3rdparty/libtiff/libtiff/tif_swab.c + ../../../3rdparty/libtiff/libtiff/tif_thunder.c + ../../../3rdparty/libtiff/libtiff/tif_tile.c + ../../../3rdparty/libtiff/libtiff/tif_version.c + ../../../3rdparty/libtiff/libtiff/tif_warning.c + ../../../3rdparty/libtiff/libtiff/tif_write.c + ../../../3rdparty/libtiff/libtiff/tif_zip.c + INCLUDE_DIRECTORIES + ../../../3rdparty/libtiff/libtiff +) + +qt_internal_extend_target(QTiffPlugin CONDITION WIN32 AND NOT QT_FEATURE_system_tiff + SOURCES + ../../../3rdparty/libtiff/libtiff/tif_win32.c +) + +qt_internal_extend_target(QTiffPlugin CONDITION UNIX AND NOT QT_FEATURE_system_tiff + SOURCES + ../../../3rdparty/libtiff/libtiff/tif_unix.c +) + +qt_internal_extend_target(QTiffPlugin CONDITION QT_FEATURE_system_zlib AND NOT QT_FEATURE_system_tiff + LIBRARIES + WrapZLIB::WrapZLIB +) + +qt_internal_extend_target(QTiffPlugin CONDITION NOT QT_FEATURE_system_tiff AND NOT QT_FEATURE_system_zlib + LIBRARIES + Qt::ZlibPrivate +) diff --git a/src/plugins/imageformats/tiff/main.cpp b/src/plugins/imageformats/tiff/main.cpp index 2c34097..8882f35 100644 --- a/src/plugins/imageformats/tiff/main.cpp +++ b/src/plugins/imageformats/tiff/main.cpp @@ -60,12 +60,12 @@ QImageIOPlugin::Capabilities QTiffPlugin::capabilities(QIODevice *device, const { if (format == "tiff" || format == "tif") return Capabilities(CanRead | CanWrite); + Capabilities cap; if (!format.isEmpty()) - return 0; + return cap; if (!device->isOpen()) - return 0; + return cap; - Capabilities cap; if (device->isReadable() && QTiffHandler::canRead(device)) cap |= CanRead; if (device->isWritable()) diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp index 65873e1..f0dfe7f 100644 --- a/src/plugins/imageformats/tiff/qtiffhandler.cpp +++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp @@ -43,6 +43,9 @@ #include <qdebug.h> #include <qimage.h> #include <qglobal.h> +#include <qbuffer.h> +#include <qfiledevice.h> + extern "C" { #include "tiffio.h" } @@ -90,13 +93,33 @@ toff_t qtiffSizeProc(thandle_t fd) return static_cast<QIODevice *>(fd)->size(); } -int qtiffMapProc(thandle_t /*fd*/, tdata_t* /*pbase*/, toff_t* /*psize*/) +int qtiffMapProc(thandle_t fd, void **base, toff_t *size) { + QIODevice *device = static_cast<QIODevice *>(fd); + + QFileDevice *file = qobject_cast<QFileDevice *>(device); + if (file) { + *base = file->map(0, file->size()); + if (*base != nullptr) { + *size = file->size(); + return 1; + } + } else { + QBuffer *buf = qobject_cast<QBuffer *>(device); + if (buf) { + *base = const_cast<char *>(buf->data().constData()); + *size = buf->size(); + return 1; + } + } return 0; } -void qtiffUnmapProc(thandle_t /*fd*/, tdata_t /*base*/, toff_t /*size*/) +void qtiffUnmapProc(thandle_t fd, void *base, toff_t /*size*/) { + QFileDevice *file = qobject_cast<QFileDevice *>(static_cast<QIODevice *>(fd)); + if (file && base) + file->unmap(static_cast<uchar *>(base)); } @@ -116,7 +139,7 @@ public: QImageIOHandler::Transformations transformation; QImage::Format format; QSize size; - uint16 photometric; + uint16_t photometric; bool grayscale; bool headersRead; int currentDirectory; @@ -205,9 +228,14 @@ bool QTiffHandlerPrivate::canRead(QIODevice *device) // current implementation uses TIFFClientOpen which needs to be // able to seek, so sequential devices are not supported - QByteArray header = device->peek(4); - return header == QByteArray::fromRawData("\x49\x49\x2A\x00", 4) - || header == QByteArray::fromRawData("\x4D\x4D\x00\x2A", 4); + char h[4]; + if (device->peek(h, 4) != 4) + return false; + if ((h[0] == 0x49 && h[1] == 0x49) && (h[2] == 0x2a || h[2] == 0x2b) && h[3] == 0) + return true; // Little endian, classic or bigtiff + if ((h[0] == 0x4d && h[1] == 0x4d) && h[2] == 0 && (h[3] == 0x2a || h[3] == 0x2b)) + return true; // Big endian, classic or bigtiff + return false; } bool QTiffHandlerPrivate::openForRead(QIODevice *device) @@ -245,8 +273,8 @@ bool QTiffHandlerPrivate::readHeaders(QIODevice *device) TIFFSetDirectory(tiff, currentDirectory); - uint32 width; - uint32 height; + uint32_t width; + uint32_t height; if (!TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width) || !TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height) || !TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric)) { @@ -255,15 +283,15 @@ bool QTiffHandlerPrivate::readHeaders(QIODevice *device) } size = QSize(width, height); - uint16 orientationTag; + uint16_t orientationTag; if (TIFFGetField(tiff, TIFFTAG_ORIENTATION, &orientationTag)) transformation = exif2Qt(orientationTag); // BitsPerSample defaults to 1 according to the TIFF spec. - uint16 bitPerSample; + uint16_t bitPerSample; if (!TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitPerSample)) bitPerSample = 1; - uint16 samplesPerPixel; // they may be e.g. grayscale with 2 samples per pixel + uint16_t samplesPerPixel; // they may be e.g. grayscale with 2 samples per pixel if (!TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel)) samplesPerPixel = 1; @@ -278,13 +306,13 @@ 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 > 8 && photometric == PHOTOMETRIC_RGB) + if (bitPerSample == 16 && photometric == PHOTOMETRIC_RGB) format = QImage::Format_RGBX64; else format = QImage::Format_RGB32; else { - uint16 count; - uint16 *extrasamples; + uint16_t count; + uint16_t *extrasamples; // If there is any definition of the alpha-channel, libtiff will return premultiplied // data to us. If there is none, libtiff will not touch it and we assume it to be // non-premultiplied, matching behavior of tested image editors, and how older Qt @@ -294,7 +322,7 @@ bool QTiffHandlerPrivate::readHeaders(QIODevice *device) if (!gotField || !count || extrasamples[0] == EXTRASAMPLE_UNSPECIFIED) premultiplied = false; - if (bitPerSample > 8 && photometric == PHOTOMETRIC_RGB) { + if (bitPerSample == 16 && photometric == PHOTOMETRIC_RGB) { // We read 64-bit raw, so unassoc remains unpremultiplied. if (gotField && count && extrasamples[0] == EXTRASAMPLE_UNASSALPHA) premultiplied = false; @@ -356,6 +384,8 @@ bool QTiffHandler::read(QImage *image) } TIFF *const tiff = d->tiff; + if (TIFFIsTiled(tiff) && TIFFTileSize64(tiff) > uint64_t(image->sizeInBytes())) // Corrupt image + return false; const quint32 width = d->size.width(); const quint32 height = d->size.height(); @@ -372,7 +402,7 @@ bool QTiffHandler::read(QImage *image) } image->setColorTable(colortable); } else if (format == QImage::Format_Indexed8) { - const uint16 tableSize = 256; + const uint16_t tableSize = 256; QVector<QRgb> qtColorTable(tableSize); if (d->grayscale) { for (int i = 0; i<tableSize; ++i) { @@ -381,9 +411,9 @@ bool QTiffHandler::read(QImage *image) } } else { // create the color table - uint16 *redTable = 0; - uint16 *greenTable = 0; - uint16 *blueTable = 0; + uint16_t *redTable = 0; + uint16_t *greenTable = 0; + uint16_t *blueTable = 0; if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) { d->close(); return false; @@ -418,14 +448,19 @@ bool QTiffHandler::read(QImage *image) quint32 tileWidth, tileLength; TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &tileWidth); TIFFGetField(tiff, TIFFTAG_TILELENGTH, &tileLength); - uchar *buf = (uchar *)_TIFFmalloc(TIFFTileSize(tiff)); - if (!tileWidth || !tileLength || !buf) { - _TIFFfree(buf); + if (!tileWidth || !tileLength || tileWidth % 16 || tileLength % 16) { d->close(); return false; } quint32 byteWidth = (format == QImage::Format_Mono) ? (width + 7)/8 : (width * bytesPerPixel); quint32 byteTileWidth = (format == QImage::Format_Mono) ? tileWidth/8 : (tileWidth * bytesPerPixel); + tmsize_t byteTileSize = TIFFTileSize(tiff); + uchar *buf = (uchar *)_TIFFmalloc(byteTileSize); + if (!buf || byteTileSize / tileLength < byteTileWidth) { + _TIFFfree(buf); + d->close(); + return false; + } for (quint32 y = 0; y < height; y += tileLength) { for (quint32 x = 0; x < width; x += tileWidth) { if (TIFFReadTile(tiff, buf, x, y, 0, 0) < 0) { @@ -443,7 +478,11 @@ bool QTiffHandler::read(QImage *image) } _TIFFfree(buf); } else { - for (uint32 y=0; y<height; ++y) { + if (image->bytesPerLine() < TIFFScanlineSize(tiff)) { + d->close(); + return false; + } + for (uint32_t y=0; y<height; ++y) { if (TIFFReadScanline(tiff, image->scanLine(y), y, 0) < 0) { d->close(); return false; @@ -454,8 +493,8 @@ bool QTiffHandler::read(QImage *image) rgb48fixup(image); } else { const int stopOnError = 1; - if (TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast<uint32 *>(image->bits()), qt2Exif(d->transformation), stopOnError)) { - for (uint32 y=0; y<height; ++y) + if (TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast<uint32_t *>(image->bits()), qt2Exif(d->transformation), stopOnError)) { + for (uint32_t y=0; y<height; ++y) convert32BitOrder(image->scanLine(y), width); } else { d->close(); @@ -466,7 +505,7 @@ bool QTiffHandler::read(QImage *image) float resX = 0; float resY = 0; - uint16 resUnit; + uint16_t resUnit; if (!TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resUnit)) resUnit = RESUNIT_INCH; @@ -489,7 +528,7 @@ bool QTiffHandler::read(QImage *image) } } - uint32 count; + uint32_t count; void *profile; if (TIFFGetField(tiff, TIFFTAG_ICCPROFILE, &count, &profile)) { QByteArray iccProfile(reinterpret_cast<const char *>(profile), count); @@ -613,7 +652,7 @@ bool QTiffHandler::write(const QImage &image) // configure image depth const QImage::Format format = image.format(); if (format == QImage::Format_Mono || format == QImage::Format_MonoLSB) { - uint16 photometric = PHOTOMETRIC_MINISBLACK; + uint16_t photometric = PHOTOMETRIC_MINISBLACK; if (image.colorTable().at(0) == 0xffffffff) photometric = PHOTOMETRIC_MINISWHITE; if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, photometric) @@ -635,7 +674,7 @@ bool QTiffHandler::write(const QImage &image) int chunkStart = y; int chunkEnd = y + chunk.height(); while (y < chunkEnd) { - if (TIFFWriteScanline(tiff, reinterpret_cast<uint32 *>(chunk.scanLine(y - chunkStart)), y) != 1) { + if (TIFFWriteScanline(tiff, reinterpret_cast<uint32_t *>(chunk.scanLine(y - chunkStart)), y) != 1) { TIFFClose(tiff); return false; } @@ -650,7 +689,7 @@ bool QTiffHandler::write(const QImage &image) QVector<QRgb> colorTable = effectiveColorTable(image); bool isGrayscale = checkGrayscale(colorTable); if (isGrayscale) { - uint16 photometric = PHOTOMETRIC_MINISBLACK; + uint16_t photometric = PHOTOMETRIC_MINISBLACK; if (colorTable.at(0) == 0xffffffff) photometric = PHOTOMETRIC_MINISWHITE; if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, photometric) @@ -672,9 +711,9 @@ bool QTiffHandler::write(const QImage &image) // allocate the color tables const int tableSize = colorTable.size(); Q_ASSERT(tableSize <= 256); - QVarLengthArray<uint16> redTable(tableSize); - QVarLengthArray<uint16> greenTable(tableSize); - QVarLengthArray<uint16> blueTable(tableSize); + QVarLengthArray<uint16_t> redTable(tableSize); + QVarLengthArray<uint16_t> greenTable(tableSize); + QVarLengthArray<uint16_t> blueTable(tableSize); // set the color table for (int i = 0; i<tableSize; ++i) { @@ -727,7 +766,7 @@ bool QTiffHandler::write(const QImage &image) } else if (format == QImage::Format_RGBA64 || format == QImage::Format_RGBA64_Premultiplied) { const bool premultiplied = image.format() != QImage::Format_RGBA64; - const uint16 extrasamples = premultiplied ? EXTRASAMPLE_ASSOCALPHA : EXTRASAMPLE_UNASSALPHA; + const uint16_t extrasamples = premultiplied ? EXTRASAMPLE_ASSOCALPHA : EXTRASAMPLE_UNASSALPHA; if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB) || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression == NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW) || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4) @@ -775,7 +814,7 @@ bool QTiffHandler::write(const QImage &image) } else { const bool premultiplied = image.format() != QImage::Format_ARGB32 && image.format() != QImage::Format_RGBA8888; - const uint16 extrasamples = premultiplied ? EXTRASAMPLE_ASSOCALPHA : EXTRASAMPLE_UNASSALPHA; + const uint16_t extrasamples = premultiplied ? EXTRASAMPLE_ASSOCALPHA : EXTRASAMPLE_UNASSALPHA; if (!TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB) || !TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression == NoCompression ? COMPRESSION_NONE : COMPRESSION_LZW) || !TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4) @@ -811,13 +850,6 @@ bool QTiffHandler::write(const QImage &image) return true; } -#if QT_DEPRECATED_SINCE(5, 13) -QByteArray QTiffHandler::name() const -{ - return "tiff"; -} -#endif - QVariant QTiffHandler::option(ImageOption option) const { if (option == Size && canRead()) { @@ -896,9 +928,9 @@ int QTiffHandler::currentImageNumber() const void QTiffHandler::convert32BitOrder(void *buffer, int width) { - uint32 *target = reinterpret_cast<uint32 *>(buffer); - for (int32 x=0; x<width; ++x) { - uint32 p = target[x]; + uint32_t *target = reinterpret_cast<uint32_t *>(buffer); + for (int32_t x=0; x<width; ++x) { + uint32_t p = target[x]; // convert between ARGB and ABGR target[x] = (p & 0xff000000) | ((p & 0x00ff0000) >> 16) @@ -915,7 +947,7 @@ void QTiffHandler::rgb48fixup(QImage *image) uchar *scanline = image->bits(); const qsizetype bpl = image->bytesPerLine(); for (int y = 0; y < h; ++y) { - quint16 *dst = reinterpret_cast<uint16 *>(scanline); + quint16 *dst = reinterpret_cast<uint16_t *>(scanline); for (int x = w - 1; x >= 0; --x) { dst[x * 4 + 3] = 0xffff; dst[x * 4 + 2] = dst[x * 3 + 2]; diff --git a/src/plugins/imageformats/tiff/qtiffhandler_p.h b/src/plugins/imageformats/tiff/qtiffhandler_p.h index c2eb412..97a63e1 100644 --- a/src/plugins/imageformats/tiff/qtiffhandler_p.h +++ b/src/plugins/imageformats/tiff/qtiffhandler_p.h @@ -55,10 +55,6 @@ public: bool read(QImage *image) override; bool write(const QImage &image) override; -#if QT_DEPRECATED_SINCE(5, 13) - QByteArray name() const override; -#endif - static bool canRead(QIODevice *device); QVariant option(ImageOption option) const override; diff --git a/src/plugins/imageformats/wbmp/main.cpp b/src/plugins/imageformats/wbmp/main.cpp index 45da0ca..5e8206e 100644 --- a/src/plugins/imageformats/wbmp/main.cpp +++ b/src/plugins/imageformats/wbmp/main.cpp @@ -64,13 +64,13 @@ QImageIOPlugin::Capabilities QWbmpPlugin::capabilities(QIODevice *device, const if (format == "wbmp") return Capabilities(CanRead | CanWrite); + Capabilities cap; if (!format.isEmpty()) - return 0; + return cap; if (!device->isOpen()) - return 0; + return cap; - Capabilities cap; if (device->isReadable() && QWbmpHandler::canRead(device)) cap |= CanRead; diff --git a/src/plugins/imageformats/webp/CMakeLists.txt b/src/plugins/imageformats/webp/CMakeLists.txt new file mode 100644 index 0000000..fbbcc1c --- /dev/null +++ b/src/plugins/imageformats/webp/CMakeLists.txt @@ -0,0 +1,208 @@ +# Generated from webp.pro. + +##################################################################### +## QWebpPlugin Plugin: +##################################################################### + +qt_internal_add_plugin(QWebpPlugin + OUTPUT_NAME qwebp + PLUGIN_TYPE imageformats + SOURCES + main.cpp + qwebphandler.cpp qwebphandler_p.h + LIBRARIES + Qt::Core + Qt::Gui +) + +#### Keys ignored in scope 1:.:.:webp.pro:<TRUE>: +# OTHER_FILES = "webp.json" +# QT_FOR_CONFIG = "imageformats-private" + +## Scopes: +##################################################################### + +qt_internal_extend_target(QWebpPlugin CONDITION QT_FEATURE_system_webp + LIBRARIES + WrapWebP::WrapWebP +) + +qt_internal_extend_target(QWebpPlugin CONDITION NOT QT_FEATURE_system_webp + SOURCES + ../../../3rdparty/libwebp/sharpyuv/sharpyuv.c + ../../../3rdparty/libwebp/sharpyuv/sharpyuv_cpu.c + ../../../3rdparty/libwebp/sharpyuv/sharpyuv_csp.c + ../../../3rdparty/libwebp/sharpyuv/sharpyuv_dsp.c + ../../../3rdparty/libwebp/sharpyuv/sharpyuv_gamma.c + ../../../3rdparty/libwebp/sharpyuv/sharpyuv_sse2.c + ../../../3rdparty/libwebp/src/dec/alpha_dec.c + ../../../3rdparty/libwebp/src/dec/buffer_dec.c + ../../../3rdparty/libwebp/src/dec/frame_dec.c + ../../../3rdparty/libwebp/src/dec/idec_dec.c + ../../../3rdparty/libwebp/src/dec/io_dec.c + ../../../3rdparty/libwebp/src/dec/quant_dec.c + ../../../3rdparty/libwebp/src/dec/tree_dec.c + ../../../3rdparty/libwebp/src/dec/vp8_dec.c + ../../../3rdparty/libwebp/src/dec/vp8l_dec.c + ../../../3rdparty/libwebp/src/dec/webp_dec.c + ../../../3rdparty/libwebp/src/demux/anim_decode.c + ../../../3rdparty/libwebp/src/demux/demux.c + ../../../3rdparty/libwebp/src/dsp/alpha_processing.c + ../../../3rdparty/libwebp/src/dsp/alpha_processing_mips_dsp_r2.c + ../../../3rdparty/libwebp/src/dsp/alpha_processing_sse2.c + ../../../3rdparty/libwebp/src/dsp/alpha_processing_sse41.c + ../../../3rdparty/libwebp/src/dsp/cost.c + ../../../3rdparty/libwebp/src/dsp/cost_mips32.c + ../../../3rdparty/libwebp/src/dsp/cost_mips_dsp_r2.c + ../../../3rdparty/libwebp/src/dsp/cost_neon.c + ../../../3rdparty/libwebp/src/dsp/cost_sse2.c + ../../../3rdparty/libwebp/src/dsp/cpu.c + ../../../3rdparty/libwebp/src/dsp/dec.c + ../../../3rdparty/libwebp/src/dsp/dec_clip_tables.c + ../../../3rdparty/libwebp/src/dsp/dec_mips32.c + ../../../3rdparty/libwebp/src/dsp/dec_mips_dsp_r2.c + ../../../3rdparty/libwebp/src/dsp/dec_msa.c + ../../../3rdparty/libwebp/src/dsp/dec_sse2.c + ../../../3rdparty/libwebp/src/dsp/dec_sse41.c + ../../../3rdparty/libwebp/src/dsp/enc.c + ../../../3rdparty/libwebp/src/dsp/enc_mips32.c + ../../../3rdparty/libwebp/src/dsp/enc_mips_dsp_r2.c + ../../../3rdparty/libwebp/src/dsp/enc_msa.c + ../../../3rdparty/libwebp/src/dsp/enc_sse2.c + ../../../3rdparty/libwebp/src/dsp/enc_sse41.c + ../../../3rdparty/libwebp/src/dsp/filters.c + ../../../3rdparty/libwebp/src/dsp/filters_mips_dsp_r2.c + ../../../3rdparty/libwebp/src/dsp/filters_msa.c + ../../../3rdparty/libwebp/src/dsp/filters_sse2.c + ../../../3rdparty/libwebp/src/dsp/lossless.c + ../../../3rdparty/libwebp/src/dsp/lossless_enc.c + ../../../3rdparty/libwebp/src/dsp/lossless_enc_mips32.c + ../../../3rdparty/libwebp/src/dsp/lossless_enc_mips_dsp_r2.c + ../../../3rdparty/libwebp/src/dsp/lossless_enc_msa.c + ../../../3rdparty/libwebp/src/dsp/lossless_enc_sse2.c + ../../../3rdparty/libwebp/src/dsp/lossless_enc_sse41.c + ../../../3rdparty/libwebp/src/dsp/lossless_mips_dsp_r2.c + ../../../3rdparty/libwebp/src/dsp/lossless_sse2.c + ../../../3rdparty/libwebp/src/dsp/lossless_sse41.c + ../../../3rdparty/libwebp/src/dsp/rescaler.c + ../../../3rdparty/libwebp/src/dsp/rescaler_mips32.c + ../../../3rdparty/libwebp/src/dsp/rescaler_mips_dsp_r2.c + ../../../3rdparty/libwebp/src/dsp/rescaler_msa.c + ../../../3rdparty/libwebp/src/dsp/rescaler_sse2.c + ../../../3rdparty/libwebp/src/dsp/ssim.c + ../../../3rdparty/libwebp/src/dsp/ssim_sse2.c + ../../../3rdparty/libwebp/src/dsp/upsampling.c + ../../../3rdparty/libwebp/src/dsp/upsampling_mips_dsp_r2.c + ../../../3rdparty/libwebp/src/dsp/upsampling_msa.c + ../../../3rdparty/libwebp/src/dsp/upsampling_sse2.c + ../../../3rdparty/libwebp/src/dsp/upsampling_sse41.c + ../../../3rdparty/libwebp/src/dsp/yuv.c + ../../../3rdparty/libwebp/src/dsp/yuv_mips32.c + ../../../3rdparty/libwebp/src/dsp/yuv_mips_dsp_r2.c + ../../../3rdparty/libwebp/src/dsp/yuv_sse2.c + ../../../3rdparty/libwebp/src/dsp/yuv_sse41.c + ../../../3rdparty/libwebp/src/enc/alpha_enc.c + ../../../3rdparty/libwebp/src/enc/analysis_enc.c + ../../../3rdparty/libwebp/src/enc/backward_references_cost_enc.c + ../../../3rdparty/libwebp/src/enc/backward_references_enc.c + ../../../3rdparty/libwebp/src/enc/config_enc.c + ../../../3rdparty/libwebp/src/enc/cost_enc.c + ../../../3rdparty/libwebp/src/enc/filter_enc.c + ../../../3rdparty/libwebp/src/enc/frame_enc.c + ../../../3rdparty/libwebp/src/enc/histogram_enc.c + ../../../3rdparty/libwebp/src/enc/iterator_enc.c + ../../../3rdparty/libwebp/src/enc/near_lossless_enc.c + ../../../3rdparty/libwebp/src/enc/picture_csp_enc.c + ../../../3rdparty/libwebp/src/enc/picture_enc.c + ../../../3rdparty/libwebp/src/enc/picture_psnr_enc.c + ../../../3rdparty/libwebp/src/enc/picture_rescale_enc.c + ../../../3rdparty/libwebp/src/enc/picture_tools_enc.c + ../../../3rdparty/libwebp/src/enc/predictor_enc.c + ../../../3rdparty/libwebp/src/enc/quant_enc.c + ../../../3rdparty/libwebp/src/enc/syntax_enc.c + ../../../3rdparty/libwebp/src/enc/token_enc.c + ../../../3rdparty/libwebp/src/enc/tree_enc.c + ../../../3rdparty/libwebp/src/enc/vp8l_enc.c + ../../../3rdparty/libwebp/src/enc/webp_enc.c + ../../../3rdparty/libwebp/src/mux/anim_encode.c + ../../../3rdparty/libwebp/src/mux/muxedit.c + ../../../3rdparty/libwebp/src/mux/muxinternal.c + ../../../3rdparty/libwebp/src/mux/muxread.c + ../../../3rdparty/libwebp/src/utils/bit_reader_utils.c + ../../../3rdparty/libwebp/src/utils/bit_writer_utils.c + ../../../3rdparty/libwebp/src/utils/color_cache_utils.c + ../../../3rdparty/libwebp/src/utils/filters_utils.c + ../../../3rdparty/libwebp/src/utils/huffman_encode_utils.c + ../../../3rdparty/libwebp/src/utils/huffman_utils.c + ../../../3rdparty/libwebp/src/utils/quant_levels_dec_utils.c + ../../../3rdparty/libwebp/src/utils/quant_levels_utils.c + ../../../3rdparty/libwebp/src/utils/random_utils.c + ../../../3rdparty/libwebp/src/utils/rescaler_utils.c + ../../../3rdparty/libwebp/src/utils/thread_utils.c + ../../../3rdparty/libwebp/src/utils/utils.c + INCLUDE_DIRECTORIES + ../../../3rdparty/libwebp + ../../../3rdparty/libwebp/sharpyuv + ../../../3rdparty/libwebp/src + ../../../3rdparty/libwebp/src/dec + ../../../3rdparty/libwebp/src/dsp + ../../../3rdparty/libwebp/src/enc + ../../../3rdparty/libwebp/src/mux + ../../../3rdparty/libwebp/src/utils + ../../../3rdparty/libwebp/src/webp +) + +qt_internal_extend_target(QWebpPlugin CONDITION ANDROID AND NOT ANDROID_EMBEDDED AND NOT QT_FEATURE_system_webp + SOURCES + ${CMAKE_ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c # special case + INCLUDE_DIRECTORIES + ${CMAKE_ANDROID_NDK}/sources/android/cpufeatures # special case +) + +# special case begin +set(neon_sources + ../../../3rdparty/libwebp/sharpyuv/sharpyuv_neon.c + ../../../3rdparty/libwebp/src/dsp/alpha_processing_neon.c + ../../../3rdparty/libwebp/src/dsp/dec_neon.c + ../../../3rdparty/libwebp/src/dsp/enc_neon.c + ../../../3rdparty/libwebp/src/dsp/filters_neon.c + ../../../3rdparty/libwebp/src/dsp/lossless_enc_neon.c + ../../../3rdparty/libwebp/src/dsp/lossless_neon.c + ../../../3rdparty/libwebp/src/dsp/rescaler_neon.c + ../../../3rdparty/libwebp/src/dsp/upsampling_neon.c + ../../../3rdparty/libwebp/src/dsp/yuv_neon.c +) + +if(NOT QT_FEATURE_system_webp) + if(ANDROID) + qt_internal_extend_target(QWebpPlugin + CONDITION (CMAKE_ANDROID_ARM_NEON OR CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") + SOURCES ${neon_sources} + ) + else() + # For universal macOS and iOS, and other platforms that support neon + qt_internal_add_simd_part(QWebpPlugin SIMD neon SOURCES ${neon_sources}) + endif() +endif() +# special case end + +#### Keys ignored in scope 6:.:../../../3rdparty:../../../3rdparty/libwebp.pri:INTEGRITY: +# QMAKE_CFLAGS = "-c99" + +#### Keys ignored in scope 12:.:../../../3rdparty:../../../3rdparty/libwebp.pri:else: +# QMAKE_EXTRA_COMPILERS = "neon_comp" +# neon_comp.commands = "$$QMAKE_CC" "-c" "$(CFLAGS)" "$$QMAKE_CFLAGS_NEON" "$(INCPATH)" "${QMAKE_FILE_IN}" +# neon_comp.dependency_type = "TYPE_C" +# neon_comp.input = "SOURCES_FOR_NEON" +# neon_comp.name = "compiling[neon]" "${QMAKE_FILE_IN}" +# neon_comp.output = "${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${firstQMAKE_EXT_OBJ}" +# neon_comp.variable_out = "OBJECTS" + +#### Keys ignored in scope 13:.:../../../3rdparty:../../../3rdparty/libwebp.pri:MSVC: +# neon_comp.commands = "-Fo${QMAKE_FILE_OUT}" + +#### Keys ignored in scope 14:.:../../../3rdparty:../../../3rdparty/libwebp.pri:else: +# neon_comp.commands = "-o" "${QMAKE_FILE_OUT}" + +#### Keys ignored in scope 15:.:../../../3rdparty:../../../3rdparty/libwebp.pri:silent: +# neon_comp.commands = "@echo" "compiling[neon]" "${QMAKE_FILE_IN}" "&&" diff --git a/src/plugins/imageformats/webp/main.cpp b/src/plugins/imageformats/webp/main.cpp index 7e9405b..02a3ed4 100644 --- a/src/plugins/imageformats/webp/main.cpp +++ b/src/plugins/imageformats/webp/main.cpp @@ -64,12 +64,12 @@ QWebpPlugin::Capabilities QWebpPlugin::capabilities(QIODevice *device, const QBy if (format == "webp") return Capabilities(CanRead | CanWrite); + Capabilities cap; if (!format.isEmpty()) - return 0; + return cap; if (!device->isOpen()) - return 0; + return cap; - Capabilities cap; if (device->isReadable() && QWebpHandler::canRead(device)) cap |= CanRead; if (device->isWritable()) diff --git a/src/plugins/imageformats/webp/qwebphandler.cpp b/src/plugins/imageformats/webp/qwebphandler.cpp index aab7aad..82d38cb 100644 --- a/src/plugins/imageformats/webp/qwebphandler.cpp +++ b/src/plugins/imageformats/webp/qwebphandler.cpp @@ -167,8 +167,11 @@ bool QWebpHandler::read(QImage *image) // Read global meta-data chunks first WebPChunkIterator metaDataIter; if ((m_formatFlags & ICCP_FLAG) && WebPDemuxGetChunk(m_demuxer, "ICCP", 1, &metaDataIter)) { - const QByteArray iccProfile = QByteArray::fromRawData(reinterpret_cast<const char *>(metaDataIter.chunk.bytes), - metaDataIter.chunk.size); + QByteArray iccProfile = QByteArray::fromRawData(reinterpret_cast<const char *>(metaDataIter.chunk.bytes), + metaDataIter.chunk.size); + // Ensure the profile is 4-byte aligned. + if (reinterpret_cast<qintptr>(iccProfile.constData()) & 0x3) + iccProfile.detach(); m_colorSpace = QColorSpace::fromIccProfile(iccProfile); // ### consider parsing EXIF and/or XMP metadata too. WebPDemuxReleaseChunkIterator(&metaDataIter); @@ -288,6 +291,7 @@ bool QWebpHandler::write(const QImage &image) if (!WebPEncode(&config, &picture)) { qWarning() << "failed to encode webp picture, error code: " << picture.error_code; WebPPictureFree(&picture); + WebPMemoryWriterClear(&writer); return false; } @@ -336,6 +340,7 @@ bool QWebpHandler::write(const QImage &image) static_cast<size_t>(device()->write(reinterpret_cast<const char *>(writer.mem), writer.size))); } WebPPictureFree(&picture); + WebPMemoryWriterClear(&writer); return res; } @@ -379,13 +384,6 @@ bool QWebpHandler::supportsOption(ImageOption option) const || option == BackgroundColor; } -#if QT_DEPRECATED_SINCE(5, 13) -QByteArray QWebpHandler::name() const -{ - return QByteArrayLiteral("webp"); -} -#endif - int QWebpHandler::imageCount() const { if (!ensureScanned()) diff --git a/src/plugins/imageformats/webp/qwebphandler_p.h b/src/plugins/imageformats/webp/qwebphandler_p.h index 96a8811..849afe3 100644 --- a/src/plugins/imageformats/webp/qwebphandler_p.h +++ b/src/plugins/imageformats/webp/qwebphandler_p.h @@ -57,10 +57,6 @@ public: ~QWebpHandler(); public: -#if QT_DEPRECATED_SINCE(5, 13) - QByteArray name() const override; -#endif - bool canRead() const override; bool read(QImage *image) override; |