File indexing completed on 2024-04-14 04:43:59
0001 /* 0002 SPDX-FileCopyrightText: 2018 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr> 0003 0004 SPDX-License-Identifier: LGPL-3.0-or-later 0005 */ 0006 0007 #include "embeddedcoverageimageprovider.h" 0008 0009 #include <KFileMetaData/EmbeddedImageData> 0010 #include <KFileMetaData/ExtractorCollection> 0011 #include <KFileMetaData/SimpleExtractionResult> 0012 0013 #include <QImage> 0014 #include <QMimeDatabase> 0015 0016 class AsyncImageResponse : public QQuickImageResponse, public QRunnable 0017 { 0018 Q_OBJECT 0019 0020 public: 0021 AsyncImageResponse(QString id, QSize requestedSize) 0022 : QQuickImageResponse(), mId(std::move(id)), mRequestedSize(requestedSize) 0023 { 0024 setAutoDelete(false); 0025 0026 if (!mRequestedSize.width()) { 0027 mRequestedSize.setWidth(mRequestedSize.height()); 0028 } 0029 0030 if (!mRequestedSize.height()) { 0031 mRequestedSize.setHeight(mRequestedSize.width()); 0032 } 0033 } 0034 0035 [[nodiscard]] QQuickTextureFactory *textureFactory() const override 0036 { 0037 return QQuickTextureFactory::textureFactoryForImage(mCoverImage); 0038 } 0039 0040 void run() override 0041 { 0042 QMimeDatabase mimeDatabase; 0043 const auto fileMimeType = mimeDatabase.mimeTypeForFile(mId).name(); 0044 KFileMetaData::ExtractorCollection ec; 0045 KFileMetaData::SimpleExtractionResult result(mId, fileMimeType, KFileMetaData::ExtractionResult::ExtractImageData); 0046 0047 mErrorMessage = QLatin1String{""}; 0048 0049 auto extractors = ec.fetchExtractors(fileMimeType); 0050 for (const auto& ex : extractors) { 0051 ex->extract(&result); 0052 } 0053 0054 auto imageData = result.imageData(); 0055 0056 if (imageData.isEmpty()) { 0057 mErrorMessage = QString{QLatin1String{"Unable to load image data from "} + mId}; 0058 Q_EMIT finished(); 0059 return; 0060 } 0061 0062 if (imageData.contains(KFileMetaData::EmbeddedImageData::FrontCover)) { 0063 mCoverImage = QImage::fromData(imageData[KFileMetaData::EmbeddedImageData::FrontCover]); 0064 } else { 0065 mCoverImage = QImage::fromData(imageData.first()); 0066 } 0067 0068 if (mCoverImage.isNull()) { 0069 mErrorMessage = QString{QLatin1String{"Invalid embedded cover image in "} + mId}; 0070 Q_EMIT finished(); 0071 return; 0072 } 0073 0074 auto newCoverImage = mCoverImage.scaled(mRequestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); 0075 if (!newCoverImage.isNull()) { 0076 mCoverImage = std::move(newCoverImage); 0077 } 0078 0079 Q_EMIT finished(); 0080 } 0081 0082 QString errorString() const override 0083 { 0084 return mErrorMessage; 0085 } 0086 0087 QString mId; 0088 QString mErrorMessage; 0089 QSize mRequestedSize; 0090 QImage mCoverImage; 0091 }; 0092 0093 EmbeddedCoverageImageProvider::EmbeddedCoverageImageProvider() 0094 : QQuickAsyncImageProvider() 0095 { 0096 } 0097 0098 QQuickImageResponse *EmbeddedCoverageImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize) 0099 { 0100 auto response = std::make_unique<AsyncImageResponse>(id, requestedSize); 0101 pool.start(response.get()); 0102 return response.release(); 0103 } 0104 0105 #include "embeddedcoverageimageprovider.moc"