File indexing completed on 2024-04-28 04:58:03

0001 /*  This file is part of the KDE libraries
0002     SPDX-FileCopyrightText: 2008 Andre Gemünd <scroogie@gmail.com>
0003     SPDX-FileCopyrightText: 2016 Alexander Volkov <a.volkov@rusbitech.ru>
0004     SPDX-FileCopyrightText: 2022 Kai Uwe Broulik <kde@broulik.de>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "config-thumbnail.h"
0010 
0011 #include "jpegcreator.h"
0012 #include "jpegcreatorsettings5.h"
0013 
0014 #include <QImage>
0015 #include <QImageReader>
0016 
0017 #include <KLocalizedString>
0018 #include <KPluginFactory>
0019 
0020 #if HAVE_KEXIV2
0021 #include <KExiv2/KExiv2>
0022 #endif
0023 
0024 K_PLUGIN_CLASS_WITH_JSON(JpegCreator, "jpegthumbnail.json")
0025 
0026 JpegCreator::JpegCreator(QObject *parent, const QVariantList &args)
0027     : KIO::ThumbnailCreator(parent, args)
0028 {
0029 }
0030 
0031 KIO::ThumbnailResult JpegCreator::exifThumbnail(const KIO::ThumbnailRequest &request) const
0032 {
0033 #if HAVE_KEXIV2
0034     KExiv2Iface::KExiv2 exiv2Image(request.url().toLocalFile());
0035     QImage image = exiv2Image.getExifThumbnail(JpegCreatorSettings::self()->rotate());
0036 
0037     if (image.isNull()) {
0038         return KIO::ThumbnailResult::fail();
0039     }
0040 
0041     // skip embedded thumbnail if strictly smaller
0042     if (image.size().width() < request.targetSize().width() && image.size().height() < request.targetSize().height()) {
0043         return KIO::ThumbnailResult::fail();
0044     }
0045 
0046     return KIO::ThumbnailResult::pass(image);
0047 #else
0048     Q_UNUSED(request)
0049     return KIO::ThumbnailResult::fail();
0050 #endif // HAVE_KEXIV2
0051 }
0052 
0053 KIO::ThumbnailResult JpegCreator::imageReaderThumbnail(const KIO::ThumbnailRequest &request) const
0054 {
0055     QImageReader imageReader(request.url().toLocalFile(), "jpeg");
0056     const QSize imageSize = imageReader.size();
0057     if (imageSize.isValid() && (imageSize.width() > request.targetSize().width() || imageSize.height() > request.targetSize().height())) {
0058         const QSize thumbnailSize = imageSize.scaled(request.targetSize(), Qt::KeepAspectRatio);
0059         imageReader.setScaledSize(thumbnailSize); // fast downscaling
0060     }
0061     imageReader.setQuality(75); // set quality so that the jpeg handler will use a high quality downscaler
0062 
0063     imageReader.setAutoTransform(JpegCreatorSettings::self()->rotate());
0064 
0065     QImage image = imageReader.read();
0066 
0067     if (image.isNull()) {
0068         return KIO::ThumbnailResult::fail();
0069     }
0070 
0071     return KIO::ThumbnailResult::pass(image);
0072 }
0073 
0074 KIO::ThumbnailResult JpegCreator::create(const KIO::ThumbnailRequest &request)
0075 {
0076     JpegCreatorSettings::self()->load();
0077 
0078     if (auto result = exifThumbnail(request); result.isValid()) {
0079         return result;
0080     }
0081 
0082     if (auto result = imageReaderThumbnail(request); result.isValid()) {
0083         return result;
0084     }
0085 
0086     return KIO::ThumbnailResult::fail();
0087 }
0088 
0089 #include "jpegcreator.moc"
0090 #include "moc_jpegcreator.cpp"